PWA的探索與應用
> 本文由雲 + 社群發表
PWA(Progressive Web App)起源背景
傳統的 Web 網頁存在以下幾個問題:
- 進入一個頁面必須要記住它的 url 或者加入書籤,入口不便捷;
- 沒網路就沒響應,不具備離線能力;
- 不像 APP 一樣能進行訊息推送。
Native app:
- 開發成本高
- 軟體上線需要稽核
- 即使使用頻率不高,想使用一個 app 必須先下載安裝
PWA 概念的提出
2016 年 Google I/O 大會上提出一個 Next Web Generation 的概念。PWA 是在傳統 Web 應用的基礎上,結合 Manifest 和 service worker,完善 Web 應用的一些能力,比如:
- 新增至主螢幕,點選主螢幕圖示可以實現啟動動畫以及隱藏位址列
- 實現離線快取功能,即使使用者手機沒有網路,依然可以使用一些離線功能
- 訊息推送
PWA 技術點
Web App Manifest
Web App Manifest 技術實現了將 PWA 網頁應用 新增至桌面的功能,但該項技術目前仍處於實驗性階段,各瀏覽器支援度不高
image.png
PWA 站點部署的 manifest.json 檔案滿足以下條件時會自動顯示橫幅:
- short\\_name (主螢幕顯示)
- name (安裝橫幅顯示)
- icons (必須包含一個 mime 型別為 image/png 的圖示宣告)
- start\\_url (應用啟動地址)
- display (必須為 standalone 或 fullscreen)
- 站點註冊 Service Worker。
- 站點支援 HTTPS 訪問。
- 同一瀏覽器中站點至少被訪問兩次,間隔至少為 5 分鐘。
Service Worker
PWA 應用的離線體驗、定期的後臺同步以及推送通知等功能的實現依賴於 Service Worker 技術,下圖為目前 SW 技術的支援度。
SW 具有以下特徵:
- 一個獨立的 worker 執行緒,獨立於當前網頁程式,有自己獨立的 worker context。
- 一旦被 install,就永遠存在,除非被手動 unregister
- 用到的時候可以直接喚醒,不用的時候自動睡眠
- 離線內容開發者可控
- 能向客戶端推送訊息
- 不能直接操作 DOM
- 必須在 HTTPS 環境下才能工作
- 非同步實現,內部大都是通過 Promise 實現
Service Worker 生命週期
- installing:這個狀態發生在 SW 註冊之後開始安裝,install 事件回撥中執行 skipWaiting() 方法表示強制當前處在 waiting 狀態的 Service Worker 進入 activate 狀態。
- installed:SW 已經完成了安裝,等待其他的 SW 執行緒被關閉。
- activating:在這個狀態下清除其他的 worker 以及關聯快取的舊快取資源,等待新的 SW 執行緒被啟用。在 activate 事件回撥中執行 self.clients.claim() 方法表示取得頁面的控制權, 這樣之後開啟頁面都會使用版本更新的快取。舊的 Service Worker 指令碼不再控制著頁面,之後會被停止。
- activated:在這個狀態可以處理功能性的事件 fetch (請求)、sync (後臺同步)、push (推送)。
- 廢棄狀態 ( redundant ):這個狀態表示一個 Service Worker 的生命週期結束。
Service Worker 支援的事件
- install:Service Worker 安裝成功後被觸發的事件, 在事件處理函式中可以新增需要快取的檔案
- activate:當 Service Worker 安裝完成後並進入啟用狀態,會觸發 activate 事件。通過監聽 activate 事件你可以做一些預處理,如對舊版本的更新、對無用快取的清理等。
- message:Service Worker 執行於獨立 context 中,無法直接訪問當前頁面主執行緒的 DOM 等資訊,但是通過 postMessage API,可以實現他們之間的訊息傳遞,這樣主執行緒就可以接受 Service Worker 的指令操作 DOM。
- fetch :當瀏覽器在當前指定的 scope 下發起請求時,會觸發 fetch 事件,並得到傳有 response 引數的回撥函式。fetch 事件特別重要,因為它能夠定義你的快取策略。也就是說,你可以決定何時使用快取資料,何時使用網路請求來的資料。
- push:push 事件是為推送準備的。通過 PUSH API,當訂閱了推送服務後,可以使用推送方式喚醒 Service Worker 以響應來自系統訊息傳遞服務的訊息,即使使用者已經關閉了頁面。
- sync:sync 事件由 background sync (後臺同步) 發出。background sync 是 Google 配合 SW 推出的 API,用於為 Service Worker 提供一個可以實現註冊和監聽同步處理的方法。但它還不在 W3C Web API 標準中。在 Chrome 中這也只是一個實驗性功能,需要訪問 chrome://flags/#enable-experimental-web-platform-features ,開啟該功能,然後重啟生效。Sync 事件允許延遲網路任務,直到使用者連線上網路,它實現的功能通常被稱為後臺同步。這對於在離線模式下,確保使用者啟動的任何有網路依賴的任務,最終都將在網路再次可用時達到其預期目的,是非常有用的。
Service Worker 的工作原理
Service Worker 是基於註冊、安裝、啟用等步驟
註冊
if ('serviceWorker' in navigator) {
window.addEventListener('load', function () {
navigator.serviceWorker.register('/jslearning/sw.js') // 預設作用域為jslearning下,也可以通過設定scope引數進行設定
.then(function (registration) {
// 註冊成功
console.log('ServiceWorker registration successful with scope: ', registration.scope);
})
.catch(function (err) {
// 註冊失敗:(
console.log('ServiceWorker registration failed: ', err);
});
});
}
安裝
this.addEventListener('install', function(event) {
console.log('V1 installing…');
//需要快取的重要的高優先順序資源
var vipUrlsToPrefetch = [
'./index.html'
];
//次重要的資源
var urlsToPrefetch = [
'./icon.png'
];
event.waitUntil(
caches.open(OFFLINE_CACHE_NAME).then(function(cache) {
//urlsToPrefetch非重要資源,即使有資源載入失敗也不影響Service Worker安裝
cache.addAll(urlsToPrefetch);
//vipUrlsToPrefetch中資源全部請求成功,Service Worker安裝事件才順利完成,可以進入啟用事件
return cache.addAll(vipUrlsToPrefetch);
})
);
});
啟用
//Service Worker啟用事件
this.addEventListener('activate', function(event) {
//在啟用事件中清除非當前版本的快取避免使用者儲存空間急劇膨脹
event.waitUntil(caches.keys().then(function(cacheNames) {
console.log('V1 activate');
return Promise.all(cacheNames.map(function(cacheName) {
if (cacheName !== OFFLINE_CACHE_NAME) {
if(cacheName.indexOf(OFFLINE_CACHE_PREFIX) != -1) {
return caches.delete(cacheName);
}
}
}));
}));
});
Service Worker 更新
- 如果執行緒的位元組與已有的 SW 執行緒位元組不同,瀏覽器則考慮更新 SW 執行緒。
- 更新的 SW 執行緒與現有 SW 執行緒一起啟動,並獲取自己的 install 事件。
- 如果新工作 SW 執行緒出現不正常狀態程式碼(例如,404)、解析失敗,在執行中引發錯誤或在安裝期間被拒,則系統將捨棄新工作執行緒,但當前工作執行緒仍處於活動狀態。
- 安裝成功後,更新的工作執行緒將 wait,直到現有工作執行緒控制 0 個客戶端。
- self.skipWaiting() 可跳過等待情況,這意味著 sw 執行緒在安裝完後立即啟用。
Service Worker 快取策略
Service Worker 快取策略大部分在 fetch 與 install 時間中定義,對於某些固定不變的靜態資源,可以在 Service Worker 初次安裝的 install 事件中將其快取,但資源過大或者網路不佳都會造成資源並未全部下載成功而導致 Service Worker 安裝被中斷安裝失敗。SW 主要有以下幾類快取策略:
- 不影響安裝的資源預快取
- 漸進式快取
- 僅使用快取、僅使用網路
- 快取優先 、網路優先
// 漸進式快取
var addToCache = function(req) {
return fetch(req.clone()).then(function(resp) {
var cacheResp = resp.clone();
if (!resp.ok) {
return resp;
}
caches.open(OFFLINE_CACHE_NAME).then(function(cache) {
cache.put(req.clone(), cacheResp);
});
return resp;
});
};
this.addEventListener('fetch', function(event) {
event.respondWith(
caches.open(OFFLINE_CACHE_NAME).then(function(cache) {
return cache.match(event.request);
}).then(function(response) {
if (response) {
return response;
} else {
return addToCache(event.request);
}
})
);
});
PWA 應用可以通過開發者工具中的 Application 進行檢視除錯,如下圖所示:
PWA 優缺點總結
優點
- 可以將 app 的快捷方式放置到桌面上,全屏執行,與原生 app 無異
- 能夠在網路差和斷網條件下
- 推送訊息的能力
- 快速響應使用者指令
缺點
- 支援率不高
- Chrome 在安卓移動端上的佔有率很低
- 依賴的 GCM 服務在國內無法使用
- 微信小程式的競爭
PWA 應用
- Lavas 是一套基於 Vue 的 PWA 解決方案,能夠幫助開發者快速搭建 PWA 應用
- 新浪微博
- 餓了麼
- Offline Wikipedia
- Spotlight
- ...
參考文獻
- https://developers.google.com/web/progressive-web-apps/
- https://developer.mozilla.org/en-US/docs/Web/Apps/Progressive
- https://lavas.baidu.com/pwa
- https://x5.tencent.com/tbs/guide/serviceworker.html
- https://segmentfault.com/a/1190000012353473#articleHeader0
- https://blog.csdn.net/baidu_browser/article/details/64440238
此文已由作者授權騰訊雲 + 社群在各渠道釋出
獲取更多新鮮技術乾貨,可以關注我們騰訊雲技術社群-雲加社群官方號及知乎機構號
更多原創文章乾貨分享,請關注公眾號
- 加微信實戰群請加微信(註明:實戰群):gocnio
相關文章
- Service Worker 在 PWA 中的應用
- PWA介紹及快速上手搭建一個PWA應用
- PWA 應用和原生應用的一些區別
- PWA入門:手把手教你製作一個PWA應用
- 情感分析技術在美團的探索與應用
- 漸進式Web應用程式(PWA)的深入概述Web
- PWA 應用列表及常用工具
- React 同構應用 PWA 升級指南React
- 《探索Python Requests中的代理應用與實踐》Python
- vivo直播應用技術實踐與探索
- [譯] PWA 會取代原生移動應用嗎?
- 人工智慧在財富領域的應用與探索人工智慧
- 雲資料庫在水利領域的應用與探索資料庫
- 【講壇實錄】知識圖譜的探索與應用
- 前端應該瞭解的PWA前端
- 如何構建可控,可靠,可擴充套件的 PWA 應用套件
- 漸進式Web應用(PWA)入門教程(下)Web
- 深度 | 線下場景的客流數字化探索與應用
- 探索 Elasticsearch 8.X Terms Set 檢索的應用與原理Elasticsearch
- 互動式推薦在外賣場景的探索與應用
- 關於 Angular PWA 應用中的 ngsw.json 檔案AngularJSON
- Google I/O 2018 : 應用於 PC 端的 PWAGo
- Dapr專案應用探索
- 【PWA學習與實踐】(6) 在Chrome中除錯你的PWAChrome除錯
- 阿里巴巴的雲原生應用開源探索與實踐阿里
- 探索自然語言處理:語言模型的發展與應用自然語言處理模型
- 關於 iOS 上的 PWA 應用,你需要知道些什麼?iOS
- 釘釘協同引擎與應用場景技術探索
- 探索美國住宅IP的優勢與應用:跨越國界的網路自由
- 使用Service Worker做一個PWA離線網頁應用網頁
- ChatGPT在工業領域的研究與應用探索-資料與工況認知ChatGPT
- Zoho推出《中國ToB超級應用探索與實踐白皮書》
- 單頁應用的資料流方案探索
- 分析:移動應用廣告的未來探索
- 前端每週清單第 42 期:V8 的執行流與優化, Pinterest 的 PWA 實踐, Rust 與 WebAssembly 應用前端優化RESTRustWeb
- 探索CSS奧秘:深入解析版式佈局與字型樣式的應用技巧CSS
- 【PWA學習與實踐】(9)生產環境中PWA實踐的問題與解決方案
- pwa+webpack,初探與踩坑Web