使用服務工作者和 Cache Storage API 的開發人員應留意 Chrome 71 推出的兩項小變更。這兩項異動可讓 Chrome 的實作內容更符合規格和其他瀏覽器。
禁止非同步 importScripts()
importScripts()
會指示主要 Service Worker 指令碼暫停目前的執行作業、從特定網址下載其他程式碼,並執行在目前的全域範圍中執行作業。完成後,主要服務工作者指令碼就會繼續執行。importScripts()
可用於將主要服務 worker 指令碼分割成較小的片段,以便進行分類,或是用於匯入第三方程式碼,為服務 worker 新增功能。
瀏覽器會嘗試透過自動快取透過 importScripts()
拉入的所有內容,來減輕「下載並執行某些同步程式碼」可能發生的效能問題,也就是說,在初始下載作業完成後,執行匯入的程式碼所需的額外負荷非常少。
不過,瀏覽器必須知道在初始安裝後,不會有任何「意外」程式碼匯入服務工作站,才能讓這項功能正常運作。根據服務 worker 規格,呼叫 importScripts()
應該只在頂層服務 worker 指令碼同步執行期間,或在 install
處理常式中非同步執行時才會生效。
在 Chrome 71 以下版本,必須透過 install
處理常式以外的方式,以非同步方式呼叫 importScripts()
。自 Chrome 71 版起,這些呼叫會擲回執行階段例外狀況 (除非先前已在 install
處理常式中匯入相同的網址),與其他瀏覽器的行為一致。
請改用以下程式碼:
// This only works in Chrome 70 and below.
self.addEventListener('fetch', event => {
importScripts('my-fetch-logic.js');
event.respondWith(self.customFetchLogic(event));
});
服務工作程程式碼應如下所示:
// Move the importScripts() to the top-level scope.
// (Alternatively, import the same URL in the install handler.)
importScripts('my-fetch-logic.js');
self.addEventListener('fetch', event => {
event.respondWith(self.customFetchLogic(event));
});
淘汰傳遞至 Cache.addAll() 的重複網址
如果您同時使用 Cache Storage API 和服務工作者,Chrome 71 中還有另一項小變更,以便與相關規格保持一致。當同一個網址多次傳遞至單一 cache.addAll()
呼叫時,規格說明指出,呼叫傳回的承諾應遭到拒絕。
在 Chrome 71 以下版本中,系統並未偵測到上述版本,因此會忽略重複的網址。
這項記錄是 Chrome 72 版的前提,重複網址不僅會記錄的警告,還會導致 cache.addAll()
拒絕。如果您在傳遞至 InstallEvent.waitUntil()
的承諾鏈中呼叫 cache.addAll()
,而這是常見做法,這可能會導致服務工作站無法安裝。
以下說明可能會遇到的問題:
const urlsToCache = [
'/index.html',
'/main.css',
'/app.js',
'/index.html', // Oops! This is listed twice and should be removed.
];
self.addEventListener('install', event => {
event.waitUntil(
caches.open('my-cache').then(cache => cache.addAll(urlsToCache))
);
});
這項限制僅適用於傳遞至 cache.addAll()
的實際網址,如果在快取結果中包含兩個不同網址 (例如 '/'
和 '/index.html'
) 的回應,則不會觸發拒絕動作。
廣泛測試服務 worker 實作
目前,服務工作者已在所有主要的「永久更新」瀏覽器上廣泛實作。如果您定期針對多個瀏覽器測試漸進式網頁應用程式,或是有大量使用者不使用 Chrome,那麼您很可能已經發現不一致性,並更新了程式碼。但如果您現在未在其他瀏覽器中註意到這項行為,我們希望在切換 Chrome 行為之前先說明這項變更。