在前端愈來愈重的這個時代,頁面加載速度成爲了一個重要的指標。對於這個問題,業界也有一些解決方案。css
其實在兩年前內部就對這塊內容作過調研了。appCache
方案?PWA
方案?可是最後都沒選擇。
以前看代碼,發現是 localstroage
存代碼,若是有就拿 localstroage
去用。省去了這一部分加載的時間。
上個同事離職了。當時的調研結果我也忘了。只能再開始新一輪的調研,我選擇的是 PWA
方案。(若是說是網速拖慢了加載速度,那麼個人網頁能夠離線訪問不就速度起飛了?)
網上的資料不多。我但願我能夠寫一篇幫助下一個想使用 PWA
方案的人。html
Service worker
是一個註冊在指定源和路徑下的事件驅動worker
。前端
Service worker
運行在worker
上下文,所以它不能訪問DOM。不一樣於主線程,它運行在其餘線程中,因此不會形成主線程阻塞。它設計爲徹底異步,同步API(如XHR和localStorage)不能在service worker中使用。vue
Service workers
本質上充當Web應用程序(服務端)與瀏覽器(客戶端)之間的代理服務器。
能夠提供有效有效的離線體驗,攔截網絡請求。還能夠推送通知。webpack
Service Workers
要求必須在 HTTPS
下才能運行。(其實好多API
都須要HTTPS
的支持)scope
),爲資源路徑。https://www.lilnong.top/static/js/sw-20190621.js
的最大做用路徑爲/static/js/
localhost
也被瀏覽器認爲是安全源。serivce workers
的瀏覽器的版本中,不少特性沒有默認開啓。若是你發現示例代碼在當前版本的瀏覽器中怎麼樣都沒法正常運行,你可能須要開啓一下瀏覽器的相關配置:about:config
並設置 dom.serviceWorkers.enabled
的值爲 true
; 重啓瀏覽器;chrome://flags
並開啓 experimental-web-platform-features;
重啓瀏覽器 (注意:有些特性在Chrome
中沒有默認開放支持);opera://flags
並開啓 ServiceWorker
的支持; 重啓瀏覽器。下載web
service worker
控制的網站或頁面時,service worker
會馬上被下載。安裝chrome
激活vue-cli
service worker
已啓用,新版本會在後檯安裝,但不會被激活,這個時序稱爲worker in waiting
service worker
纔會激活新的service worker
。新的service worker
會被激活(成爲active worker
)。咱們頁面引入sw.js
內容爲a
。當咱們修改成b
。
這時候a
和b
都是已經安裝完畢的,可是a
是當前正在用的。b
須要等沒有頁面在用a
,纔會進入激活狀態。segmentfault
Cache
爲緩存的 Request
/Response
對象對提供存儲機制。
當前咱們做爲 ServiceWorker
生命週期的一部分。儘管它被定義在 service worker
的標準中, 可是它沒必要必定要配合 service worker
使用。也暴露在 window
做用域下的。api
request
是一個字符串類型的 URL
。如cache.add('https://www.lilnong.top/static/css/normalize-8.0.0.css')
fetch()
, 而後使用 Cache.put()
將 response
添加到 cache
中。Cache.match(request, options)
返回一個 Promise
對象,resolve
的結果是跟 Cache
對象匹配已經緩存的請求。requres
同上,是要匹配的 URL
options
以下
ignoreSearch
: 設置是否忽略url
中的query
。該選項默認爲 false
。ignoreMethod
: true
匹配時就不會驗證 Request
對象的 http
方法 (一般只容許是 GET
或 HEAD
。) 該參數默認值爲 false。ignoreVary
: 爲 true 時匹配不進行 VARY
部分的匹配。例如,若是一個URL
匹配,此時不管Response
對象是否包含VARY
頭部,都會認爲是成功匹配。該參數默認爲 false。cacheName
: 一個 DOMString ,表明一個具體的要被搜索的緩存。注意該選項被 Cache.match()方法忽略。URL
設置response
Cache
條目,而且返回一個resolve
爲true
的Promise
對象;若是未找到,則返回一個resolve
爲false
的Promise
對象。resolve
的結果是Cache
對象key
值(request 對象)組成的數組。serviceWorkerContainer.register()
來註冊service worker
如今能夠接收事件。service worker
控制的頁面打開後會嘗試去安裝 service worker
。service worker
的事件是安裝事件(在這個事件裏能夠開始進行填充 IndexDB和緩存站點資源),讓全部資源可離線訪問。oninstall
事件的處理程序執行完畢後,能夠認爲 service worker
安裝完成了。service worker
安裝完成後,會接收到一個激活事件 onactivate
主要用途是清理先前版本的 service worker
腳本中使用的資源。Service Worker
如今能夠控制頁面了,但僅是在 register()
成功後的打開的頁面。if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/sw-test/sw.js', { scope: '/sw-test/' }).then(function(reg) { // registration worked console.log('Registration succeeded. Scope is ' + reg.scope); }).catch(function(error) { // registration failed console.log('Registration failed with ' + error); }); }
測試路徑
https://www.lilnong.top/stati...
https
SW
經過fetch
來實現代理瀏覽器請求。SW
註冊以後會嘗試安裝。可是激活須要等下次(沒有再用的資源了)SW
要注意他限制的域importScripts('https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js');
是一個封裝包vue-cli
也有一些webpack
支持的工具
@vue/pwa
@vue/cli-plugin-pwa
參數中的request能夠是
"https://www.lilnong.top/static/project/pwa-20190625/index.5.html"
也能夠是Request
對象。
fetch
<html manifest="example.appcache">