摘要:的核心在于,目前中文社區中關于的知識深度普遍不夠,難以應對實際項目中的問題。通過方法,可以直接讓狀態的新替換掉老的,注意還會自動接管上一個管轄的頁面。
Service Worker
PWA的核心在于Service Worker,目前中文社區中關于Service Worker的知識深度普遍不夠,難以應對實際項目中的問題。例如我想要知道在卸載sw(下文簡稱sw)后需不需要手動清理caches,搜索引擎是沒有什么好答案的。這篇文章結合淘寶首頁PWA的經驗,分享出我認為非常有價值的關于Service Worker的知識點。先從注冊說起,sw應該在什么時候注冊?
一些教程是這樣注冊sw的
if ("serviceWorker" in navigator) { navigator.serviceWorker.register("/sw.js") }
這樣做會造成第一個問題,sw線程將加劇對CPU和內存的使用,并且sw內預緩存的資源是需要下載的,移動設備帶寬有限,sw線程占用的同時,主進程帶寬就變成了小水管了。
首次打開各種資源都非常寶貴,況且是漸進式,完全沒有必要爭第一次打開頁面就要緩存資源。正確的做法是,頁面加載完以后sw的事。
if ("serviceWorker" in navigator) { window.addEventListener("load", function() { navigator.serviceWorker.register("/sw.js"); }); }我想注銷所有已注冊用戶的sw,怎么做才最穩妥?
并不是所有移動端瀏覽器都支持getRegistrations,getRegistration更靠譜,可以先嘗試使用getRegistrations,如果無法使用再嘗試getRegistration,如下。
var serviceWorker = navigator.serviceWorker; serviceWorker.getRegistrations ? serviceWorker.getRegistrations().then(function(sws) { sws.forEach(function(sw) { sw.unregister(); }); }) : serviceWorker.getRegistration && serviceWorker.getRegistration().then(function(sw) { sw && sw.unregister(); });我注銷了sw,之前留下的caches還需要自己動手處理嗎?
需要,cacheStorage雖然屬于PWA規范API當中,但它是獨立的,雖然注銷了service worker,caches里垃圾不清掉,它就會一直留在那里了。這么清
window.caches && caches.keys && caches.keys().then(function(keys) { keys.forEach(function(key) { caches.delete(key); }); });該不該使用self.clients.claim?
clients.claim的作用是使當前SW接管已經打開的所有標簽頁,使用場景是用戶首次打開注冊sw的頁面時,還存在其他同域頁面的瀏覽器標簽的情況。之前打開的頁面沒有被接管,所以通過clients.claim接管已經打開但沒受到控制的瀏覽器標簽頁面。
skipWaiting的使用場景是在sw更新時,因為有上一個sw正在控制著所有該站點的頁面,新的sw在active后進入waiting狀態,直到用戶將所有該站點頁面關閉,新的sw才上位。這跟Chrome和VScode的更新機制一樣,在使用過程中有更新的時候,并不影響你繼續使用老版本,而是在重啟程序后,直接才變成新版。通過skipWaiting方法,可以直接讓waiting狀態的新sw替換掉老的sw,注意 還會自動接管上一個sw管轄的頁面。
我是不推薦使用clients.claim的,首先出現不受控標簽的情況相對比較少,況且首次加載速度尤其重要,能省點開銷就省點吧。
在sw里監聽fetch事件,請求多過了一層sw,會有性能損耗嗎?當然會,像下面這樣搞,是萬萬不要的
self.addEventListener("fetch", event => { event.respondWith(fetch(event.request)); });為什么我在sw中postMessage到頁面,頁面無法收到message
這是在測試serviceWorker的postMessage能力時,經常遇到的一個問題,想要找到原因就要從sw接管的頁面說起。在sw.js中使用self.clients.matchAll方法獲取當前serviceWorker實例所接管的所有標簽頁,注意是當前實例 已經接管的,并且sw.js中的代碼只會執行一次,當sw.js代碼中存在如下代碼時
self.clients.matchAll() .then(function (clients) { clients.forEach(client => { client.postMessage("這條消息不會被收到"); }) });
clients一定是個空數組,所以永遠也postMessage不到頁面。那要如何才能在首次install就postMessage到頁面上那?答案是self.skipWaiting,然后在activate事件中使用self.clients.matchAll,因為調用了skipWaiting,當前的sw在install以后會立刻avtivate并接管上一個sw的所有標簽頁,這樣就能在新sw中拿到標簽頁postMessage了
self.skipWaiting() self.addEventListener("activate", () => { self.clients.matchAll() .then(function (clients) { clients.forEach(client => { client.postMessage("skipWaiting讓新的sw接管了頁面,這樣就可以收到"); }) }); })
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/108132.html
摘要:業界動態發布版本,同時發布了版本以及首個穩定版本的。程序人生如何用人類的方式進行二關于如何在中進行良好的溝通,避免陷入一些潛在的陷阱。技術周刊由小組出品,匯聚一周好文章,周刊原文。 業界動態 Angular 5.1 & More Now Available Angular發布5.1版本,同時發布了Angular CLI 1.6版本以及首個穩定版本的Angular Material。CL...
摘要:一閱前熱身為了更加形象的說明同步異步阻塞非阻塞,我們以小明去買奶茶為例。等奶茶做好了,店員喊一聲小明,奶茶好了,然后小明去取奶茶。將響應結果發給相應的連接請求處理完成因為基于,所以每個可以處理無數個連接請求。如此,就輕松的處理了高并發。 一、閱前熱身 為了更加形象的說明同步異步、阻塞非阻塞,我們以小明去買奶茶為例。 1、同步與異步 ①同步與異步的理解 同步與異步的重點在消息通知的方式上...
摘要:一閱前熱身為了更加形象的說明同步異步阻塞非阻塞,我們以小明去買奶茶為例。等奶茶做好了,店員喊一聲小明,奶茶好了,然后小明去取奶茶。將響應結果發給相應的連接請求處理完成因為基于,所以每個可以處理無數個連接請求。如此,就輕松的處理了高并發。 一、閱前熱身 為了更加形象的說明同步異步、阻塞非阻塞,我們以小明去買奶茶為例。 1、同步與異步 ①同步與異步的理解 同步與異步的重點在消息通知的方式上...
閱讀 3476·2021-11-19 09:40
閱讀 1492·2021-10-13 09:41
閱讀 2655·2021-09-29 09:35
閱讀 2710·2021-09-23 11:21
閱讀 1693·2021-09-09 11:56
閱讀 830·2019-08-30 15:53
閱讀 844·2019-08-30 15:52
閱讀 598·2019-08-30 12:47