1. 程式人生 > 其它 >輕鬆理解什麼是漸進式web應用

輕鬆理解什麼是漸進式web應用

PWA 是什麼?

PWA 的全稱是 Progressive Web App,漸進式web應用。一個為響應式設計的“保護傘”式的術語,是 Google 在2015年提出,是在移動端利用提供的標準化框架,在網頁應用中實現和原生應用相近的使用者體驗。獨立連線性、新穎、安全、可探索、可重定製、可安裝性、可連結的應用/web站點,並帶有原生應用般的互動效能。

PWA 的優勢

  • 訊息推送。使用者只要允許,即使網頁關閉後仍然可以在系統通知欄收到推送訊息。
  • 後臺載入。往常的網頁應用只要關閉了網頁他的生命就結束了,現在引入了一個 Service Worker 的概念,即使網頁關閉,PWA 仍然可以在後臺執行獲取資料更新(當然有限制)。離線使用。PWA 開啟後會快取一些內容,之後再次訪問即使沒有網路也可以瀏覽之前的頁面(如同IE時代的離線瀏覽)。
  • 原生應用介面。在某些情況下 PWA 應用可以隱藏瀏覽器本身的所有視覺成分,光從UI和UX上看,很容易認為這就是一個原生介面,如下圖其實都是PWA而不是原生應用。
  • 桌面圖示。PWA只要配上一個圖示,再放快捷方式在桌面上,就真的和原生系統無異了,開啟的速度也很快。另一方面,和原生應用比,PWA 又不需要使用者安裝,只需要瀏覽器支援 PWA 就可以了。

PWA 和 Service Worker 關係?

Service Worker 是一個執行在瀏覽器後臺程序裡的js,基於它可以實現訊息推送,靜默更新以及攔截和處理網路請求,包括可程式設計的響應快取管理,是 PWA 的核心。ssl證書申請

工作原理

Service worker 是一個完全獨立於 Web 頁面的 js 指令碼,有他自己的生命週期。

每個 service worker 會對應一個快取池,每個快取池有多個快取倉庫。

首先講講它的宣告週期:

若網站對應的 cacheName 沒有 install,則首先觸發 install事件。
若install失敗,則退出等待下次訪問再啟動;否則觸發activate事件。
在activate中,判斷當前頁面是否在上文宣告的 filesToCache 列表中,如果是則接管網頁的顯示。

接管網頁以後,如果當前記憶體不足,會被殺死;否則等待處理fetch和message事件。這兩個事件一個是當網路請求時,或者其他網頁發出了訊息時。

從使用開始準備工作

首先站點必須支援https。
其次,技術人員至少得懂一點 js開發。
最後,有一個 52 或以上的版本的 Chrome 用作除錯。

註冊 Service Worker

首先,在網站根目錄下建立一個 service-worker.js 檔案(檔名自定)。
這個 service-worker.js 檔案必須放在跟目錄,因為 service workers 的作用範圍是根據其在目錄結構中的位置決定的。

後需要檢查瀏覽器是否支援 service workers,如果支援,就註冊 service worker,將下面程式碼新增至網頁要載入的js中。

if(“serviceWorker” in navigator) {      //註冊上一步建立的js檔案    navigator.serviceWorker          .register(“/service-worker.js”)          .then(function() { console.log(“Service Worker Registered”); });  }載入快取

當用戶訪問一個註冊了 service worker 的頁面時,會觸發一個叫install事件,所以我們首先對這個事件監聽。

var cacheName = “oslab-kymjs-blog”;var filesToCache = [];self.addEventListener(“install”, function(e) {  console.log(“[ServiceWorker] Install”);  e.waitUntil(    caches.open(cacheName).then(function(cache) {      console.log(“[ServiceWorker] Caching app shell”);      return cache.addAll(filesToCache);    })  );});

當監聽到install事件以後,去快取池開啟名為 oslab-kymjs-blog 的快取倉庫。

每個 service worker 會對應一個快取池,每個快取池有多個快取倉庫。

只要快取被開啟,就呼叫 cache.addAll() 並傳入一個 url 列表,然後載入這些資源並將響應新增至快取。

有個注意事項要知道 cache.addAll() 方法中,如果某個檔案下載失敗了,那麼整個快取就會失敗,service worker 的install事件也將會失敗。而如果install失敗了,那麼接下來 service worker 就完全不會工作了。 所以一定要注意,檔案列表一定不要太長了,越長造成失敗的可能性就越高,每個要快取的頁面越大失敗的可能性也越高。

除錯

用 Chrome Developer Tools 除錯 Service Worker 非常方便。

首先 run 起你本地的 server(我部落格是 jekyll 生成的,所以直接用了 jekyll 服務),然後 Chrome 右上角三個點,More Tools,Developer Tools。(mac快捷鍵 cmd+opt+i)

首次執行應該顯示空的,看不到東西,重新整理一下就可以了。但如果重新整理後還是看不到,這意味著當前開啟的頁面沒有已經被註冊的 Service Worker,檢查一下 註冊 步驟的js是否被載入了吧。

重新整理前 注意勾選【update on reload】不然每次重新整理都會起一個新的service worker,然後由於是序列執行,會等待前一個執行完,不然得手動點【skipWaiting】。

然後如果勾選了【update on reload】,可能會看到這個警告,無所謂,忽略它就好了。

刪除無用快取

當 service worker 開始啟動時,就會觸發 activate 事件。 所以我們監聽 activate 在這裡更新快取。

self.addEventListener(“activate”, function(e) {    console.log(“[ServiceWorker] Activate”);    e.waitUntil(      caches.keys().then(function(keyList) {        return Promise.all(keyList.map(function(key) {          console.log(“[ServiceWorker] Removing old cache”, key);          if (key !== cacheName) {            return caches.delete(key);          }        }));      })    );  });

以上程式碼表示,如果執行到了 activate,首先判斷現在快取池中的快取倉庫 cacheName 是否和宣告的 cacheName 同一個,如果不是,就清空快取池中的無用快取(install中下載新的快取,activate 中刪除舊快取)。所以建議大家在 cacheName 的末尾加一個版本號,這樣可以始終讓service worker 載入最新的快取。