摘要:接受一個對象作參數,來定義安裝時長和安裝是否成功,如果狀態為,則認為此次安裝失敗,并且拋棄如果一個舊版本的正在運行,則它將保持不變。在頁面既可以在中獲取到,也可以在頁面中獲取到,這就意味著你不必一定要通過來向緩存中添加內容。
原文鏈接:The offline cookbook
作者:Jake Archibald
使用AppCache可以為我們提供幾種支持內容離線工作的模式。如果這些模式正是你所需要的,那么恭喜你,你中了APPCache的大獎(盡管頭等獎依然無人認領),但我們這些其余的人都擠在角落里來回搖擺(譯者注:作者指的是由于設計上的原因,AppCache逐漸地被Web標準移除,雖然現在依然有瀏覽器支持這個功能,但最好不要再使用它了)
對于ServiceWorker(介紹),我們放棄嘗試去解決離線問題,并且給開發者們提供靈活的組件從而讓他們自己去解決離線問題。它為您提供了控制緩存和處理請求的方式。這就意味著您可以創建您自己的模式。接下來讓我們來看一下幾個隔離環境下的可行模式,但是在實踐中,您可能會根據URL和context以串聯方式用到其中的多個模式。
目前,除非另有說明,所有的示例代碼都可以運行在Chrome和Firefox瀏覽器中。關于ServiceWorker支持程度的完整詳情,請查閱"Is Service Worker Ready?"。
有關對于其中部分模式的運行演示,請查閱Trained-to-thrill,并且此處的視頻將向您展示性能影響。
緩存機-何時開始存儲資源?您可以通過ServiceWorker來獨立地從緩存中處理請求,所以我們要先多帶帶地研究一下它們。首先,我們啥時候應該進行緩存呢?
安裝時——以依賴的形式ServiceWorker提供給您一個install事件,您可以使用它把資源準備好,即在處理其他事件之前必須要提前準備好的東西。但是當這些操作正在進行中的時候,任何舊版本的ServiceWorker仍舊在運行并且提供給頁面,因此您在此處進行的操作一定不能中斷它們。
適用于: CSS、圖片、字體、JS文件、模板等,基本包含了你認為網站在當前“版本”中應該需要的所有靜態資源。
如果未能獲取上述資源,那么您的網站完全無法運行,對應的本機應用會將這些對象包含在初始下載中。
self.addEventListener("install", function(event) { event.waitUntil( caches.open("mysite-static-v3").then(function(cache) { return cache.addAll([ "/css/whatever-v3.css", "/css/imgs/sprites-v6.png", "/css/fonts/whatever-v8.woff", "/js/all-min-v4.js" // etc ]); }) ); });
event.waitUntil接受一個promise對象作參數,來定義安裝時長和安裝是否成功,如果promise狀態為rejected,則認為此次安裝失敗,并且拋棄ServiceWorker(如果一個舊版本的ServiceWorker正在運行,則它將保持不變)。caches.open和caches.addAll都返回promise對象,如果其中有任何一個資源獲取失敗,則caches.addAll會調用reject。
在trained-to-thrill 上,我使用此方法緩存靜態資源。
此方式與上述相似,但區別是:即使緩存失敗,既不會延遲安裝也不會導致安裝失敗。
適用于: 體積較大的,且暫時用不到的資源,比如用于游戲的較高級別的資源。
self.addEventListener("install", function(event) { event.waitUntil( caches.open("mygame-core-v1").then(function(cache) { cache.addAll( // levels 11-20 ); return cache.addAll( // core assets & levels 1-10 ); }) ); });
我們沒有將levels 11-20的cache.addAll promise對象,返回給event.waitUntil,所以事件即使失敗,游戲在離線的時候依然可以使用。當然,您必須考慮到缺少這些level的情況,如果缺少它們,則嘗試重新緩存它們。
在當level 11-20正在下載的時候,ServiceWorker可能會終止,因為它已經完成處理事件。這就意味著它們就不會被緩存下來。未來,我們計劃添加一個在后臺下載的API以處理類似這樣的情況,以及下載像電影一樣的大體積文件。
激活時適用于: 清理和遷移
在新的ServiceWorker已經被安裝,并且較早版本的sw沒有在使用的情況下,則新的ServiceWorker會被激活,您就會得到一個activate事件。由于舊版本的退出,所以此時非常適合處理 IndexedDB 中的架構遷移和刪除未使用的緩存。
self.addEventListener("activate", function(event) { event.waitUntil( caches.keys().then(function(cacheNames) { return Promise.all( cacheNames.filter(function(cacheName) { // 如果您想刪除緩存,則返回true, // 但是請記住緩存在該域名內的所有頁面之間 // 是共享的 }).map(function(cacheName) { return caches.delete(cacheName); }) ); }) ); });
在激活的過程中,諸如fetch等事件會被放置在一個隊列中,所以一個長時間的激活可能會阻塞頁面加載。保證您的激活盡可能地簡潔,僅用于舊版本處于活動狀態時無法執行的操作。
在trained-to-thrill上,我使用此方法移除舊緩存。
在用戶交互時適用于: 如果整個站點無法離線工作,您可以允許用戶選擇需要離線的可用內容,比如,YouTube上的某個視頻,維基百科上的某篇文章,Flickr上的某張圖片等等。
為用戶提供一個“稍后閱讀”或者“離線保存”的按鈕。當點擊按鈕,從網絡中獲取您所需要的內容并把它放進緩存中。
document.querySelector(".cache-article").addEventListener("click", function(event) { event.preventDefault(); var id = this.dataset.articleId; caches.open("mysite-article-" + id).then(function(cache) { fetch("/get-article-urls?id=" + id).then(function(response) { // /get-article-urls returns a JSON-encoded array of // resource URLs that a given article depends on return response.json(); }).then(function(urls) { cache.addAll(urls); }); }); });
cacheAPI在頁面既可以在ServiceWorker中獲取到,也可以在頁面中獲取到,這就意味著你不必一定要通過ServiceWorker來向緩存中添加內容。
網絡響應時適用于: 頻繁更新的資源,比如用戶收件箱,或者文章內容。同樣適用于不重要但需要謹慎處理的內容,比如用戶頭像。
如果請求的資源與緩存中的任何資源均不匹配,則從網絡中獲取,將其發送到頁面中,同時將其添加到緩存中。
如果您針對一系列網址執行此操作,如頭像,那么您需要謹慎,不要使域名下的存儲變得臃腫,如果用戶需要回收磁盤空間,您不會想成為主要候選對象。請確保將緩存中不再需要的項目刪除。
self.addEventListener("fetch", function(event) { event.respondWith( caches.open("mysite-dynamic").then(function(cache) { return cache.match(event.request).then(function (response) { return response || fetch(event.request).then(function(response) { cache.put(event.request, response.clone()); return response; }); }); }) ); });
為了高效使用內存,只允許讀取一次response或request的body,在上面的代碼中,使用.clone來創建能夠多帶帶地讀取數據的額外副本。
在trained-to-thrill上,我使用此方法緩存Flickr圖像。
Stale-while-revalidate適用于: 頻繁更新,但卻沒必要獲取最新的資源。用戶頭像就屬于此類。
如果緩存中已經有一個可用的版本,直接使用該版本,但是會為了下一次的請求而獲取一個更新版本。
self.addEventListener("fetch", function(event) { event.respondWith( caches.open("mysite-dynamic").then(function(cache) { return cache.match(event.request).then(function(response) { var fetchPromise = fetch(event.request).then(function(networkResponse) { cache.put(event.request, networkResponse.clone()); return networkResponse; }) return response || fetchPromise; }) }) ); });
它和 HTTP 的 stale-while-revalidate 非常相似。
推送消息時注意: Chrome暫時還不支持Push。(譯者注:Chrome 50及之后的版本開始支持,更多信息請參考 can i use)
Push API是基于ServiceWorker構建的另一個功能。它允許喚醒ServiceWorker以響應來自系統服務的消息,即使用戶沒有為您的站點打開一個標簽,Push API也同樣可以工作。只有ServiceWorker被喚醒。您從頁面請求執行此操作權限的同時,用戶也將收到提示。
適用于: 與通知有關的內容,比如聊天消息,突發新聞,或者Email等。同樣適用于不經常更改的可立即同步的內容,例如待辦事項更新或者日程表的更改。
用戶常見的頁面表現是,出現一個通知,當點擊它的時候,會打開或者聚焦到相關的頁面,但是在點擊它之前,務必要更新緩存。顯然,用戶在收到推送消息的時候,一定是在線的,但是,當他們最終與通知交互時可能已經離線,因此,允許離線訪問此內容非常重要。Twitter原生應用在大多數情況下都是非常好的離線優先例子,但在這點上卻有點小問題。
如果沒有網絡連接,Twitter無法提供與推送消息相關的內容。但是點按通知會移除通,從而使用戶獲取的信息比點按通知之前還要少。不要這么做!
下面的代碼會在展示通知之前更新緩存。
self.addEventListener("push", (event) => { if (event.data.text() == "new-email") { event.waitUntil(async function() { const cache = await caches.open("mysite-dynamic"); const response = await fetch("/inbox.json"); await cache.put("/inbox.json", response.clone()); const emails = await response.json(); registration.showNotification("New email", { body: "From " + emails[0].from.name tag: "new-email" }); }()); } }); self.addEventListener("notificationclick", function(event) { if (event.notification.tag == "new-email") { // Assume that all of the resources needed to render // /inbox/ have previously been cached, e.g. as part // of the install handler. new WindowClient("/inbox/"); } });后臺同步時
注意: 后臺同步尚未加入到Chrome穩定版本中。(譯者注:Chrome 49及之后的版本中開始支持,但FireFox、Safari尚未支持,更多信息請參考 can i use)
后臺同步是基于ServiceWorker來構建的另一個功能。它允許您一次性地,或者按照(非常具有啟發性的)時間間隔來請求后臺數據同步。即使用戶沒有為您的站點打開一個標簽,后臺同步也同樣可以工作。只有ServiceWorker被喚醒。您從頁面請求執行此操作權限的同時,用戶也將收到提示。
適用于: 不緊急的更新,尤其是那些定期進行的更新,每次更新都發送一個推送消息顯得太頻繁,比如社交時間表和新聞資訊。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/99742.html
摘要:譯前端離線指南上原文鏈接作者緩存持久化為您的站點提供一定量的可用空間來執行其所需的操作。這是可能的,因為通常會保持使內容最具線性特性的順序。 [[譯]前端離線指南(上)](https://juejin.im/post/5c0788...原文鏈接:The offline cookbook 作者:Jake Archibald 緩存持久化 為您的站點提供一定量的可用空間來執行其所需的操作...
摘要:是在谷歌的年開發者峰會上宣布,但穩定的技術和工具終于在月到達。固然也不能保證蘋果將實施這項技術,但這并不重要,你的應用程序仍然可以在中工作,它只是不會從離線執行中受益。我有一種感覺一旦上體驗有明顯提升蘋果將鼓勵支持。 2016年是值得紀念、奇怪的、有點歡騰/可怕的一年,取決于你的觀點。跟其他事件相比僅僅專注于JavaScript可能看起來無關緊要,但它是每個Web開發人員的工作生活中巨...
摘要:是在谷歌的年開發者峰會上宣布,但穩定的技術和工具終于在月到達。固然也不能保證蘋果將實施這項技術,但這并不重要,你的應用程序仍然可以在中工作,它只是不會從離線執行中受益。我有一種感覺一旦上體驗有明顯提升蘋果將鼓勵支持。 2016年是值得紀念、奇怪的、有點歡騰/可怕的一年,取決于你的觀點。跟其他事件相比僅僅專注于JavaScript可能看起來無關緊要,但它是每個Web開發人員的工作生活中巨...
摘要:是在谷歌的年開發者峰會上宣布,但穩定的技術和工具終于在月到達。固然也不能保證蘋果將實施這項技術,但這并不重要,你的應用程序仍然可以在中工作,它只是不會從離線執行中受益。我有一種感覺一旦上體驗有明顯提升蘋果將鼓勵支持。 2016年是值得紀念、奇怪的、有點歡騰/可怕的一年,取決于你的觀點。跟其他事件相比僅僅專注于JavaScript可能看起來無關緊要,但它是每個Web開發人員的工作生活中巨...
摘要:雖然有著各種各樣的不同,但是相同的是,他們前端優化不完全指南前端掘金篇幅可能有點長,我想先聊一聊閱讀的方式,我希望你閱讀的時候,能夠把我當作你的競爭對手,你的夢想是超越我。 如何提升頁面渲染效率 - 前端 - 掘金Web頁面的性能 我們每天都會瀏覽很多的Web頁面,使用很多基于Web的應用。這些站點看起來既不一樣,用途也都各有不同,有在線視頻,Social Media,新聞,郵件客戶端...
閱讀 1480·2021-11-17 09:33
閱讀 1260·2021-10-11 10:59
閱讀 2892·2021-09-30 09:48
閱讀 1904·2021-09-30 09:47
閱讀 3023·2019-08-30 15:55
閱讀 2335·2019-08-30 15:54
閱讀 1491·2019-08-29 15:25
閱讀 1645·2019-08-29 10:57