Workbox :Service Worker 初嘗試

Service Worker

咱們的應用程序的主進程主要負責渲染dom,執行交互請求,而Service Worker 是瀏覽器在後臺獨立於網頁運行的,它從新在後臺起了一個進程,它和應用的主進程互不影響,能夠同時執行。 sw能夠攔截和處理網絡請求,包括經過程序來管理緩存中的響應。在使用 service-worker 前,咱們必需要先在主進程中註冊它,而後才能在 service-worker 進程中編寫邏輯。css

//index.js. 註冊SW
if ("serviceWorker" in navigator) {
    // Use the window load event to keep the page load performant
    window.addEventListener("load", () => {
      navigator.serviceWorker.register("/service-worker.js").then(registration=>{
        console.log("register succces...")
      }, err=>{
        console.log("register error...",err)
      });
    });
  }

複製代碼

demo

咱們在根路徑下注冊了一個 SW,那SW 就能夠攔截對應服務下的全部請求。只須要監聽 fetch 事件,你就能夠任意的操縱請求,能夠返回從 CacheStorage 中讀的數據,也能夠經過 Fetch API 發起新的請求,甚至能夠 new 一個 Response,返回給頁面。html

service-worker
//service-worker.js  簡單輸出一些文本
console.log('Hello from service-worker.js');

var cacheStorageKey = 'cachesName';
var cacheList = [
   // 註冊成功後要當即緩存的資源列表
    "/test.css",
    "/index.js",
    {
      url: "/index.html",
      revision: "383676" //-- revision 能夠經過工具插件workbox-webpack-plugin維護
    }
]

// 當瀏覽器解析完 SW 文件時觸發 install 事件  安裝SW
self.addEventListener('install', function(e) {
  // install 事件中通常會將 cacheList 中要換存的內容經過 addAll 方法,請求一遍放入 caches 中
  e.waitUntil(
    caches.open(cacheStorageKey).then(function(cache) {
      return cache.addAll(cacheList)
    })
  );
});

// 激活時觸發 activate 事件
self.addEventListener('activate', function(e) {
  // active 事件中一般作一些過時資源釋放的工做,匹配到就從 caches 中刪除
  var cacheDeletePromises = caches.keys().then(cacheNames => {
    return Promise.all(cacheNames.map(name => {
      if (name !== cacheStorageKey) {
        return caches.delete(name);
      } else {
        return Promise.resolve();
      }
    }));
  });

  e.waitUntil(
    Promise.all([cacheDeletePromises])
  );
});

// 緩存和返回請求
self.addEventListener('fetch', function(e) {
  // 在此編寫緩存策略
  e.respondWith(
    // 能夠經過匹配緩存中的資源返回
    caches.match(e.request)
    // 也能夠從遠端拉取
    fetch(e.request.url)
    // 也能夠本身造
    new Response('hell0')
    // 也能夠經過吧 fetch 拿到的響應經過 caches.put 方法放進 caches
  );
});


複製代碼

test

Workbox

workbox 用於支持離線web apps的js庫, 是Google 根據SW的最佳實踐推出的官方框架,封裝了SW底層的API來監聽SW的安裝,激活,fetch事件以及緩存等相關邏輯處理,使用起來更簡單方便。webpack

  • 預緩存
  • 運行時緩存np
  • 策略(Strategies)
  • 請求路由
  • 後臺同步
  • 便捷的調試
  • 相比於 sw-precache和 sw-toolbox 具備更大的靈活性和更完備的功能

Workbox 的主要功能是它的路由和緩存策略模塊。偵聽網頁的請求,並根據策略如何緩存和響應請求。這兩個功能的具體實現對應於它們的workerbox的workbox.routing ,workbox.strategies 和workbox.precaching。 經過 workbox.routing 模塊提供的路由控制和 workbox.strategies 模快提供的緩存策略控制幫助你作動態緩存。經過workbox.precaching 模塊來處理 Service Worker 靜態資源的預緩存。git

緩存策略

