去年apple在iOS11.3的正式更新中,新增了對service worker的支援。新的桌面版Safari會預設開啟Service Worker。這意味著我們可以通過Safari將支援PWA的站點像原生app一樣新增到桌面,並且支援在離線狀態下訪問。至此,Microsoft, Chrome, Apple這些瀏覽器大廠都已全部支援了PWA。本文將為大家介紹PWA的特點、技術核心、建立方法、在專案中的應用和除錯技巧。
什麼是PWA
PWA(progressing web app),漸進式網頁應用程式,是google在2016年GoogleI/O大會上提出的下一代web應用模型,並在隨後的日子裡迅速發展。PWA的目的在於增強web體驗。從功能上來講,PWA首先是一個web應用,通過manifest.json配置檔案以及Service Worker來獲得web載入速度提升,支援離線工作,可被新增主螢幕,全屏執行等特性。這些特性使得web應用(尤其是移動裝置)體驗漸進式接近原生app。
PWA的特點
在我們思考PWA會為我們帶來哪些提升的時候,google已經為我們總結出了PWA的相關特性(可參考:https://developers.google.com/web/progressive-web-apps/)。
PWA會為web應用帶來如下的特點:
Reliable - Load instantly and never show the downasaur, even in uncertainnetwork conditions(可靠的,即使在網路不穩定的條件下,也能夠立即載入並且永遠不會顯示網路癱瘓的頁面)
Fast - Respondquickly to user interactions with silky smooth animations and no jankyscrolling.(迅速的,藉助於流暢的動畫和無卡頓滾動實現快速響應使用者的互動)
Engaging- Feel like a natural app on the device, with an immersive user experience.(迷人的,PWA有著近乎原生app般的使用者體驗)
而在google更具體的定義下,PWA至少應具有這些特性:
響應式:所有硬體裝置如手機,pc都能夠完美適配
離線應用:支援沒有網路的情況下也可以開啟網頁
app化:體驗近似app
常更新:經常處於最新的狀態
安全:僅服務於https協議確保傳輸內容不會被篡改
可被發現:允許被搜尋引擎識別
推送:在沒有開啟app的情況下可以獲取到推送資訊
可安裝:能夠像app一樣被新增到桌面
可跳轉:只需一個連結即可訪問到你的web app
PWA的技術核心
想讓自己的web app升級成為PWA,繞不開PWA三個關鍵的技術:
Service Worker
Manifest
Push Notification
下面我會逐一為大家介紹三者的概念
1
ServiceWorker
Service worker算是PWA中的最核心內容了。相比於瀏覽器預設提供的workers, service worker是一種特別的事件驅動的worker,特別之處在於它的生命週期與當前頁面無關,當前頁面未關閉也可以退出,當前頁面未開啟時也可以啟動。也就是,service worker提供了web應用通常不具有的離線能力。在網路不穩定的情況下,可以操作cache獲取資料,並保持頁面在離線狀態下也能正常顯示。(達觀資料 施列宇)
你可能會問AppCache也具有同樣的離線能力,為什麼我們不能使用AppCache呢?實際上AppCache這項技術本身存在更新,儲存大小,路徑問題。在多頁面應用方便,AppCache還存在著明顯的缺陷。而Service Worker可以很好的規避這些問題。
Service Worker的啟用條件是1.必須是https協議或者localhost環境下,2..瀏覽器支援。有了這兩個先決條件,我們就可以使用Service Worker進行PWA開發了。
Service Worker相容性目前進展
生命週期是Service Worker中比較複雜的一部分了,如果不能瞭解它的整個週期,在使用過程中,你可能會有一種失控的感覺。
Service Worker的生命週期包含六種狀態:parsed, installing, installed. activating, activated, redundant。狀態之前的轉換過程可以用一張圖來表達。
Service Worker的生命週期
Parsed(解析成功): 頁面註冊Service Worker時,瀏覽器解析指令碼並獲取入口點。解析成功,就可以訪問serviceworker物件了。
Installing(正在安裝):Service Worker在解析完成後,瀏覽器會進行安裝。如果安裝失敗會直接進入到redundant(廢棄)狀態。(達觀資料 施列宇)
Installed/Waiting(安裝成功/等待狀態): 如果ServiceWorker成功安裝,Service Worker會處於等待狀態,等待事件響應。
Activating(正在啟用): 處於等待狀態下的Service Worker如果感知到以下幾件事兒,將會進入activating狀態中:1.Service Worker指令碼中self.skipWaiting()方法被呼叫;2.使用者已關閉service worker作用域下的所有頁面;3.頁面超時。Acticating失敗也會使Service Worker進入Rendundant狀態。
Activated(啟用成功): 啟用成功狀態。
Redundant(廢棄): 廢棄狀態,Serivce Worker處於這個狀態就會停止工作,需要開發者去檢查哪一個環節出了問題。
2
Manifest(應用清單)
PWA提供了一個manifest.json清單檔案來向瀏覽器暴露web應用的後設資料,包括名稱,icon的url等。以備瀏覽器使用,比如在新增至主屏或推送通知時暴露給作業系統,從而增強web應用於作業系統的整合能力。
Manifest在PWA中的作用大致有:
將PWA新增至手機螢幕上
在app中全屏啟動,不顯示位址列
控制螢幕橫豎屏
定義PWA啟動畫面
設定應用的啟動方式,是從主螢幕啟動還是從URL啟動
設定新增螢幕上的應用程式的基本屬性,如名稱,圖示
3
Push Notification(訊息推送)
Service worker中提供了訊息推送的功能。訊息推送在原生app或者hybird app中已不鮮見。訊息推送到頁面,意味著頁面預先知道有些事情要發生,並把這些事情做好。比如,提前準備好頁面需要的資源。推送的伺服器,chromium預設使用的是GCM/FCM,目前由於某些原因還無法在國內進行訪問,國內暫時也沒有瀏覽器廠商支援標準的推送服務。
建立一個簡單的PWA
在使用Service之前,需要先判斷宿主物件navigator中是否含有servicerWorker物件。如果存在,則可以通過serviceWorker物件的register方法進行註冊。
註冊Service Worker
註冊過程中,瀏覽器會解析serviceWorker註冊檔案,在此期間出現任何錯誤,service Worker都會進入Redundant狀態。(達觀資料 施列宇)
Service Worker成功執行,install事件就會被啟用,install完成後,service worker進入就緒狀態,可以進行使用了。
install事件預處理安裝邏輯,使用skipWaiting方法讓service worker直接進入activating狀態
service worker物件監聽fetch對接,在此覺得是否需要使用service worker快取檔案亦或是原地址內容。
使用caches.match方法判斷當前request是否為已快取內容
除此之外,我們也需要及時將過期的靜態資源清除掉,當web更新,某些檔案新增了新的版本號,可以通過activate事件回撥,清除掉過期資源。然後使用clients.claim方法取得頁面控制權,這樣新頁面開啟則會使用新的service worker,舊的service worker物件則會進入redundant狀態。
使用activate事件處理過期資源
這樣一個支援PWA的web app已經搭建起來了,重新整理頁面後可以從chrome network中看到幾個快取的靜態資源來源是from ServiceWorker。
從network中看出部分資源是從service worker載入而來的
在angular專案中新增PWA支援
達觀資料使用了Angular作為前端技術棧,我們前端技術團隊在研究pwa支援的同時也考慮了前端專案在angular專案中的相容性。
Angular在6.0版本加入了PWA的支援,想要支援PWA特性需要先將angular,angular-cli升級到6+.
使用ng add @angular/pwa新增PWA特性支援。新增後會檢測到angular.json,ngsw.json,manifest.json等多個檔案被編輯或被建立。其中ngsw.json是angular的PWA特性的配置檔案。(達觀資料 施列宇)
使用ng build –prod –build-optimizer 命令將程式碼打包,將程式碼部署後會看到靜態資源都來源於serviceWorker,也就證明PWA新增成功了。
開發者通過F12開啟除錯視窗,選擇application,下方會有service workers相應的視窗。這裡可以看到當前域下有哪些serviceworker物件,可以觀察到他們當前的狀態,service worker物件檔案詳情等資訊。也可以通過offline勾選項切換無網路狀態下頁面的反應,update on reload強制每次重新整理都重置service worker進行install; Bypass for network切換不支援service worker視窗下的頁面呈現狀態。可以說都是很棒的除錯功能。(達觀資料 施列宇)
chrome service worker除錯視窗
大家也可以在chrome://serviceworker-internals中瞭解瀏覽器中所有的service worker狀態。
關於作者
施列宇:達觀資料前端技術專家,負責達觀資料畢昇系統,倉頡系統等專案的研發,對資料探勘在前端產品中落地,前端資料視覺化,標準化工程化有著多年的研究。