重點摘要
從 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 遭到「喚醒」透過 push
或 sync
事件觸發
會同時要求原本傳入至
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 將軟體部署到網路的所有開發人員。