1、什么是Workbox Strategies?
當service workers 首次被引入時,可以設定一組常見的緩存策略。 緩存策略是一種模式,用於確定service workers 在收到fetch事件后如何生成響應。
workbox-strategies提供了最常用的緩存策略,因此很容易將它們應用到服務工作者中。
我們不會在Workbox支持的策略之外詳細介紹,但你可以在Offline Cookbook中了解更多信息
2、使用策略
在以下示例中,我們將向你展示如何在workbox-routing中使用Workbox緩存策略。 你可以使用本文的“配置策略”部分中介紹的每種策略定義一些選項。
在高級用法部分,我們將介紹如何在沒有workbox-routing的情況下直接使用緩存策略。
下面我們將介紹幾種基本的策略
2.1 Stale-While-Revalidate

stale-while-revalidate模式允許你使用緩存的內容盡快響應請求(如果可用),如果未緩存,則回退到網絡請求。 然后,網絡請求用於更新緩存。
這是一種相當常見的策略,適合更新頻率很高但重要性要求不高(至少允許一次緩存讀取)的內容。在有緩存的情況下,該模式保證了客戶端第一時間拿到數據的同時,也會去請求網絡資源更新緩存,保證下次客戶端從緩存中讀取的數據是最新的。因此該模式不能減輕后台服務器的訪問壓力,但卻能給前端用戶提供快速響應的體驗。
workbox.routing.registerRoute( // 當是資源js文件的時候 new RegExp('(app|manifest|vendor)+.js'), workbox.strategies.staleWhileRevalidate({ cacheName: 'main-js' }) )
2.2 Cache First (緩存優先,緩存回落到網絡)

離線Web應用程序將嚴重依賴緩存,但對於非關鍵且可逐步緩存的資產,首先緩存是最佳選擇。
如果緩存中有響應,則將使用緩存的響應來完成請求,根本不會使用網絡。 如果沒有緩存的響應,則將通過網絡請求來滿足請求,並且將緩存響應,以便直接從緩存提供下一個請求。
該模式可以在為前端提供快速響應的同時,減輕后台服務器的訪問壓力。但是數據的時效性就需要開發者通過設置緩存過期時間或更改sw.js里面的修訂標識來完成緩存文件的更新。一般需要結合實際的業務場景來判斷數據的時效性。
workbox.routing.registerRoute( new RegExp('/styles/'), workbox.strategies.cacheFirst() );
2.3 Network First (網絡回落到緩存)
對於經常更新且關鍵(由業務判斷出來)的請求,網絡優先策略是理想的解決方案。 默認情況下,它將嘗試從網絡獲取最新請求。 如果請求成功,它會將響應放入緩存中。 如果網絡無法返回響應,則將使用緩存響應。

workbox.routing.registerRoute( new RegExp('/index/'), workbox.strategies.networkFirst() );
這意味着只要當第一次請求成功時,service worker就會緩存一份請求結果。當后續重復請求時,緩存也會每次更新。
若網絡請求失敗時,只要緩存里有內容,就能讓前端獲取一個響應(從service worker的緩存里)。因此,此種模式提高了前端頁面的穩固性,即使在網絡請求失敗的情況下,頁面也能從上次的緩存中讀取到數據展示,而不是粗魯的告訴用戶網絡請求失敗的一個響應。
workbox.routing.registerRoute( new RegExp('/index/'), workbox.strategies.networkFirst() );
2.4 Network Only

如果你需要從網絡中完成特定請求,則首先要使用網絡策略。
workbox.routing.registerRoute( new RegExp('/admin/'), workbox.strategies.networkOnly() );
2.5 Cache Only

僅緩存策略確保從緩存獲取請求。 這在workbox中不太常見,但如果你有自己的預先緩存步驟則可能很有用。
workbox.routing.registerRoute( new RegExp('/app/v2/'), workbox.strategies.cacheOnly() );
3、配置策略
所有策略都允許你配置:
- 要在策略中使用的緩存的名稱。
- 緩存在策略中使用的過期限制。
- 一組插件,在獲取和緩存請求時將調用其生命周期方法。
3.1 更改策略使用的緩存
你可以通過提供緩存名稱來更改緩存所使用的策略。 如果要分離資源以幫助調試,這非常有用。
workbox.routing.registerRoute( new RegExp('/images/'), workbox.strategies.cacheFirst({ cacheName: 'image-cache', }) );
3.2 使用插件
Workbox附帶了一組可以與這些策略一起使用的插件。
- workbox.expiration.Plugin
- workbox.cacheableResponse.Plugin
- workbox.broadcastUpdate.Plugin
- workbox.backgroundSync.Plugin
要使用任何這些插件(或自定義插件),你只需將實例傳遞給插件選項。
后續文章會專門介紹這些插件模塊的用法。
workbox.routing.registerRoute( new RegExp('/images/'), workbox.strategies.cacheFirst({ cacheName: 'image-cache', plugins: [ new workbox.expiration.Plugin({ // Only cache requests for a week maxAgeSeconds: 7 * 24 * 60 * 60, // Only cache 10 requests. maxEntries: 10, }), ] }) );
4、高級用法
如果要在自己的fetch事件邏輯中使用策略,可以使用策略類通過特定策略運行請求。
例如,要實現stale-while-revalidate類,您可以執行以下操作:
self.addEventListener('fetch', (event) => { if (event.request.url === '/') { const staleWhileRevalidate = new workbox.strategies.StaleWhileRevalidate(); event.respondWith(staleWhileRevalidate.handle({event})); } });