Service Workers (PWA 初體驗)

在前端愈來愈重的這個時代,頁面加載速度成爲了一個重要的指標。對於這個問題,業界也有一些解決方案。css

  1. 瀏覽器緩存、協議緩存、強緩存
  2. 懶加載(首屏)
  3. CDN 多域名突破下載併發限制。

其實在兩年前內部就對這塊內容作過調研了。appCache方案?PWA方案?可是最後都沒選擇
以前看代碼,發現是 localstroage 存代碼,若是有就拿 localstroage 去用。省去了這一部分加載的時間。
上個同事離職了。當時的調研結果我也忘了。只能再開始新一輪的調研,我選擇的是 PWA 方案。(若是說是網速拖慢了加載速度,那麼個人網頁能夠離線訪問不就速度起飛了?)
網上的資料不多。我但願我能夠寫一篇幫助下一個想使用 PWA 方案的人。html

Service Workers

Service worker是一個註冊在指定源和路徑下的事件驅動worker前端

Service worker運行在worker上下文,所以它不能訪問DOM。不一樣於主線程,它運行在其餘線程中,因此不會形成主線程阻塞。它設計爲徹底異步,同步API(如XHR和localStorage)不能在service worker中使用vue

Service workers 本質上充當Web應用程序(服務端)瀏覽器(客戶端)之間的代理服務器
能夠提供有效有效的離線體驗,攔截網絡請求。還能夠推送通知。webpack

Service Workers 須要注意的地方

  1. 須要支持 HTTPS 訪問你的頁面。出於安全緣由,Service Workers 要求必須在 HTTPS 下才能運行。(其實好多API都須要HTTPS的支持)
  2. 資源路徑爲根目錄的絕對路徑。最大做用域 (scope),爲資源路徑。
    https://www.lilnong.top/static/js/sw-20190621.js的最大做用路徑爲/static/js/
  3. 爲了便於本地開發,localhost 也被瀏覽器認爲是安全源。
  4. 在已經支持 serivce workers 的瀏覽器的版本中,不少特性沒有默認開啓。若是你發現示例代碼在當前版本的瀏覽器中怎麼樣都沒法正常運行,你可能須要開啓一下瀏覽器的相關配置:
    Firefox Nightly: 訪問 about:config 並設置 dom.serviceWorkers.enabled 的值爲 true; 重啓瀏覽器;
    Chrome Canary: 訪問 chrome://flags 並開啓 experimental-web-platform-features; 重啓瀏覽器 (注意:有些特性在Chrome中沒有默認開放支持);
    Opera: 訪問 opera://flags 並開啓 ServiceWorker 的支持; 重啓瀏覽器。

service worker 聲明週期

  1. 下載web

    1. 首次訪問service worker控制的網站或頁面時,service worker會馬上被下載。
    2. 至少每24小時它會被下載一次。
  2. 安裝chrome

    1. 首次下載會嘗試安裝,
    2. 下載的文件是新的,嘗試進行安裝
  3. 激活vue-cli

    1. 安裝成功後它會被激活
    2. 若是現有service worker已啓用,新版本會在後檯安裝,但不會被激活,這個時序稱爲worker in waiting
    3. 直到全部已加載的頁面再也不使用舊的service worker纔會激活新的service worker。新的service worker會被激活(成爲active worker)。

咱們頁面引入sw.js內容爲a。當咱們修改成b
這時候ab都是已經安裝完畢的,可是a是當前正在用的。b須要等沒有頁面在用a,纔會進入激活狀態。
clipboard.pngsegmentfault

Cache

Cache 爲緩存的 Request/Response 對象對提供存儲機制。
當前咱們做爲 ServiceWorker 生命週期的一部分。儘管它被定義在 service worker 的標準中, 可是它沒必要必定要配合 service worker 使用。也暴露在 window 做用域下的。api

  1. Cache.add(request)
    request 是一個字符串類型的 URL。如cache.add('https://www.lilnong.top/static/css/normalize-8.0.0.css')
    功能上等於調用 fetch(), 而後使用 Cache.put()response 添加到 cache 中。
  2. Cache.addAll(requests)
    功能同上,只不過入參爲字符串數組
  3. Cache.match(request, options)
    返回一個 Promise 對象,resolve 的結果是跟 Cache 對象匹配已經緩存的請求。
    requres 同上,是要匹配的 URL
    options 以下

    1. ignoreSearch: 設置是否忽略url中的query。該選項默認爲 false
    2. ignoreMethod: true匹配時就不會驗證 Request 對象的 http 方法 (一般只容許是 GETHEAD 。) 該參數默認值爲 false。
    3. ignoreVary: 爲 true 時匹配不進行 VARY 部分的匹配。例如,若是一個URL匹配,此時不管Response對象是否包含VARY頭部,都會認爲是成功匹配。該參數默認爲 false。
    4. cacheName: 一個 DOMString ,表明一個具體的要被搜索的緩存。注意該選項被 Cache.match()方法忽略。
  4. Cache.matchAll(request, options)
    同上,返回一個Promise 對象,resolve的結果是跟Cache對象匹配的全部請求組成的數組
  5. Cache.put(request, response)
    人爲的,爲一個URL設置response
  6. Cache.delete(request, options)
    搜索條目。若是找到,則刪除該Cache 條目,而且返回一個resolvetruePromise對象;若是未找到,則返回一個resolvefalsePromise對象。
  7. Cache.keys(request, options)
    返回一個Promise對象,resolve的結果是Cache對象key(request 對象)組成的數組。

ServiceWorker 的使用

  1. serviceWorkerContainer.register() 來註冊
  2. 註冊成功的話,會開啓另外一個線程來作這件事。與咱們的網頁是互不相干的。
  3. service worker 如今能夠接收事件。
  4. service worker 控制的頁面打開後會嘗試去安裝 service worker
  5. 最早發送給 service worker 的事件是安裝事件(在這個事件裏能夠開始進行填充 IndexDB和緩存站點資源),讓全部資源可離線訪問。
  6. oninstall 事件的處理程序執行完畢後,能夠認爲 service worker 安裝完成了。
  7. service worker 安裝完成後,會接收到一個激活事件 onactivate 主要用途是清理先前版本的 service worker 腳本中使用的資源。
  8. Service Worker 如今能夠控制頁面了,但僅是在 register() 成功後的打開的頁面。

ServiceWorker 的註冊

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);
  });
}

微信公衆號

clipboard.png

總結

測試路徑
https://www.lilnong.top/stati...

  1. https
  2. SW 經過fetch來實現代理瀏覽器請求。
  3. SW 註冊以後會嘗試安裝。可是激活須要等下次(沒有再用的資源了)
  4. SW 要注意他限制的域
  5. importScripts('https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js'); 是一個封裝包
  6. vue-cli也有一些webpack支持的工具

    1. @vue/pwa
    2. @vue/cli-plugin-pwa
  7. 參數中的request能夠是

    1. url 好比"https://www.lilnong.top/static/project/pwa-20190625/index.5.html"
    2. 也能夠是Request對象。

      1. 能夠直接用於保存(put),查找(match),添加(add)
      2. 能夠用於fetch

資料

  1. Service_Worker_API --mdn
  2. Service Workers --mdn
  3. cache --mdn
  4. AppCache --mdn
    這個內容我以爲不用再關心了 <html manifest="example.appcache">
  5. 前端每週清單半年盤點之 PWA 篇 ---王下邀月熊_Chevalier
  6. 傻傻分不清的Manifest
  7. PWA之 workbox 學習
  8. 初探PWA
相關文章
相關標籤/搜索