摘要:對(duì)來(lái)說(shuō)主要兩個(gè)事件。是當(dāng)前的變量,執(zhí)行該方法表示強(qiáng)制當(dāng)前處在狀態(tài)的進(jìn)入狀態(tài)。頁(yè)面關(guān)閉之后,老的會(huì)被干掉,新的接管頁(yè)面新的生效后會(huì)觸發(fā)事件。
一、傳統(tǒng)web 應(yīng)用
當(dāng)前web應(yīng)用在移動(dòng)時(shí)代并沒(méi)有達(dá)到其在桌面設(shè)備上流行的程度,下面有張圖來(lái)對(duì)比與原生應(yīng)用之間的差別。
究其原因,無(wú)外乎下面不可避免的幾點(diǎn):
移動(dòng)設(shè)備網(wǎng)絡(luò)限制-不可忽略的加載時(shí)間
web應(yīng)用依賴于瀏覽器作為入口
體驗(yàn)與原生的差距
假如能解決以上的幾點(diǎn),對(duì)web app 來(lái)說(shuō)會(huì)有多大的提升可以想象。
二、PWA是什么PWA 全稱Progressive Web Apps(漸進(jìn)式Web應(yīng)用程序),旨在使用現(xiàn)有的web技術(shù)提供用戶更優(yōu)的使用體驗(yàn)。
基本要求
可靠(Reliable)
即使在不穩(wěn)定的網(wǎng)絡(luò)環(huán)境下,也能瞬間加載并展現(xiàn)
快速響應(yīng)(Fast)
快速響應(yīng),并且有平滑的動(dòng)畫響應(yīng)用戶的操作
粘性(Engaging)
像設(shè)備上的原生應(yīng)用,具有沉浸式的用戶體驗(yàn),用戶可以添加到桌面
PWA 本身強(qiáng)調(diào)漸進(jìn)式,并不要求一次性達(dá)到安全、性能和體驗(yàn)上的所有要求,開發(fā)者可以通過(guò) PWA Checklist 查看現(xiàn)有的特征。
除以上的基準(zhǔn)要求外,還應(yīng)該包括以下特性:
漸進(jìn)式 - 適用于所有瀏覽器,因?yàn)樗且詽u進(jìn)式增強(qiáng)作為宗旨開發(fā)的
連接無(wú)關(guān)性 - 能夠借助 Service Worker 在離線或者網(wǎng)絡(luò)較差的情況下正常訪問(wèn)
類似應(yīng)用 - 由于是在 App Shell 模型基礎(chǔ)上開發(fā),因?yàn)閼?yīng)具有 Native App 的交互和導(dǎo)航,給用戶 Native App 的體驗(yàn)
持續(xù)更新 - 始終是最新的,無(wú)版本和更新問(wèn)題
安全 - 通過(guò) HTTPS 協(xié)議提供服務(wù),防止窺探和確保內(nèi)容不被篡改
可索引 - 應(yīng)用清單文件和 Service Worker 可以讓搜索引擎索引到,從而將其識(shí)別為『應(yīng)用』
粘性 - 通過(guò)推送離線通知等,可以讓用戶回流
可安裝 - 用戶可以添加常用的 webapp 到桌面,免去去應(yīng)用商店下載的麻煩
可鏈接 - 通過(guò)鏈接即可分享內(nèi)容,無(wú)需下載安裝
看起來(lái)有點(diǎn)眼花繚亂,這又是一個(gè)新的飛起的輪子嗎?這里重申一下,PWA背后不是一種新的技術(shù),而是集合當(dāng)前多種web技術(shù)的一種集合。分別利用各自的功能來(lái)完成漸進(jìn)式的整體需求。下面就沿著前面提出的問(wèn)題分別了解一下相關(guān)技術(shù)
三、技術(shù)組成由以下幾種技術(shù)構(gòu)成:
App Manifest
Service Worker
Notifications API
Push API
其中Service Worker是PWA技術(shù)的關(guān)鍵,它們可以讓app滿足上面的三基準(zhǔn)。其他技術(shù)則是錦上添花,讓app更加的強(qiáng)大。
3.1 service worker背景 離線緩存背景針對(duì)網(wǎng)頁(yè)的體驗(yàn),從前到后都做了很多努力,極力去降低響應(yīng)時(shí)間,這里就不表述多樣的技術(shù)手段。
另一個(gè)方向的就是緩存,減少與服務(wù)器非必要的交互,不過(guò)對(duì)于離線的情況下瀏覽器緩存就無(wú)力了,
這樣離線緩存的需求就出現(xiàn)了。
web應(yīng)用在離線緩存發(fā)展的過(guò)程中也不是一簇而就的,經(jīng)歷了逐漸完善的過(guò)程。
初期的解決方案是AppCache
然而,事實(shí)證明這是一個(gè)失敗的嘗試,缺陷太多,已經(jīng)被廢棄了。具體可以查看Application Cache is a douchebag
但是方向還是正確的,那就繼續(xù)孜孜不倦的探索。
持久化先放一邊,來(lái)談?wù)劻硪粋€(gè)問(wèn)題
基于瀏覽器中的 javaScript 單線程的現(xiàn)實(shí)逐漸不能滿足現(xiàn)代web需求的現(xiàn)狀,例如耗時(shí)的計(jì)算,用戶的交互顯然會(huì)受影響。
為了將這些耗時(shí)操作從主線程中解放出來(lái),早期W3C新增了一個(gè)Web Worker 的 API,可以脫離主線程多帶帶執(zhí)行,并且可以與主線程交互。
不過(guò)Web Worker是臨時(shí)性的依賴于創(chuàng)建頁(yè)面 ,不能滿足我們持久化的需求。
沖著這個(gè)目標(biāo),下面就比較容易解決了,搞個(gè)能持久存在的就行了。
在Web Worker的基礎(chǔ)上,W3C新增了service worker來(lái)滿足我們持久化的需求。
其生命周期與頁(yè)面無(wú)關(guān),關(guān)聯(lián)頁(yè)面未關(guān)閉時(shí),它也可以退出,沒(méi)有關(guān)聯(lián)頁(yè)面時(shí),它也可以啟動(dòng)
功能
Service Worker雖然滿足了離線緩存來(lái),其功能可不僅僅局限于此。 可以提供
豐富的離線體驗(yàn),
周期的后臺(tái)同步,
消息推送通知,
攔截和處理網(wǎng)絡(luò)請(qǐng)求,
管理資源緩存
這些正好也是PWA的目的,所以說(shuō)Service Worker是PWA的關(guān)鍵技術(shù)。
前提條件Service Worker 出于安全性和其實(shí)現(xiàn)原理,在使用的時(shí)候有一定的前提條件。
由于 Service Worker 要求 HTTPS 的環(huán)境
當(dāng)然一般瀏覽器允許調(diào)試 Service Worker 的時(shí)候 host 為 localhost 或者 127.0.0.1
Service Worker 的緩存機(jī)制是依賴 Cache API (略過(guò))
依賴 HTML5 fetch API(略過(guò))
依賴 Promise 實(shí)現(xiàn)
由上可知,不是所有的瀏覽器都支持的,支持情況大概如下:
iOS 內(nèi)的所有的瀏覽器都基于 safari,所以iOS要在11.3以上
IE是放棄支持了,不過(guò)Edge好歹支持了。
Cache是Service Worker衍生出來(lái)的API,配合Service Worker實(shí)現(xiàn)對(duì)資源請(qǐng)求的緩存。
不過(guò)cache并不直接緩存字符串,而是直接緩存資源請(qǐng)求(css、js、html等)。
cache也是key-value形式,一般來(lái)說(shuō)key就是request,value就是response
caches.open(cacheName) 打開一個(gè)cache
caches是global對(duì)象,返回一個(gè)帶有cache返回值的Promise
cache.keys() 遍歷cache中所有鍵,得到value的集合
cache.match(Request|url) 在cache中匹配傳入的request,返回Promise;
cache.matchAll只有第一個(gè)參數(shù)與match不同,需要一個(gè)request的數(shù)組,當(dāng)然返回的結(jié)果也是response的數(shù)組
cache.add(Request|url) 并不是單純的add,因?yàn)閭魅氲氖莚equest或者url,在cache.add內(nèi)部會(huì)自動(dòng)去調(diào)用fetch取回request的請(qǐng)求結(jié)果,然后才是把response存入cache;
cache.addAll類似,通常在sw install的時(shí)候用cache.addAll把所有需要緩存的文件都請(qǐng)求一遍
cache.put(Request, Response) 這個(gè)相當(dāng)于cache.add的第二步,即fetch到response后存入cache
cache.delete(Request|url) 刪除緩存
3.3 注冊(cè)Service Worker注冊(cè)即聲明sw文件的位置,顯然應(yīng)該在主js中引入。大概如下:
//基于promise function registerServiceWorker(){ // 注冊(cè)service worker return navigator.serviceWorker.register("./sw1.js").then(registration => { console.log("注冊(cè)成功"); // 返回 return registration; }) .catch(err => { console.error("注冊(cè)失敗", err); }); } window.onload = function () { //是否支持 if (!("serviceWorker" in navigator)) { return; } registerServiceWorker() }3.4 生命周期
Service worker 有一個(gè)獨(dú)立于web 頁(yè)面的生命周期。
如果在網(wǎng)站上安裝 serice worker ,你需要注冊(cè),注冊(cè)后瀏覽器會(huì)在后臺(tái)安裝 service worker。然后進(jìn)入下面的不同階段。
激活之后,service worker 將控制所有的頁(yè)面,納入它的范圍,不過(guò)第一次在頁(yè)面注冊(cè) service worker 時(shí)不會(huì)控制頁(yè)面,直到它再次加載。
service worker 生效之后,它會(huì)處于下面兩種狀態(tài)之一:
service worker 終止來(lái)節(jié)省內(nèi)存,
頁(yè)面發(fā)起網(wǎng)絡(luò)請(qǐng)求后,它將處理請(qǐng)求獲取和消息事件。
由上圖看知,分為這么幾個(gè)階段:
Installing
發(fā)生在 Service Worker 注冊(cè)之后,表示開始安裝,觸發(fā) install 事件回調(diào)指定一些靜態(tài)資源進(jìn)行離線緩存
Installed
Service Worker 已經(jīng)完成了安裝,并且等待其他的 Service Worker 線程被關(guān)閉。
Activating
在這個(gè)狀態(tài)下沒(méi)有被其他的 Service Worker 控制的客戶端,允許當(dāng)前的 worker 完成安裝
Activated
在這個(gè)狀態(tài)會(huì)處理 activate 事件回調(diào) (提供了更新緩存策略的機(jī)會(huì))。并可以處理功能性的事件 fetch (請(qǐng)求)、sync (后臺(tái)同步)、push (推送)
Redundant
被替換,即被銷毀
了解聲明周期其實(shí)是為了我們?cè)诓煌瑫r(shí)間段去監(jiān)聽事件來(lái)完成相應(yīng)操作。對(duì)PWA來(lái)說(shuō)主要兩個(gè)事件。
install 事件回調(diào):
event.waitUntil():傳入一個(gè) Promise 為參數(shù),等到該 Promise 為 resolve 狀態(tài)為止。
self.skipWaiting():self 是當(dāng)前 context 的 global 變量,執(zhí)行該方法表示強(qiáng)制當(dāng)前處在 waiting 狀態(tài)的 Service Worker 進(jìn)入 activate 狀態(tài)。
activate 回調(diào):
event.waitUntil():傳入一個(gè) Promise 為參數(shù),等到該 Promise 為 resolve 狀態(tài)為止。
self.clients.claim():在 activate 事件回調(diào)中執(zhí)行該方法表示取得頁(yè)面的控制權(quán), 這樣之后打開頁(yè)面都會(huì)使用版本更新的緩存。舊的 Service Worker 腳本不再控制著頁(yè)面,之后會(huì)被停止。
const CURCACHE = "CURCACHE_test_1" const RUNTIME = "runtime"; const CURCACHE_URLS = [ "./", "/asset/sw.jpg", "index.js" ] self.addEventListener("install",e=>{ e.waitUntil( //存儲(chǔ)緩存路徑對(duì)應(yīng)的資源 caches.open(CURCACHE).then(cache=>{ cache.addAll(CURCACHE_URLS) }).then( self.skipWaiting() ) ) }) //代理請(qǐng)求,使用緩存,請(qǐng)求發(fā)送之前 self.addEventListener("fetch", e => { e.respondWith( //緩存是否匹配 caches.match(e.request).then(function(response) { if (response != null) { //命中緩存返回緩存,結(jié)束請(qǐng)求 return response } //未命中緩存,正常請(qǐng)求 return fetch(e.request.url) }) ) });
更新service worker
service worker 更新步驟如下:
更新 service worker 的文件
網(wǎng)頁(yè)打開時(shí)服務(wù)器會(huì)進(jìn)行對(duì)比,保持最新
新的 service worker 啟動(dòng)install
當(dāng)前頁(yè)面生效的依然是老的service worker,新的 service worker 會(huì)進(jìn)入 “waiting” 狀態(tài)。
頁(yè)面關(guān)閉之后,老的 service worker 會(huì)被干掉,新的 servicer worker 接管頁(yè)面
新的 service worker 生效后會(huì)觸發(fā) activate 事件。
const CURCACHE = "precache_test_1" //假設(shè)上個(gè)版本的key為precache_test_2 反正不等于CURCACHE self.addEventListener("activate", e => { e.waitUntil( //遍歷當(dāng)前緩存keys caches.keys().then(cacheNames=>{ return Promise.all( cacheNames.map(function(cacheName) { //是否等于當(dāng)前key,保留自己 if (cacheName !== CURCACHE) { return caches.delete(cacheName); } }) )}).then(() => self.clients.claim()) ) })
這樣一個(gè)簡(jiǎn)單的service worker離線緩存完成了??刂婆_(tái)可以看到,來(lái)源是service worker
關(guān)閉網(wǎng)絡(luò)之后再次訪問(wèn),可以同樣得到上面的結(jié)果,并且sw.js請(qǐng)求未能拿到,但是不影響,舊的文件依然在,這里證明了每次都回去對(duì)比sw文件以確保更新
到這里,離線緩存就實(shí)現(xiàn)了。
允許將站點(diǎn)添加至主屏幕,是 PWA 提供的一項(xiàng)重要功能。這樣就不用再依賴于瀏覽器作為平臺(tái),符合移動(dòng)端的用戶習(xí)慣。
manifest.json需要 manifest.json 文件去配置應(yīng)用的圖標(biāo)、名稱等基本信息如下:
{ //被提示安裝應(yīng)用時(shí)出現(xiàn)的文本 "name": "PQJ-PWA", //添加至主屏幕后的文本 "short_name":"PQJ", "description": "測(cè)試demo", //添加之后,啟動(dòng)地址 "start_url": "/index.html", //圖標(biāo)信息 "icons": { "128": "/asset/sw.jpg" }, "developer": { "name": "pqj", "url": "" }, "display": "standalone", "background_color": "#287fc5", "theme_color": "#fff", "permissions": { "desktop-notification": { "description": "Needed for creating system notifications." } } }
然后以如下方式在html中引入
這樣完成之后,移動(dòng)端安卓使用chrome(親測(cè)),首次訪問(wèn)時(shí)會(huì)提示是否允許安裝到主屏幕,以應(yīng)用icon的形式出現(xiàn)。
圖片和文字即由配置決定。
消息通知也是使用service worker的通知功能進(jìn)行的,允許服務(wù)器想用戶發(fā)生通知,而非用戶主動(dòng)請(qǐng)求才去響應(yīng)某些行為。
正常的通知邏輯需要服務(wù)器來(lái)參與實(shí)現(xiàn),這次展示只實(shí)現(xiàn)功能。
首先申請(qǐng)通知權(quán)限
注冊(cè)service worker
處理邏輯,發(fā)送通知
function getPermission(){ return new Promise((resolve, reject) => { //權(quán)限獲取 const permissionPromise = Notification.requestPermission(result => { resolve(result); }); }).then(result => { //判斷條件 if (result === "granted") { execute(); } else { console.log("no permission"); } }); }
發(fā)送通知
function execute() { // 允許之后執(zhí)行 registerServiceWorker().then(registration => { // 通知 registration.showNotification("Hello World!"); }); }結(jié)束語(yǔ) 參考文檔
https://lavas.baidu.com/doc
https://developer.mozilla.org/zh-CN/Apps/Progressive
至此,本文介紹就結(jié)束了,更多請(qǐng)參考實(shí)例雖然PWA目前來(lái)看,面對(duì)的限制還很多,但是也可以看出web組織在更好的提升web應(yīng)用方向上做的努力。正如一直提到的那句話,未來(lái)可期。
目前國(guó)內(nèi)百度這方面做的比較成熟,新浪微博已經(jīng)有了pwa 測(cè)試版。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/94943.html
摘要:前端每周清單專注前端領(lǐng)域內(nèi)容,以對(duì)外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點(diǎn)分為新聞熱點(diǎn)開發(fā)教程工程實(shí)踐深度閱讀開源項(xiàng)目巔峰人生等欄目。 前端每周清單專注前端領(lǐng)域內(nèi)容,以對(duì)外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點(diǎn);分為新聞熱點(diǎn)、開發(fā)教程、工程實(shí)踐、深度閱讀、開源項(xiàng)目、巔峰人生等欄目。歡迎關(guān)注【前端之巔】微信公眾號(hào)(ID:frontshow),及時(shí)獲取前端每周清單;本文則是對(duì)于...
摘要:同時(shí),前端技術(shù)也慢慢的趨于穩(wěn)固,自成一套體系。從月份開始,微信正式將公測(cè)了小程序?;谛〕绦虻拈_發(fā),也將成為國(guó)內(nèi)的前端的一大重點(diǎn)。 前言 臨近2017的尾聲,總是希望來(lái)盤點(diǎn)一下這一年中前端的發(fā)展。到目前為止,前端的井噴期也快臨近尾聲了。并不像幾年前一樣,總是會(huì)有層出不窮的新東西迸發(fā)出來(lái)。同時(shí),前端技術(shù)也慢慢的趨于穩(wěn)固,自成一套體系。如果你喜歡我的文章,歡迎評(píng)論,歡迎Star~。歡迎關(guān)注...
摘要:同時(shí),前端技術(shù)也慢慢的趨于穩(wěn)固,自成一套體系。從月份開始,微信正式將公測(cè)了小程序?;谛〕绦虻拈_發(fā),也將成為國(guó)內(nèi)的前端的一大重點(diǎn)。 前言 臨近2017的尾聲,總是希望來(lái)盤點(diǎn)一下這一年中前端的發(fā)展。到目前為止,前端的井噴期也快臨近尾聲了。并不像幾年前一樣,總是會(huì)有層出不窮的新東西迸發(fā)出來(lái)。同時(shí),前端技術(shù)也慢慢的趨于穩(wěn)固,自成一套體系。如果你喜歡我的文章,歡迎評(píng)論,歡迎Star~。歡迎關(guān)注...
摘要:葡萄城通過(guò)深厚的技術(shù)積累和豐富的項(xiàng)目開發(fā)經(jīng)驗(yàn),為您的企業(yè)為什么需要漸進(jìn)式應(yīng)用程序做項(xiàng)目開發(fā)總結(jié)了個(gè)理由,希望對(duì)您有所幫助。漸進(jìn)式應(yīng)用程序可縮短項(xiàng)目開發(fā)周期更多時(shí)間更多機(jī)會(huì)。谷歌正在為漸進(jìn)式應(yīng)用程序的信息和使用場(chǎng)景開創(chuàng)先河。 轉(zhuǎn)載請(qǐng)注明出處:葡萄城官網(wǎng),葡萄城為開發(fā)者提供專業(yè)的開發(fā)工具、解決方案和服務(wù),賦能開發(fā)者。 自從漸進(jìn)式Web應(yīng)用程序(PWA)誕生以來(lái),許多公司已開始利用這個(gè)新平...
閱讀 898·2021-10-27 14:19
閱讀 1117·2021-10-15 09:42
閱讀 1540·2021-09-14 18:02
閱讀 748·2019-08-30 13:09
閱讀 2995·2019-08-29 15:08
閱讀 2096·2019-08-28 18:05
閱讀 960·2019-08-26 10:25
閱讀 2790·2019-08-23 16:28