使用服務工作站和 Cache Storage API 的開發人員應在 Chrome 71 中推出兩項小幅變更。這兩項變更讓 Chrome 的實作方式更符合規格和其他瀏覽器。
不允許非同步 importScripts()
importScripts()
會指示主要服務工作站指令碼暫停目前的執行作業、從特定網址下載額外程式碼,並在目前的全域範圍中執行指令碼。完成後,主要服務工作站指令碼就會繼續執行。當您基於機構考量,而想將主要服務工作站指令碼分割成較小的檔案,或是插入第三方程式碼來為服務工作站新增功能時,importScripts()
非常實用。
瀏覽器會自動快取透過 importScripts()
提取的內容,藉此減少「下載並執行部分同步程式碼」可能帶來的效能問題,這表示在初始下載後,執行匯入的程式碼幾乎不會造成負擔。
但為此,瀏覽器必須知道在初次安裝後,系統不會將任何「意外」程式碼匯入 Service Worker。根據服務工作站規格,呼叫 importScripts()
應該只會在頂層 Service 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));
});
Service Worker 程式碼應如下所示:
// 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 和 Service Worker,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'
) 就不會觸發拒絕情形。
廣泛測試 Service Worker 的實作
目前,服務工作站已在所有主要「長期」瀏覽器上全面實作。如果您會定期針對各種瀏覽器測試漸進式網頁應用程式,或是有大量未使用 Chrome 的使用者,或許已經偵測到不一致並更新了程式碼。不過,您可能從未在其他瀏覽器中註意到這個行為,因此我們想在切換 Chrome 的行為前先提出變更。