摘要:已經(jīng)得到越來越多的瀏覽器的支持,包括蘋果騰訊的內(nèi)核。蘋果從開始,已經(jīng)開始支持了。針對(duì)各種應(yīng)用場景的多種緩存策略。在無網(wǎng)絡(luò)環(huán)境的情況,也可以做到離線緩存的效果,極大地提升頁面的用戶體驗(yàn)。
什么是workbox,workbox有什么用途,為什么要使用它?在介紹workbox之前,我們來先大致了解一下service worker,有助于我們后面更好地去理解workbox。
一. service workerservice worker是在瀏覽器后臺(tái)獨(dú)立于網(wǎng)頁運(yùn)行的腳本,它能夠?qū)崿F(xiàn)對(duì)網(wǎng)絡(luò)請求進(jìn)行緩存,并向網(wǎng)頁推送和同步信息的功能,令人更加興奮的是,它可以實(shí)現(xiàn)離線的情況下,也能看到我們的網(wǎng)頁,極大提升了我們的用戶體驗(yàn)。
service worker 已經(jīng)得到越來越多的瀏覽器的支持,包括蘋果、騰訊的X5內(nèi)核。蘋果從safari11開始,已經(jīng)開始支持了。支持情況如下:
workbox 是 GoogleChrome 團(tuán)隊(duì)推出的一套 Web App 靜態(tài)資源和請求結(jié)果的本地存儲(chǔ)的解決方案,該解決方案包含一些 Js 庫和構(gòu)建工具,在 Chrome Submit 2017 上首次隆重面世。而在 workbox 背后則是 Service Worker 和 Cache API 等技術(shù)和標(biāo)準(zhǔn)在驅(qū)動(dòng)。在 Workebox 之前,GoogleChrome 團(tuán)隊(duì)較早時(shí)間推出過 sw-precache 和 sw-toolbox 庫,但是在 GoogleChrome 工程師們看來,workbox 才是真正能方便統(tǒng)一的處理離線能力的更完美的方案,所以停止了對(duì) sw-precache 和 sw-toolbox 的維護(hù)。那workbox能解決什么問題呢?
在service worker中,如果我們要攔截并代理所有的請求,需要我們手動(dòng)去維護(hù)一套緩存列表。但是現(xiàn)在前端開發(fā),多數(shù)用webpack、gulp、grant來構(gòu)建前端的代碼,導(dǎo)致我們的文件名可能會(huì)經(jīng)常發(fā)生,這個(gè)時(shí)候,特別是中大型的多頁應(yīng)用,緩存列表的內(nèi)容可能會(huì)非常多,手動(dòng)維護(hù)就顯得非常麻煩,維護(hù)成本也變得很高。
這個(gè)時(shí)候,workbox的橫空出世,就是為了解決上面的問題。
workbox的一些特性:不管你的站點(diǎn)是哪種方式構(gòu)建的,都可以實(shí)現(xiàn)離線緩存的效果;
自動(dòng)管理好緩存列表,包括更新、同步、刪除舊的緩存等;
配置簡單卻不失靈活,可以完全自定義相關(guān)需求(支持 Service Worker 相關(guān)的特性如 Web Push, Background sync 等)。
針對(duì)各種應(yīng)用場景的多種緩存策略。
三. workbox的使用下面來看下workbox的例子。
1.在入口頁面的onload中,注冊一個(gè)service worker,注冊時(shí)引入緩存列表文件,也就是build.sw.js。
index.html
我們來看下build.sw.js文件的內(nèi)容,主要包含緩存列表和緩存策略。這里面的內(nèi)容不用我們手動(dòng)生成,workbox有三種方式生成,我們可以使用workbox-webpack-plugin、workbox-cli、workbox-build。我們暫不討論具體的實(shí)現(xiàn),在這里,我們先來了解一下預(yù)緩存列表和緩存策略這兩個(gè)東西。
預(yù)緩存列表如果我們要緩存靜態(tài)資源,平時(shí)不會(huì)經(jīng)常更新,只有到發(fā)版時(shí)才會(huì)修改了資源的hash值,才需要重新更新的,那那 precache 預(yù)緩存應(yīng)該是你所期待的。
workbox 提供了一種非常方便的 API 幫助我們解決 precache 的問題,我們可以使用workbox.precaching來配置,配置格式如下:
workbox.precaching.precacheAndRoute([ { "url": "將要預(yù)緩存的文件 URL", "revision": "緩存的hash值" }, ])路由請求緩存路由請求緩存是指通過對(duì)匹配路由給文件采取不用的緩存方式,這個(gè)可以通過workbox.routing.registerRoute來進(jìn)行配置。 路由匹配的方式有三種:
1.通過字符串的方式進(jìn)行匹配
// 可以直接是當(dāng)前項(xiàng)目下的絕對(duì)路徑 workbox.routing.registerRoute( "path/to/logo.png", handler // handler 是做緩存策略的回調(diào)函數(shù),通常指后面所會(huì)降到的 "緩存策略函數(shù)" ); // 也可以是完整的帶完整 host 的 URL 路徑,這里的 URL 必須是 https 的 workbox.routing.registerRoute( "https://example.com/a/b/c.jpg", handler );2.通過正則的方式進(jìn)行匹配
workbox.routing.registerRoute( new RegExp(".*.(js|css|jpg|png|gif)"), // 這里是任何正則都行,只要能匹配得上的請求路由地址 handler );3.通過回調(diào)函數(shù)的方式進(jìn)行匹配
// 通過回調(diào)函數(shù)來匹配請求路由將會(huì)讓策略更加靈活 const customFun = ({url, event}) => { // 如果請求路由匹配了就返回true,也可以返回一個(gè)參數(shù)對(duì)象以供 handler 接收處理 return false; }; workbox.routing.registerRoute( customFun, handler );緩存策略緩存策略是指對(duì)于匹配到的路由,采取何種方式進(jìn)行緩存。 workbox提供了兩種配置緩存策略的方式
通過 workbox.strategies API 提供的 緩存策略。
提供一個(gè)自定義返回帶有返回結(jié)果的 Promise 的回調(diào)方法。
以下介紹workbox默認(rèn)提供的幾種緩存策略,包含有五種,分別是:
Stale While Revalidate
Network First
Cache First
Network Only
Cache Only
Stale While Revalidate這種策略的意思是當(dāng)請求的路由有對(duì)應(yīng)的 Cache 緩存結(jié)果就直接返回,在返回 Cache 緩存結(jié)果的同時(shí)會(huì)在后臺(tái)發(fā)起網(wǎng)絡(luò)請求拿到請求結(jié)果并更新 Cache 緩存,如果本來就沒有 Cache 緩存的話,直接就發(fā)起網(wǎng)絡(luò)請求并返回結(jié)果。 使用方式如下:
workbox.routing.registerRoute( match, // 匹配的路由 workbox.strategies.staleWhileRevalidate() );Network First這種策略就是當(dāng)請求路由是被匹配的,就采用網(wǎng)絡(luò)優(yōu)先的策略,也就是優(yōu)先嘗試拿到網(wǎng)絡(luò)請求的返回結(jié)果,如果拿到網(wǎng)絡(luò)請求的結(jié)果,就將結(jié)果返回給客戶端并且寫入 Cache 緩存,如果網(wǎng)絡(luò)請求失敗,那最后被緩存的 Cache 緩存結(jié)果就會(huì)被返回到客戶端 使用方式如下:
workbox.routing.registerRoute( match, // 匹配的路由 workbox.strategies.networkFirst() );Cache First這個(gè)策略的意思就是當(dāng)匹配到請求之后直接從 Cache 緩存中取得結(jié)果,如果 Cache 緩存中沒有結(jié)果,那就會(huì)發(fā)起網(wǎng)絡(luò)請求,拿到網(wǎng)絡(luò)請求結(jié)果并將結(jié)果更新至 Cache 緩存,并將結(jié)果返回給客戶端。
workbox.routing.registerRoute( match, // 匹配的路由 workbox.strategies.cacheFirst() );Network Only比較直接的策略,直接強(qiáng)制使用正常的網(wǎng)絡(luò)請求,并將結(jié)果返回給客戶端,這種策略比較適合對(duì)實(shí)時(shí)性要求非常高的請求。
workbox.routing.registerRoute( match, // 匹配的路由 workbox.strategies.networkOnly() );Cache Only這個(gè)策略也比較直接,直接使用 Cache 緩存的結(jié)果,并將結(jié)果返回給客戶端,這種策略比較適合一上線就不會(huì)變的靜態(tài)資源請求。
workbox.routing.registerRoute( match, // 匹配的路由 workbox.strategies.cacheOnly() );四. 使用workerbox后的效果在我們的項(xiàng)目中,我們以DomContentLoaded的時(shí)間作為參考點(diǎn),對(duì)比有加service worker 和未加的service worker情況。
測試條件
以首頁為例,在不同的網(wǎng)絡(luò)環(huán)境下,發(fā)起10次網(wǎng)絡(luò)請求,然后取平均值,作為它們的最終結(jié)果,測試結(jié)果如下:
通過上面的數(shù)據(jù)可以得出幾個(gè)結(jié)論:
在弱環(huán)境下,service worker的優(yōu)勢越發(fā)明顯,
即使在wifi環(huán)境下面,由于存在緩存的情況,瀏覽器加載的速度也比未使用service worker的時(shí)間要短。
在無網(wǎng)絡(luò)環(huán)境的情況,也可以做到離線緩存的效果,極大地提升頁面的用戶體驗(yàn)。
五. 幾個(gè)注意點(diǎn)在使用workbox的過程中,會(huì)遇到一些問題,下面列出幾點(diǎn),也算是做個(gè)總結(jié):
1. service worker 注冊文件放置的位置在頁面注冊service worker的時(shí)候,盡量注冊到項(xiàng)目的根目錄下,這樣才能最大的發(fā)揮service worker的作用
// build.sw.js最好放在項(xiàng)目的根目錄下,才能發(fā)揮最大的緩存效果 navigator.serviceWorker.register(`./build.sw.js`) // 如果這樣配置的話,就只有path目錄下面的文件才能實(shí)現(xiàn)緩存,其他目錄,包括根目錄的都不能緩存 navigator.serviceWorker.register(`./path/build.sw.js`)2.使用workbox 命令行生成預(yù)緩存列表的注意點(diǎn)我們先預(yù)設(shè)一下應(yīng)用場景:假設(shè)你的項(xiàng)目在目錄 /app 下,必須保證在你的項(xiàng)目根目錄下有一個(gè) app/sw.js 包含以下內(nèi)容:
// 通常項(xiàng)目中的 sw.js 源文件都是通過這樣預(yù)留一個(gè)空數(shù)組的方式來預(yù)緩存內(nèi)容列表的 workbox.precaching.precacheAndRoute([]);這樣才能保證能將生成的預(yù)緩存內(nèi)容列表內(nèi)容注入到 Service Worker 文件中。
3.緩存策略設(shè)置在經(jīng)過一段時(shí)間的使用和思考以后,給出認(rèn)為較為合理的緩存策略:
HTML,如果想讓頁面離線可以訪問,使用 NetworkFirst,如果不需要離線訪問,使用 NetworkOnly,其他策略均不建議對(duì) HTML 使用。
CSS 和 JS,情況比較復(fù)雜,因?yàn)橐话阏军c(diǎn)的 CSS,JS 都在 CDN 上,SW 并沒有辦法判斷從 CDN 上請求下來的資源是否正確(HTTP 200),如果緩存了失敗的結(jié)果,問題就大了。建議使用 Stale-While-Revalidate 策略,既保證了頁面速度,即便失敗,用戶刷新一下就更新了。
如果CSS,JS 與站點(diǎn)在同一個(gè)域下,并且文件名中帶了 Hash 版本號(hào),那可以直接使用 Cache First 策略。
圖片建議使用 Cache First,并設(shè)置一定的失效事件,請求一次就不會(huì)再變動(dòng)了。
如果大家在使用過程中有更友好的策略,麻煩也貢獻(xiàn)你們的策略,大家共同學(xué)習(xí),共同進(jìn)步。
還有,要牢記,對(duì)于不在同一域下的任何資源,絕對(duì)不能使用 Cache only 和 Cache first。
4.service worker的運(yùn)行環(huán)境需要注意的是,Service Worker 腳本除了域名為 localhost 時(shí)能運(yùn)行在 http 協(xié)議下以外,只能運(yùn)行 https 協(xié)議下。
5. 使用Service Worker緩存請求時(shí),POST請求無法緩存Google對(duì)web的標(biāo)準(zhǔn)化還是遵循的,SW認(rèn)為POST請求就是象服務(wù)器提交資源,不存在緩存需求
參考文檔:
https://developers.google.com...
https://zoumiaojiang.com/arti...
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/103566.html
摘要:原文地址譯文出自我的個(gè)人博客概述在本文中,您將學(xué)習(xí)如何使用和創(chuàng)建離線優(yōu)先數(shù)據(jù)驅(qū)動(dòng)的漸進(jìn)式應(yīng)用程序。在離線的情況下也可以使用后臺(tái)同步功能將應(yīng)用程序與服務(wù)器同步。保存數(shù)據(jù)到中現(xiàn)在我們保存數(shù)據(jù)到剛創(chuàng)建的數(shù)據(jù)庫中的對(duì)象中。 原文地址:Build an offline-first, data-driven PWA譯文出自:我的個(gè)人博客 概述 在本文中,您將學(xué)習(xí)如何使用 Workbox 和 In...
摘要:另外,單頁應(yīng)用因?yàn)閿?shù)據(jù)前置到了前端,不利于搜索引擎的抓取。所以我們需要對(duì)自己的單頁應(yīng)用進(jìn)行一些優(yōu)化。 前言 最近秋招之余空出時(shí)間來按自己的興趣動(dòng)手做了一個(gè)項(xiàng)目,一個(gè)基于vue-cli3.0, vue,typescript的移動(dòng)端pwa,現(xiàn)在趁熱打鐵,將這個(gè)項(xiàng)目從開發(fā)到部署整個(gè)過程記錄下來,并將從這個(gè)項(xiàng)目中學(xué)習(xí)到的東西分享出來,如果大家有什么意見或補(bǔ)充也可以在評(píng)論區(qū)提出。先介紹一下這個(gè)項(xiàng)...
摘要:是谷歌近幾年一直在推進(jìn)的應(yīng)用新模型。既然如此,我們最好是站在巨人的肩膀上,這個(gè)巨人就是谷歌。是由谷歌瀏覽器團(tuán)隊(duì)發(fā)布,用來協(xié)助創(chuàng)建應(yīng)用的庫。當(dāng)然直接用還是太復(fù)雜了,谷歌還很貼心的發(fā)布了一個(gè)插件,能夠自動(dòng)生成和靜態(tài)資源列表。 PWA(Progressive Web Apps)是谷歌近幾年一直在推進(jìn)的 web 應(yīng)用新模型。PWA 借助 Service Worker 緩存網(wǎng)站的靜態(tài)資源,甚至...
摘要:最后用把緩存的路徑憑證信息存在中。緩存策略現(xiàn)在來看看提供的緩存策略,主要有這幾種。自定義緩存配置回到在緩存策略里提到的,講講和緩存策略的參數(shù)。 作者:陳達(dá)孚 香港中文大學(xué)研究生,《移動(dòng)Web前端高效開發(fā)實(shí)戰(zhàn)》作者之一,《前端開發(fā)者指南2017》譯者之一,在中國前端開發(fā)者大會(huì),中生代技術(shù)大會(huì)等技術(shù)會(huì)議發(fā)表過主題演講, 專注于新技術(shù)的調(diào)研和使用. 本文為原創(chuàng)文章,轉(zhuǎn)載請注明作者及出處 ...
摘要:另一部分屬于進(jìn)程,它重新在后臺(tái)起了一個(gè)進(jìn)程,它和應(yīng)用的主進(jìn)程互不影響,可以同時(shí)執(zhí)行。其中一般作為應(yīng)用程序?yàn)g覽器和網(wǎng)絡(luò)如果可用之間的代理服務(wù)。他們還將允許訪問推送通知和后臺(tái)同步。然后開始在進(jìn)程中通過事件,來監(jiān)聽請求,并對(duì)請求和響應(yīng)進(jìn)行緩存。 前言:我們的應(yīng)用可以分為兩部分,一部分是屬于主進(jìn)程的(包括js(同步,異步),以及dom渲染等等),在一個(gè)時(shí)刻點(diǎn),只能執(zhí)行一個(gè),要么先去渲染dom,...
閱讀 2849·2021-11-19 09:40
閱讀 3709·2021-11-15 18:10
閱讀 3289·2021-11-11 16:55
閱讀 1246·2021-09-28 09:36
閱讀 1663·2021-09-22 15:52
閱讀 3375·2019-08-30 14:06
閱讀 1171·2019-08-29 13:29
閱讀 2317·2019-08-26 17:04