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