新推出 Service Worker 預設為

重點摘要

從 Chrome 68 開始,檢查 Service Worker 指令碼更新的 HTTP 要求不會 未經過 HTTP 快取 根據預設。這可以解決開發人員的常見問題。 在 Service Worker 指令碼中設定錯誤的 Cache-Control 標頭, 。

如果您透過提供 /service-worker.js 指令碼,停用 HTTP 快取功能 的 Cache-Control: max-age=0,則應該不會出現因為新的預設值而產生任何變更 行為

此外,從 Chrome 78 版開始,「每個位元組的比較」功能 套用至在 Service Worker 中載入的指令碼 importScripts()。 對匯入的指令碼所做的變更都會觸發 Service Worker 更新流程, 就像變更頂層 Service Worker 一樣

背景

每次前往位於 Service Worker 範圍內的新頁面時,請明確呼叫 registration.update() 或 Service Worker 遭到「喚醒」透過 pushsync 事件觸發 會同時要求原本傳入至 navigator.serviceWorker.register() 呼叫,藉此尋找 Service Worker 指令碼的更新。

為方便您參考,我們假設其網址為 /service-worker.js, 包含對 importScripts() 的一次呼叫 載入在 Service Worker 中執行的其他程式碼:

// Inside our /service-worker.js file:
importScripts('path/to/import.js');

// Other top-level code goes here.

異動內容

在 Chrome 68 以下版本中,/service-worker.js 的更新要求會透過 HTTP 快取發出 (多數擷取次數都是)。也就是說,如果指令碼原本是以 Cache-Control: max-age=600 傳送,在未來 600 秒 (10 分鐘) 內的更新就不會傳至網路,因此 使用者可能不會收到最新版本的 Service Worker。不過,如果 max-age 之前 大於 86400 (24 小時) 時,系統會視為 86400,以免使用者停滯不前 就會永遠針對特定版本

自 68 版起,要求更新 Service Worker 時,系統會忽略 HTTP 快取 指令碼,因此現有的網頁應用程式送出要求頻率可能會增加 Service Worker 指令碼。對「importScripts」的要求仍會透過 HTTP 快取傳送。但這是 只有預設的註冊選項:updateViaCache 提供新的註冊選項,可讓您控管 這種行為

updateViaCache

開發人員現在可以在呼叫 navigator.serviceWorker.register() 時傳入新選項:updateViaCache 參數。 這個值採用以下三個值之一:'imports''all''none'

這些值可決定瀏覽器的標準 HTTP 快取,以及其方式 的運作時間有限。

  • 設為 'imports' 時,系統在檢查 /service-worker.js 指令碼,但擷取任何匯入的指令碼時將會查詢 (在本範例中為 path/to/import.js)。這是預設設定,且符合啟動行為 Chrome 68 版。

  • 如果設為 'all',系統就會在提出 HTTP 快取 頂層 /service-worker.js 指令碼,以及匯入服務中的任何指令碼 例如 path/to/import.js這個選項對應的是先前的 Chrome 行為 Chrome 68 以下版本。

  • 設為 'none' 時,當 頂層 /service-worker.js 或任何匯入的指令碼,例如假設 path/to/import.js

例如,下列程式碼將註冊 Service Worker,並確認 HTTP 快取 檢查 /service-worker.js 指令碼的更新時不曾參考任何資訊,或者 透過 /service-worker.js 中的 importScripts() 參照的指令碼:

if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/service-worker.js', {
    updateViaCache: 'none',
    // Optionally, set 'scope' here, if needed.
  });
}

檢查匯入的指令碼是否有更新

在 Chrome 78 以下版本中,任何 Service Worker 指令碼會經由 importScripts()敬上 只會擷取一次 (檢查 HTTP 快取,或是透過 視 updateViaCache 設定而定)。在此初始之後 只會由瀏覽器內部儲存,絕不會重新擷取。

強制已安裝 Service Worker 要強制安裝變更, 匯入的指令碼即可變更指令碼的網址,做法通常是將 semver 值 (例如 importScripts('https://example.com/v1.1.0/index.js')) 或加入 (例如 importScripts('https://example.com/index.abcd1234.js'))。A 罩杯 變更匯入的網址會產生副作用,那就是頂層 Service Worker 指令碼內容變更,進而觸發 Service Worker 更新流程

從 Chrome 78 開始,每次執行更新檢查時 Service Worker 檔案會同時進行檢查,以判斷 或所有匯入指令碼的內容都已變更根據用途 使用 Cache-Control 標頭,匯入的指令碼檢查可能會透過以下項目完成: 如果 updateViaCache 設為 'all''imports' (也就是 預設值) 或檢查可能會直接透過網路進行 updateViaCache已設為 'none'

如果更新檢查匯入的指令碼後會產生位元組差異 相較於 Service Worker 先前儲存的資料, 觸發完整 Service Worker 更新流程,即使頂層服務也一樣 工作站檔案保持不變

Chrome 78 的行為符合 Firefox implemented 甚至幾年前的 Firefox 版本 56Safari 已經導入這個行為

開發人員需要做些什麼?

如果您已透過提供 /service-worker.js 指令碼,有效停用 HTTP 快取功能 帶有 Cache-Control: max-age=0 (或類似的值) 標籤,則應該不會因為 新的預設行為

如果您在啟用 HTTP 快取的情況下提供 /service-worker.js 指令碼,您必須刻意 或者這只是代管環境的預設選項。 針對 /service-worker.js 發出的其他 HTTP 要求,可能會開始增加 伺服器—這些要求過去要由 HTTP 快取執行。如果您想 繼續允許 Cache-Control 標頭值影響 /service-worker.js,您必須在下列情況下明確設定 updateViaCache: 'all' 註冊 Service Worker。

由於舊版瀏覽器的使用者可能會長久以來 繼續在 Service Worker 指令碼中設定 Cache-Control: max-age=0 HTTP 標頭, 所以新版瀏覽器可能會忽略這些網址。

開發人員可以把握這個機會,決定是否要明確選擇匯入資料庫 立即將指令碼移出 HTTP 快取,並將 updateViaCache: 'none' 新增至 Service Worker 註冊

提供匯入的指令碼

從 Chrome 78 開始,開發人員可能會看到更多傳入 HTTP 要求: 透過 importScripts() 載入的資源,因為現在會檢查 更新。

如果不想再產生這段額外的 HTTP 流量,請將 放送指令碼且包含 Semver 或雜湊值時,Cache-Control 標頭 這類網址,並採用 'imports' 的預設 updateViaCache 行為。

或者,如果您想經常檢查匯入的指令碼 進行更新,請務必使用 Cache-Control: max-age=0 放送。 或是使用 updateViaCache: 'none'

延伸閱讀

The Service Worker 生命週期」和 「快取最佳做法與max-age 畫面上會顯示作業", 我們推薦使用 Jake Archibald 將軟體部署到網路的所有開發人員。