摘要:的生命周期生命周期與您的網(wǎng)頁是完全分開。激活安裝之后,下一步是將其激活。一旦激活,將開始控制所有屬于其范圍的頁面。否則,將執(zhí)行事件。響應(yīng)結(jié)果被添加到緩存中。請求和響應(yīng)必須被克隆,因?yàn)樗鼈兪橇鳌P碌膶硬⑶沂录⒈挥|發(fā)。
您可能已經(jīng)知道,漸進(jìn)式Web應(yīng)用(PWA)會越來越受歡迎,因?yàn)樗鼈冎荚谑筗eb應(yīng)用的用戶體驗(yàn)更加流暢,創(chuàng)建Native應(yīng)用程序般的體驗(yàn),而不只是運(yùn)行在瀏覽器的應(yīng)用。
構(gòu)建漸進(jìn)式Web應(yīng)用程序的主要原因之一是使應(yīng)用在網(wǎng)絡(luò)和加載方面非常可靠 - 它應(yīng)該可用于不確定或不存在的網(wǎng)絡(luò)條件。
在這篇文章中,我們將深入探討Service Worker:他們?nèi)绾芜\(yùn)作以及應(yīng)該注意的地方。最后,我們還列出了您應(yīng)該利用的Service Workers的一些獨(dú)特優(yōu)勢。
概述如果你想了解關(guān)于Service Workers的一切,你應(yīng)該首先閱讀本系列第幾篇文章。
基本上,Service Worker是一種網(wǎng)絡(luò)工作者,更具體地說,它就像一個(gè)Shared Worker:
Service Worker在它自己的全局腳本上下文中運(yùn)行
它沒有綁定到特定的網(wǎng)頁
它無法訪問DOM
Service Worker API令人興奮的主要原因之一是它可以讓你的網(wǎng)絡(luò)應(yīng)用程序支持離線體驗(yàn),從而使開發(fā)人員能夠完全控制流程。
Service Worker 的生命周期Service Worker生命周期與您的網(wǎng)頁是完全分開。它由以下幾個(gè)階段組成:
下載
安裝
激活
下載這是瀏覽器下載包含Service Worker的.js文件的時(shí)候。
安裝您的Web應(yīng)用程序想要安裝Service Worker,您必須先注冊它,您可以在JavaScript代碼中進(jìn)行注冊。當(dāng)Service Worker被注冊時(shí),它會提示瀏覽器在后臺啟動Service Worker安裝步驟。
通過注冊Service Worker,你可以告訴瀏覽器你的Service Worker的JavaScript文件在哪里。我們來看下面的代碼:
if ("serviceWorker" in navigator) { window.addEventListener("load", function() { navigator.serviceWorker.register("/sw.js").then(function(registration) { // 注冊成功 console.log("ServiceWorker registration successful"); }, function(err) { // 注冊失敗 console.log("ServiceWorker registration failed: ", err); }); }); }
該代碼檢查當(dāng)前環(huán)境中是否支持Service Worker API。如果支持,則注冊/sw.js Service Worker。
您可以在每次加載頁面時(shí)調(diào)用register()方法而不用擔(dān)心 - 瀏覽器會判斷Service Worker是否已經(jīng)注冊,并且會正確處理。
register()方法的一個(gè)重要細(xì)節(jié)是Service Worker文件的位置。在這種情況下,您可以看到服務(wù)工作者文件位于域的根目錄。這意味著Service Worker的范圍將是整個(gè)來源。換句話說,這個(gè)Service Worker將會收到這個(gè)域的所有東西的fetch事件(我們將在后面討論)。如果我們在/example/sw.js注冊Service Worker文件,那么服務(wù)工作者將只能看到URL以/example/(即/example/page1/,/example/page2/)開頭的頁面的fetch事件。
在安裝階段,最好加載和緩存一些靜態(tài)資源。資源成功緩存后,Service Worker安裝完成。如果沒有成功(加載失敗) - Service Worker將重試。一旦安裝成功,您將知道靜態(tài)資源位于緩存中。
在安裝階段,最好加載和緩存一些靜態(tài)資源。資源成功緩存后,Service Worker安裝完成。如果沒有成功(加載失敗) - Service將重試。一旦安裝成功,您將知道靜態(tài)資產(chǎn)位于緩存中。
如果注冊需要在加載事件之后發(fā)生,這將回答您的問題。這不是必須的,但它是絕對推薦的。
為什么這樣?讓我們考慮用戶第一次訪問您的網(wǎng)絡(luò)應(yīng)用程序。目前還沒有Service Worker,瀏覽器無法事先知道是否會有安裝的Service Worker。如果安裝了Service Worker,則瀏覽器需要為這個(gè)額外的線程花費(fèi)額外的CPU和內(nèi)存,否則瀏覽器將花費(fèi)在渲染網(wǎng)頁上。
最重要的是,如果你只是在你的頁面上安裝一個(gè)Service Worker,你可能會有延遲加載和渲染的風(fēng)險(xiǎn) - 而不是盡快讓你的用戶可以使用這個(gè)頁面。
請注意,這僅在第一次訪問頁面時(shí)才顯得重要。后續(xù)頁面訪問不受Service Worker安裝的影響。一旦在第一次訪問頁面時(shí)激活Service Worker,它可以處理加載/緩存事件,以便隨后訪問您的Web應(yīng)用程序。這一切都是有道理的,因?yàn)樗枰獪?zhǔn)備好處理有限的網(wǎng)絡(luò)連接。
激活安裝Service Worker之后,下一步是將其激活。這一步是管理以前緩存的好機(jī)會。
一旦激活,Service Worker將開始控制所有屬于其范圍的頁面。一個(gè)有趣的事實(shí)是:首次注冊Service Worker的頁面將不會被控制,直到該頁面再次被加載。一旦處于Service Worker控制之下,它將處于以下狀態(tài)之一:
它將處理從頁面發(fā)出網(wǎng)絡(luò)請求或消息時(shí)發(fā)生的fetch和message事件
它將被終止以節(jié)省內(nèi)存
以下是生命周期的外觀:
在頁面加速注冊過程之后,讓我們看看Service Worker腳本中發(fā)生了什么,它通過向Service Worker實(shí)例添加事件偵聽器來處理install事件。
這些是install事件處理時(shí)需要采取的步驟:
打開緩存
緩存我們的文件
確認(rèn)是否緩存了所有必需的資源
這是一個(gè)簡單的install在Service Worker內(nèi):
var CACHE_NAME = "my-web-app-cache"; var urlsToCache = [ "/", "/styles/main.css", "/scripts/app.js", "/scripts/lib.js" ]; self.addEventListener("install", function(event) { // event.waitUntil takes a promise to know how // long the installation takes, and whether it // succeeded or not. event.waitUntil( caches.open(CACHE_NAME) .then(function(cache) { console.log("Opened cache"); return cache.addAll(urlsToCache); }) ); });
如果所有文件成功被緩存,Service Worker會被安裝。如果任何文件下載失敗,install步驟會失敗。所以主要注意你需要緩存的文件。
處理install事件是可選的,你可以避免處理它。在這種情況下,上面三個(gè)步驟你都無需處理。
在運(yùn)行時(shí)緩存請求這部分是關(guān)鍵所在。這里您將看到如何攔截請求并返回創(chuàng)建的緩存(并創(chuàng)建新緩存)。
安裝Service Worker并且用戶導(dǎo)航到另一個(gè)頁面或刷新他所在的頁面后,Service Worker將收到fetch事件。下面是一個(gè)演示如何返回緩存資源或執(zhí)行新請求然后緩存結(jié)果的示例:
self.addEventListener("fetch", function(event) { event.respondWith( // This method looks at the request and // finds any cached results from any of the // caches that the Service Worker has created. caches.match(event.request) .then(function(response) { // If a cache is hit, we can return thre response. if (response) { return response; } // Clone the request. A request is a stream and // can only be consumed once. Since we are consuming this // once by cache and once by the browser for fetch, we need // to clone the request. var fetchRequest = event.request.clone(); // A cache hasn"t been hit so we need to perform a fetch, // which makes a network request and returns the data if // anything can be retrieved from the network. return fetch(fetchRequest).then( function(response) { // Check if we received a valid response if(!response || response.status !== 200 || response.type !== "basic") { return response; } // Cloning the response since it"s a stream as well. // Because we want the browser to consume the response // as well as the cache consuming the response, we need // to clone it so we have two streams. var responseToCache = response.clone(); caches.open(CACHE_NAME) .then(function(cache) { // Add the request to the cache for future queries. cache.put(event.request, responseToCache); }); return response; } ); }) ); });
簡而言之,這就是發(fā)生的過程:
event.respondWith()將決定我們?nèi)绾雾憫?yīng)fetch事件。我們傳遞了一個(gè)來自caches.match()的promise,它查看請求并發(fā)現(xiàn)是否有任何已創(chuàng)建的緩存的緩存結(jié)果。
如果存在緩存,則返回結(jié)果。
否則,將執(zhí)行fetch事件。
檢查狀態(tài)是否為200。我們還檢查響應(yīng)類型是否basic,這表明它是來自我們origin的請求。在這種情況下,不會緩存對第三方資源的請求。
響應(yīng)結(jié)果被添加到緩存中。
請求和響應(yīng)必須被克隆,因?yàn)樗鼈兪橇鳌A鞯闹黧w只能被使用一次。而且由于我們想要使用它們,瀏覽器也要使用它們,所以必需克隆它們。
更新服務(wù)工作者當(dāng)用戶訪問您的Web應(yīng)用程序時(shí),瀏覽器會嘗試重新下載包含Service Worker代碼的.js文件。這發(fā)生在后臺。
如果與當(dāng)前Service Worker的文件相比,現(xiàn)在下載的Service Worker文件中甚至存在單字節(jié)差異,則瀏覽器將假定有改變并且必須啟動新的Service Worker。
新的Service Worker將啟動并且install事件將被觸發(fā)。然而,在這一點(diǎn)上,舊的Service Worker仍在控制你的網(wǎng)絡(luò)應(yīng)用程序的頁面,這意味著新的Service Worker將進(jìn)入waiting狀態(tài)。
一旦您的Web應(yīng)用程序當(dāng)前打開的頁面關(guān)閉,舊的Service Worker將被瀏覽器終止,新安裝的Service Worker將完全控制。這是當(dāng)它的激活事件將被觸發(fā)。
為什么需要這些?為了避免兩個(gè)版本的Web應(yīng)用程序同時(shí)運(yùn)行在不同的選項(xiàng)卡上 - 這在網(wǎng)絡(luò)上實(shí)際上非常常見,并且可能會創(chuàng)建非常糟糕的錯(cuò)誤(例如,在瀏覽器中存儲數(shù)據(jù)時(shí)存在不同模式的情況)。
從緩存中刪除數(shù)據(jù)activate回調(diào)中最常見的步驟是緩存管理。你現(xiàn)在要這樣做,因?yàn)槿绻阍诎惭b步驟中刪除了所有舊的緩存,舊的Service Workers將突然停止提供緩存中的文件。
下面是一個(gè)示例,您可以從緩存中刪除某些未列入白名單的文件(在這種情況下,其名稱中包含page-1或page-2):
self.addEventListener("activate", function(event) { var cacheWhitelist = ["page-1", "page-2"]; event.waitUntil( // Retrieving all the keys from the cache. caches.keys().then(function(cacheNames) { return Promise.all( // Looping through all the cached files. cacheNames.map(function(cacheName) { // If the file in the cache is not in the whitelist // it should be deleted. if (cacheWhitelist.indexOf(cacheName) === -1) { return caches.delete(cacheName); } }) ); }) ); });HTTPS要求
在構(gòu)建Web應(yīng)用程序時(shí),您可以通過本地主機(jī)使用Service Worker,但是一旦將其部署到生產(chǎn)環(huán)境中,則需要準(zhǔn)備好HTTPS(這是您擁有HTTPS的最后一個(gè)原因)。
使用Service Worker,您可以劫持連接并制作響應(yīng)。 通過不使用HTTPs,您的Web應(yīng)用程序變得容易受到攻擊。
為了讓事情更安全,您需要在通過HTTPS提供的頁面上注冊Service Worker,以便您知道瀏覽器接收的Service Worker在通過網(wǎng)絡(luò)中未被修改。
瀏覽器支持服務(wù)人員的瀏覽器支持正在變得越來越好:
Service Worker提供的一些獨(dú)特功能是:
推送通知 - 允許用戶選擇從網(wǎng)絡(luò)應(yīng)用程序及時(shí)更新。
后臺同步 - 允許您推遲操作,直到用戶具有穩(wěn)定的連接。這樣,您可以確保無論用戶想要發(fā)送什么,實(shí)際上都會發(fā)送。
定期同步(未支持) - 提供管理定期后臺同步功能的API。
Geofencing(未來支持) - 您可以定義參數(shù),也稱為圍繞感興趣區(qū)域的地理圍欄。當(dāng)設(shè)備跨越地理圍欄時(shí),Web應(yīng)用程序會收到通知,這可以讓您根據(jù)用戶的地理位置提供有用的體驗(yàn)。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/107759.html
摘要:生命周期的生命周期和網(wǎng)頁完全不相關(guān)。意即會作用于整個(gè)源地址上。激活安裝完之后下一步即激活。同時(shí)檢查響應(yīng)類型是否為,即檢查請求是否同域。創(chuàng)建新的的過程將會啟動,然后觸發(fā)事件。可以利用劫持網(wǎng)絡(luò)連接和偽造響應(yīng)數(shù)據(jù)。 原文請查閱這里,略有刪減,本文采用知識共享署名 4.0 國際許可協(xié)議共享,BY Troland。 本系列持續(xù)更新中,Github 地址請查閱這里。 這是 JavaScript 工...
摘要:的生命周期的生命周期與頁面完全分離。換句話說,這個(gè)將為這個(gè)域中的所有內(nèi)容接收事件。這不是必要的,但絕對是推薦的。新的將啟動并且安裝事件將被移除。使用,可以很容易被劫持連接并偽造響應(yīng)。后臺同步允許延遲操作,直到用戶具有穩(wěn)定的連接。 這是專門探索 JavaScript 及其所構(gòu)建的組件的系列文章的第8篇。 想閱讀更多優(yōu)質(zhì)文章請猛戳GitHub博客,一年百來篇優(yōu)質(zhì)文章等著你! 如果你錯(cuò)過了前...
摘要:我喜歡移動,而且也是那些堅(jiān)持使用技術(shù)構(gòu)建移動應(yīng)用程序的人之一。我們準(zhǔn)備做這樣的一個(gè)漸進(jìn)式應(yīng)用是典型的旨在提高用戶離線體驗(yàn)的應(yīng)用。當(dāng)我們開始構(gòu)建應(yīng)用時(shí),你就能理解上面的場景了。的作用范圍是針對相對路徑的。最佳的做法是在應(yīng)用的入口。 我喜歡移動app,而且也是那些堅(jiān)持使用Web技術(shù)構(gòu)建移動應(yīng)用程序的人之一。 經(jīng)過技術(shù)的不斷迭代(可能還有一些其它的東西),移動體驗(yàn)設(shè)計(jì)愈來愈平易近人,給予用戶...
摘要:不過,這并不意味著語言本身就支持了多線程,對于語言本身它仍是運(yùn)行在單線程上的,只是瀏覽器宿主環(huán)境提供的一個(gè)能力。主線程與子線程之間也可以交換二進(jìn)制數(shù)據(jù),比如等對象,也可以在線程之間發(fā)送。 先看幾個(gè)例子 本例子是通過通過紅點(diǎn)展示地球上的地震帶,數(shù)據(jù)來自于地質(zhì)探測局通過console.log看到數(shù)據(jù)運(yùn)算所耗的時(shí)間不使用 webworker No web workers - all on ...
閱讀 1016·2021-09-26 09:55
閱讀 3556·2021-09-24 10:30
閱讀 1364·2021-09-08 09:36
閱讀 2553·2021-09-07 09:58
閱讀 603·2019-08-30 15:56
閱讀 765·2019-08-29 18:32
閱讀 3593·2019-08-29 15:13
閱讀 1840·2019-08-29 13:49