您已發布 PWA:有些使用者是透過瀏覽器使用 PWA,有些人則會在裝置上安裝 PWA。更新應用程式時,請務必採用最佳做法,避免陷入困境。
可更新的部分如下:
- 。
- 裝置已快取資產。
- Service Worker 檔案或其依附元件。
- 資訊清單中繼資料。
以下將說明每個元素的最佳做法。
更新資料
如要更新資料 (例如儲存在 IndexedDB 中的資料),您可以使用 Fetch、WebRTC 或 WebSockets API 等工具。如果您的應用程式支援任何離線功能,請記得一併更新支援這些功能的資料。
在相容的瀏覽器中,您不僅能同步處理資料,還可以選擇在使用者開啟 PWA 時,以及在背景中同步處理資料。這些選項包括:
- 背景同步處理:儲存失敗的要求,並使用 Service Worker 的同步處理功能重試要求。
- 網頁定期背景同步處理:在特定時間定期在背景同步處理資料,讓應用程式即使使用者未開啟應用程式,也能提供更新資料。
- 背景擷取:下載大型檔案 (即使 PWA 已關閉)。
- 網路推送:從伺服器傳送訊息,喚醒 Service Worker 並通知使用者。這類通知通常稱為「推播通知」。這個 API 需要使用者的授權。
這些 API 全都是從 Service Worker 環境執行。這些功能目前僅適用於以 Chromium 為基礎的瀏覽器,以及 Android 和電腦作業系統。當您使用這些 API 時,可以在 Service Worker 執行緒中執行程式碼。例如從伺服器下載資料並更新 IndexedDB 資料
正在更新資產
更新素材資源會包括用來呈現應用程式介面的檔案變更,例如 HTML、CSS、JavaScript 和圖片。例如變更應用程式邏輯、介面中的圖片,或 CSS 樣式表。
更新模式
以下是處理應用程式更新的常見模式,但您隨時可以根據自己的需求自訂程序:
- 完整更新:每次變更,即使只做一個變更,也會觸發取代整個快取內容。這個模式會模仿裝置專屬應用程式處理更新的方式,而且會耗用較多頻寬,需要更多時間。
- 已變更資產更新:快取中只會取代上次更新後曾變更的素材資源。通常會使用 Workbox 等程式庫導入。這包括建立快取檔案清單、檔案的雜湊表示法和時間戳記。透過這項資訊,服務工作處理程序會將這份清單與快取資產進行比較,並決定要更新哪些資產。
- 個別資產會更新:每當資產變更時,系統都會逐一更新資產。放送章節中所述的重新驗證策略過時,就是個別更新素材資源的例子。
更新時間
另一種建議做法是尋找適當時機檢查並套用更新。建議的方法如下:
- 喚醒 Service Worker 的時間。目前沒有可監聽的事件,但瀏覽器在喚醒時,會在 Service Worker 的全域範圍內執行任何程式碼。
- 在 PWA 的主要視窗環境,瀏覽器載入網頁後,為了避免應用程式載入速度變慢。
- 觸發背景事件時,例如 PWA 收到推播通知或背景同步處理啟動時。您可以更新快取,使用者下次開啟應用程式時取得資產的新版本。
最新即時資訊
還能選擇要在應用程式開啟 (即時) 或關閉時套用更新。應用程式關閉方法後,即使應用程式已下載新素材資源,也不會進行任何變更,且會在下次載入時使用新版本。
即時更新是指在快取中更新資產後,PWA 就會取代目前載入中的資產。這不是本課程的複雜工作。一些有助於導入這項更新的工具是 livereload-js,而 CSS 資產更新 CSSStyleSheet.replace() API。
更新 Service Worker
當服務工作站或其依附元件有所變更時,瀏覽器會觸發更新演算法。瀏覽器會以位元組為單位比較快取檔案和來自網路的資源來偵測更新。
接著,瀏覽器嘗試安裝新版 Service Worker,而新的 Service Worker 將會處於 waiting 狀態,如服務工作處理程序章節中所述。新的安裝作業會為新的 Service Worker 執行 install
事件。如果您在事件處理常式中快取資產,系統也會重新快取資產。
偵測 Service Worker 異動
為偵測是否已準備好並安裝新的 Service Worker,我們會使用 Service Worker 註冊中的 updatefound
事件。新的 Service Worker 開始安裝時,會引發此事件。我們需要等待其狀態透過 statechange
事件變更為 installed
。請參閱以下內容:
async function detectSWUpdate() {
const registration = await navigator.serviceWorker.ready;
registration.addEventListener("updatefound", event => {
const newSW = registration.installing;
newSW.addEventListener("statechange", event => {
if (newSW.state == "installed") {
// New service worker is installed, but waiting activation
}
});
})
}
強制覆寫
系統會安裝新的 Service Worker,但系統會預設等待啟用。這樣可以防止新 Service Worker 接管可能與新版本不相容的舊用戶端。
新的 Service Worker 可以略過等候期並立即啟動啟用程序,但我們不建議這麼做。
self.addEventListener("install", event => {
// forces a service worker to activate immediately
self.skipWaiting();
});
self.addEventListener("activate", event => {
// when this SW becomes activated, we claim all the opened clients
// they can be standalone PWA windows or browser tabs
event.waitUntil(clients.claim());
});
當控制目前頁面的服務工作人員變更時,會觸發 controllerchange
事件。例如,有一位新的工作站略過了等待,並成為新的執行中工作站。
navigator.serviceWorker.addEventListener("controllerchange", event => {
// The service worker controller has changed
});
更新中繼資料
您也可以更新應用程式的中繼資料,主要是在網頁應用程式資訊清單中設定。舉例來說,你可以更新應用程式的圖示、名稱或起始網址,也可以新增應用程式捷徑等新功能。 不過,如果使用者已安裝應用程式但裝置上出現舊圖示,會發生什麼情況?他們何時會取得更新版本?
答案會因平台而異。以下將介紹可用的選項。
iOS、iPadOS 和 Android 瀏覽器的 Safari
在這些平台上,如要取得新的資訊清單中繼資料,只能從瀏覽器重新安裝應用程式。
使用 WebAPK 的 Android 裝置上的 Google Chrome
如果使用者在 Android 上使用 Google Chrome 安裝 PWA,同時啟用 WebAPK (大部分安裝的 Chrome PWA),系統就會根據演算法偵測並套用更新。詳情請參閱這篇資訊清單更新文章。
關於程序的其他注意事項:
如果使用者未開啟您的 PWA,就不會更新其 WebAPK。 如果伺服器未傳回資訊清單檔案 (出現 404 錯誤),Chrome 至少 30 天都不會檢查更新,即便使用者開啟 PWA 亦然。
在 Android 裝置上的 Chrome 中前往 about:webapks
,查看「需要更新」的狀態,並要求提供更新。您可以在「Tools and debug chapter」中進一步瞭解這個偵錯工具。
在 Android 裝置上使用 WebAPK 的 Samsung 網際網路
這個流程與 Chrome 版本類似。在這種情況下,如果 PWA 資訊清單需要更新,請在接下來的 24 小時內,退出新版 WebAPK,然後透過 Wi-Fi 更新 WebAPK。
Google Chrome 和 Microsoft Edge 電腦版
如果是電腦裝置,當 PWA 啟動時,瀏覽器就會判斷上次檢查本機資訊清單是否有變更。如果資訊清單在瀏覽器上次啟動後尚未經過審查,或是在過去 24 小時內未檢查過,瀏覽器就會對資訊清單發出網路要求,然後與本機副本進行比較。
所選屬性更新後,會在所有視窗關閉後觸發更新作業。
通知使用者
部分更新策略需要重新載入或從用戶端進行新的導覽。建議您告知使用者有可用的更新,但適時更新他們最適合的網頁。
您可以透過下列方法通知使用者:
- 使用 DOM 或 canvas API 在螢幕上顯示通知。
- 使用 Web Notifications API。此 API 是推送權限的一部分,可在作業系統中產生通知。即使你並未使用伺服器中的推送訊息通訊協定,仍必須要求網路推送權限才能使用。如果未開啟 PWA,我們只會提供這個選項。
- 使用 Badging API,顯示 PWA 安裝圖示中有可用的更新
。
進一步瞭解徽章 API
Badging API 可讓你為 PWA 的圖示加上徽章號碼或相容瀏覽器上的標記點。徽章圓點在已安裝圖示中是一個小標誌,表示正在等候應用程式中的內容。
您需要在 navigator
物件上呼叫 setAppBadge(count)
,才能設定徽章號碼。當您知道有更新通知使用者時,可以從視窗或 Service Worker 的內容中執行這項操作。
let unreadCount = 125;
navigator.setAppBadge(unreadCount);
如要清除標記,請在相同物件上呼叫 clearAppBadge()
:
navigator.clearAppBadge();