利用 workbox.precaching 模塊來處理 Service Worker 靜態資源的預緩存。github

//  precache (預緩存) 靜態文件 一般項目中的 sw.js 源文件都是經過這樣預留一個空數組的方式來預緩存內容列表的
  workbox.precaching.precacheAndRoute([
    // 註冊成功後要當即緩存的資源列表
    "/test.css",
    "/index.js",
    {
      url: "/index.html",
      revision: "383676"    //-- revision 能夠經過工具插件workbox-webpack-plugin維護
    }
  ]);

複製代碼

路由請求

workbox.routing有3種方式來攔截匹配到的請求web

  • string
  • 正則
  • 回調函數
// string
workbox.routing.registerRoute(
  '/logo.png',
  handler
);

// RegExp
workbox.routing.registerRoute(
  new RegExp('\\.js$'),
  jsHandler
 );
 

// Callback Function
const matchFunction = ({url, event}) => {
  // Return true if the route should match
  return false;
};

workbox.routing.registerRoute(
  matchFunction,
  handler
);



複製代碼

上述中的處理函數有兩種方式chrome

  • 使用workbox.strategies.
  • 提供一個Promise的回調函數

然而,利用 workbox.routing 模塊提供的路由控制和 workbox.strategies 模快提供的緩存策略控制幫助你作動態緩存。數組

緩存策略

Stale While Revalidate

這種策略當請求的路由有對應的 Cache 緩存結果就直接返回,在返回 Cache 緩存結果的同時會在後臺發起網絡請求拿到請求結果並更新 Cache 緩存,若是原本就沒有 Cache 緩存的話,直接就發起網絡請求並返回結果。瀏覽器

workbox.routing.registerRoute(
    match, // 匹配的路由
    workbox.strategies.staleWhileRevalidate()
);
複製代碼
Network First

這種策略就是當請求路由是被匹配的,就採用網絡優先的策略,也就是優先嚐試拿到網絡請求的返回結果,若是拿到網絡請求的結果,就將結果返回給客戶端而且寫入 Cache 緩存,若是網絡請求失敗,那最後被緩存的 Cache 緩存結果就會被返回到客戶端,這種策略通常適用於返回結果不太固定或對實時性有要求的請求,爲網絡請求失敗進行兜底。緩存

Cache First

這個策略的意思就是當匹配到請求以後直接從 Cache 緩存中取得結果,若是 Cache 緩存中沒有結果,那就會發起網絡請求,拿到網絡請求結果並將結果更新至 Cache 緩存,並將結果返回給客戶端。這種策略比較適合結果不怎麼變更且對實時性要求不高的請求。

以前的疑問,若是網絡請求一直失敗的狀況, 是和 Stale While Revalidate的動做同樣的 ,是發請求,成功以後而後更新緩存,若是第一次也是失敗的,緩存中無對應結果,一樣也是是發請求,成功以後而後更新緩存。

Network Only

比較直接的策略,直接強制使用正常的網絡請求,並將結果返回給客戶端,這種策略比較適合對實時性要求很是高的請求。能夠像以下方式使用 Network Only 策略:

Cache Only

這個策略也比較直接,直接使用 Cache 緩存的結果,並將結果返回給客戶端,這種策略比較適合一上線就不會變的靜態資源請求。能夠像以下方式使用 Cache Only 策略

tips

  • 查看啓動的SW

    • chrome://inspect/#service-workers查看啓動的sw
  • https sw 只工做在安全模式下

    • 本地的local和http 模式下sw都註冊不成功。
  • Web App Manifest Generator這個工具能夠幫助生成 manifest

  • 策略

    • 靜態資源圖片等使用 Cache First
    • CSS 和 JS, 使用 Stale-While-Revalidate 策略,既保證了頁面速度,即使失敗,用戶刷新一下就更新了
    • 不建議使用 Cache only 和 Cache first

參考

Workbox 官方文檔 Workbox 3.0

代碼實例

GitHub

相關文章
相關標籤/搜索