提問
sw-precache是什么?
workbox又是什么?
web前端的各位同學(xué)可能或多或少聽過pwa,聽過service worker(后面簡稱為SW),也知道對應(yīng)的生命周期。知道了這些api后,你還是不知道如何將pwa技術(shù)投入生產(chǎn)。它不僅僅是個玩具,它是一個“神器”,是用來拉近native和web app之間的差距。當我們做spa項目越做越大的時候,JS bundle會越來越大,單頁面不能承載那么多的邏輯,我們可能會選擇多個單頁面(也就是多頁面)。每次加載都會存在空白加載的情景,雖然性能優(yōu)化上,我們能把這個時間減少到很少很少,但是沒法完全把它“干掉”。pwa的service-worker技術(shù)很好地彌補這片“空白”?!癮pp-shell”也就是web app中的應(yīng)用殼將會緩存在瀏覽器端,讓它的加載速度更加快速。而可變的內(nèi)容則是異步加載。
歷史背景
有很多文章把pwa技術(shù)和小程序技術(shù)放在一起比較。谷歌瀏覽器至于pwa,微信至于小程序,都是給網(wǎng)頁應(yīng)用提供了離線緩存靜態(tài)資源文件的功能,動靜分離,native的接口,這些都是給網(wǎng)頁應(yīng)用提供更優(yōu)質(zhì)的加載性能。但是小程序并沒有BOM和DOM,意味著它對瀏覽器有著更深入的改造,它并非純正意義上的網(wǎng)頁應(yīng)用,是對所有Web開發(fā)資源的一種限制。
相反,pwa則不一樣。
安卓的支持

考慮到service worker是一個新的接口本身,肯定會存在兼容性問題。PWA的意思在于Progressive,也就是支持pwa的頁面則使用SW的緩存機制,而不支持的頁面使用原來的HTTP緩存機制。由于pwa是谷歌的“親兒子”,所以它在新版本安卓的各大瀏覽器都有非常好的支持。詳情我們可以參考lavas的兼容性報告
重點的重點當然是微信瀏覽器對pwa的支持情況,我們可以看到除了推送信息和支付接口之外基本已經(jīng)實現(xiàn)支持(支付接口的支持應(yīng)該是出于安全的考慮,以及和weixin-js-sdk重疊的原因,X5瀏覽器支持它只是時間的問題)。如今我們更關(guān)心的是關(guān)于SW-cache這一部分,換句話說,我們可以放心在安卓微信上使用SW-cache的技術(shù)。

ios(蘋果)的支持
《震驚!蘋果向開發(fā)者低頭???!開始支持Service Worker》一文中講述了蘋果的開發(fā)工程師開始完成研發(fā),并且在2017年底safari桌面技術(shù)預(yù)覽版上已經(jīng)實現(xiàn)了service worker的相關(guān)api,從In development的狀態(tài)轉(zhuǎn)移到Supported In Preview,這意味著service worker極有可能在IOS12得到支持(詳情https://webkit.org/status),這也就意味著pwa的時代很快就會到來。

sw-precache 和 workbox
我們知道vue-cli打造出來的pwa模版,使用的是sw-precache,而workbox是它的取代品。它們各自有一個webpack版的插件,分別是sw-precache-webpack-plugin和workbox-webpack-plugin。
結(jié)合Vue筆記八:多頁面打包框架的多頁面打包框架,我添加上precache的功能(以后計劃替換成為workbox),實現(xiàn)多頁面的service worker框架,github的地址是https://github.com/brandonxiang/mpa-pwa
我寫了一個關(guān)于workbox在vue-webpack框架的腳手架,github的地址是https://github.com/brandonxiang/example-vue-workbox,大家可以參考一下。
它們之間的區(qū)別如下,可以說非常相似:
| 中文說明 | workbox | 中文說明 | sw-precache |
|---|---|---|---|
| 緩存的目錄 | globDirectory | 緩存前綴 | stripPrefix |
| 緩存的靜態(tài)文件類型 | globPatterns | 緩存的靜態(tài)文件類型 | staticFileGlobs |
| sw文件路徑 | swDest | sw文件名 | filename |
| 讓sw立即接管網(wǎng)頁 | clientsClaim | (相同) | clientsClaim |
| 激活的等待 | skipWaiting | (相同) | skipWaiting |
| 動態(tài)請求 | runtimeCaching | (相同) | runtimeCaching |
sw-precache的主要開發(fā)者 jeffposnick 也是workbox的主要開發(fā)者,這說明了它們之間的關(guān)系,sw-precache是為了滿足service worker的cache API中的靜態(tài)資源文件的注冊作用。而workbox是為了滿足所有pwa的資源內(nèi)容,可以看作一個“平臺”。

workbox中已經(jīng)支持很多方面的內(nèi)容,當然,還有很多內(nèi)容有待開發(fā)。
緩存機制
Service Worker的出現(xiàn)很大程度,改變了web app的格局,HTTP cache和SW cache有著天壤之別。這樣的HTTP緩存機制沒法彌補網(wǎng)頁跳轉(zhuǎn)帶來的白屏間隙,SW cache由于優(yōu)先緩存靜態(tài)資源以及接口的機制,大大減少了網(wǎng)絡(luò)狀況差(甚至斷網(wǎng))帶來的白屏現(xiàn)象。優(yōu)先更新本地的同時,service worker會和后端進行一次通信,這次通信會告知靜態(tài)資源是否被更改,在下次刷新的時候更改內(nèi)容。
動態(tài)接口方面則會采用 runtimeCaching 進行交互,這部分也會進行動態(tài)內(nèi)容的緩存,sw-toolbox的代碼將會被引入你的sw.js中,它會利用正則表達式匹配到你請求的接口,進行接口緩存,當該接口出現(xiàn)內(nèi)容變化時,SW會和后端進行一次通訊保證下一次加載的數(shù)據(jù)是最新數(shù)據(jù),這樣的更新機制分為5個類型。
- networkFirst
- cacheFirst
- fastest
- cacheOnly
- networkOnly
networkFirst是顯示完成后,SW優(yōu)先和后端通訊,看接口是否更新,下一次刷新則是采用最新數(shù)據(jù)內(nèi)容。cacheFirst則是優(yōu)先考慮緩存,如果緩存沒有命中,才會去請求接口拿新數(shù)據(jù),這個選型適合那種不經(jīng)常更改的內(nèi)容或者有別的更新機制。fastest則是兩個同時進行,哪個快執(zhí)行哪個。cacheOnly和networkOnly比較不常用。