溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

JavaScript中Service Worker生命周期及使用場(chǎng)景的示例分析

發(fā)布時(shí)間:2020-12-24 09:46:09 來(lái)源:億速云 閱讀:210 作者:小新 欄目:web開發(fā)

小編給大家分享一下JavaScript中Service Worker生命周期及使用場(chǎng)景的示例分析,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!

JavaScript中Service Worker生命周期及使用場(chǎng)景的示例分析

你可能已經(jīng)知道,漸進(jìn)式Web應(yīng)用程序 只會(huì)越來(lái)越受歡迎,因?yàn)樗鼈兊哪繕?biāo)是讓W(xué)eb應(yīng)用程序用戶體驗(yàn)更流暢,創(chuàng)建類似于原生應(yīng)用程序的體驗(yàn),而不是瀏覽器的外觀和感覺。

構(gòu)建漸進(jìn)式Web應(yīng)用程序的主要要求之一是使其在網(wǎng)絡(luò)和加載方面非??煽俊鼞?yīng)該在不確定或不存在的網(wǎng)絡(luò)條件下可用。

在這篇文章中,將深入探討 Service Workers:它們是如何工作,你應(yīng)該關(guān)心什么。最后,還列出了 Service Workers 中的一些獨(dú)特優(yōu)點(diǎn)在哪些場(chǎng)景下是值得我們使用的。

MDN 的介紹:

Service Worker 是一個(gè)瀏覽器背后運(yùn)行的腳步,獨(dú)立于 web 頁(yè)面,為無(wú)需一個(gè)頁(yè)面或用戶交互的功能打開了大門。今日,它包含了推送通知和背景異步(push notifications and background sync)的功能。將來(lái),Service Worker 將支持包括 periodic sync or geofencing 的功能。

基本上,Service Worker 是 Web Worker 的一個(gè)類型,更具體地說(shuō),它像 Shared Worker:

  • Service Worker 在其自己的全局上下文中運(yùn)行

  • 它沒有綁定到特定的網(wǎng)頁(yè)

  • 它不能訪問到 DOM

這是一個(gè)令人興奮的 API 的原因是它允許你支持離線體驗(yàn),讓開發(fā)人員完全控制體驗(yàn)。

Service Worker 的生命周期

Service Worker 的生命周期與 web 頁(yè)面完全分離。它包括以下幾個(gè)階段:

  • 下載

  • 安裝

  • 激活

下載

這是瀏覽器下載包含 Service Worker 的 .js 文件的時(shí)候。

安裝

要為 web 應(yīng)用程序安裝 Service Worker,必須先注冊(cè)它,這可以在 JavaScript 代碼中完成。注冊(cè) Service Worker 后,它會(huì)提示瀏覽器在后臺(tái)啟動(dòng) Service Worker 安裝步驟。

通過注冊(cè)  Service Worker,你可以告訴瀏覽器你的 Service Worker 的 JavaScript 文件的位置。看看下面的代碼:

JavaScript中Service Worker生命周期及使用場(chǎng)景的示例分析

上例代碼首先檢查當(dāng)前環(huán)境中是否支持 Service Worker API。如果支持,則 /sw.js 這個(gè) Service Worker 就被注冊(cè)了。

每次頁(yè)面加載時(shí)都可以調(diào)用 register() 方法,瀏覽器會(huì)判斷 Service Worker 是否已經(jīng)注冊(cè),根據(jù)注冊(cè)情況會(huì)對(duì)應(yīng)的給出正確處理。

register() 方法的一個(gè)重要細(xì)節(jié)是 Service Worker 文件的位置。在本例中,可以看到 Service Worker 文件位于域的根目錄,這意味著 Service Worker 范圍將是這個(gè)域下的。換句話說(shuō),這個(gè) Service Worker 將為這個(gè)域中的所有內(nèi)容接收 fetch 事件。如果我們?cè)?/example/sw.js 注冊(cè) Service Worker 文件,那么 Service Worker 只會(huì)看到以 /example/ 開頭的頁(yè)面的 fetch 事件(例如 /example/page1/、/example/page2/)。

通常在安裝步驟中,你需要緩存一些靜態(tài)資源。 如果所有文件都緩存成功,則 Service Worker 將被安裝。 如果任何文件無(wú)法下載和緩存,則安裝步驟將失敗,Service Worker 將不會(huì)激活(即不會(huì)被安裝)。 如果發(fā)生這種情況,不要擔(dān)心,下次再試一次。 但是,這意味著如果它安裝,你知道你有這些靜態(tài)資源在緩存中。

如果注冊(cè)需要在加載事件之后發(fā)生,這就解答了你“注冊(cè)是否需要在加載事件之后發(fā)生”的疑惑。這不是必要的,但絕對(duì)是推薦的。

為什么?讓我們考慮用戶第一次訪問你的 Web 應(yīng)用程序。目前還沒有 Service Worker,而且瀏覽器無(wú)法預(yù)先知道最終是否會(huì)安裝 Service Worker。如果安裝了 Service Worker,瀏覽器將需要為這個(gè)額外的線程花費(fèi)額外的 CPU 和內(nèi)存,否則瀏覽器將把這些額外的 CPU 和內(nèi)存用于呈現(xiàn) Web 頁(yè)面。

最重要的是,如果在頁(yè)面上安裝一個(gè) Service Worker,就可能會(huì)有延遲加載和渲染的風(fēng)險(xiǎn) —— 而不是盡快讓你的用戶可以使用該頁(yè)面。

注意,這種情況對(duì)第一次的訪問頁(yè)面時(shí)才會(huì)有。后續(xù)的頁(yè)面訪問不會(huì)受到 Service Worker 安裝的影響。一旦 Service Worker 在第一次訪問頁(yè)面時(shí)被激活,它就可以處理加載/緩存事件,以便后續(xù)訪問 Web 應(yīng)用程序。這一切都是有意義的,因?yàn)樗枰獪?zhǔn)備好處理受限的的網(wǎng)絡(luò)連接。

激活

安裝 Service Worker 之后,下一步將是激活它,這是處理舊緩存管理的好機(jī)會(huì)。

在激活步驟之后,Service Worker 將控制所有屬于其范圍的頁(yè)面,盡管第一次注冊(cè) Service Worker 的頁(yè)面將不會(huì)被控制,直到再次加載。

Service Worker 一旦掌控,它將處于以下兩種狀態(tài)之一:

  • 處理從網(wǎng)頁(yè)發(fā)出網(wǎng)絡(luò)請(qǐng)求或消息時(shí)發(fā)生的提取和消息事件

  • Service Worker 將被終止以節(jié)省內(nèi)存

Service Worker 生命周期如下:

JavaScript中Service Worker生命周期及使用場(chǎng)景的示例分析

Service Worker 安裝的內(nèi)部機(jī)制

在頁(yè)面啟動(dòng)注冊(cè)過程之后,看看 Service Worker 腳本中發(fā)生了什么,它通過向 Service Worker 實(shí)例添加事件監(jiān)聽來(lái)處理 install 事件:

以下是處理安裝事件時(shí)需要采取的步驟:

  • 開啟一個(gè)緩存

  • 緩存我們的文件

  • 確認(rèn)是否緩存了所有必需的資源

對(duì)于最基本的示例,你需要為安裝事件定義回調(diào)并決定要緩存哪些文件。

self.addEventListener('install', function(event) { // Perform install steps });

下面是 Service Worker 簡(jiǎn)單的一個(gè)內(nèi)部安裝過程:

JavaScript中Service Worker生命周期及使用場(chǎng)景的示例分析

從上例代碼可以得到:

調(diào)用了caches.open() 和我們想要的緩存名稱, 之后調(diào)用 cache.addAll() 并傳入文件數(shù)組。 這是一個(gè)promise 鏈( caches.open() 和 cache.addAll() )。 event.waitUntil() 方法接受一個(gè)承諾,并使用它來(lái)知道安裝需要多長(zhǎng)時(shí)間,以及它是否成功。

如果成功緩存了所有文件,那么將安裝 Service Worker。如果其中的一個(gè)文件下載失敗,那么安裝步驟將失敗。這意味著需要小心在安裝步驟中決定要緩存的文件列表,定義一長(zhǎng)串文件將增加一個(gè)文件可能無(wú)法緩存的機(jī)會(huì),導(dǎo)致你的  Service Worker 沒有得到安裝。

處理 install 事件完全是可選的,你可以避免它,在這種情況下,你不需要執(zhí)行這里的任何步驟。

運(yùn)行時(shí)緩存請(qǐng)求

安裝了 Service Worker 后,用戶導(dǎo)航到另一個(gè)頁(yè)面或刷新所在的頁(yè)面,Service Worker 將收到 fetch 事件。下面是一個(gè)例子,演示如何返回緩存的資源或執(zhí)行一個(gè)新的請(qǐng)求,然后緩存結(jié)果:

JavaScript中Service Worker生命周期及使用場(chǎng)景的示例分析

上述流程:

  • 在這里我們定義了 fetch 事件,在 event.respondWith() 中,我們傳遞了一個(gè)來(lái)自 caches.match()promise。 此方法查看請(qǐng)求,并查找來(lái)自 Service Worker 創(chuàng)建的任何緩存的任何緩存結(jié)果。

  • 如果在緩存中,響應(yīng)內(nèi)容就被恢復(fù)了。

  • 否則,將會(huì)執(zhí)行 fetch。

  • 檢查狀態(tài)碼是不是 200,同時(shí)檢查響應(yīng)類型是 basic,表明響應(yīng)來(lái)自我們最初的請(qǐng)求。在這種情況下,不會(huì)緩存對(duì)第三方資源的請(qǐng)求。

  • 響應(yīng)被緩存下來(lái)

如果通過檢查,克隆響應(yīng)。這是因?yàn)轫憫?yīng)是 Stream,所以只能消耗一次。既然要返回瀏覽器使用的響應(yīng),并將其傳遞給緩存使用,就需要克隆它,以便可以一個(gè)發(fā)送到瀏覽器,一個(gè)發(fā)送到緩存。

更新 Service Worker

當(dāng)用戶訪問你的 Web 應(yīng)用程序時(shí),瀏覽器試圖重新下載包含 Service Worker  代碼的 .js 文件,這是在后臺(tái)完成的。

如果現(xiàn)在下載的 Service Worker 的文件與當(dāng)前 Service Worker 的文件相比如果有一個(gè)字節(jié)及以上的差異,瀏覽器將假設(shè) Service Worker 文件已改過,瀏覽器就會(huì)啟動(dòng)新的 Service Worker。

新的 Service Worker 將啟動(dòng)并且安裝事件將被移除。然而,在這一點(diǎn)上,舊的 Service Worker 仍在控制你的 web 應(yīng)用的頁(yè)面,這意味著新的 Service Worker 將進(jìn)入 waiting 狀態(tài)。

一旦你的 Web 應(yīng)用程序當(dāng)前打開的頁(yè)面被關(guān)閉,舊的  Service Worker 將被瀏覽器殺死,新 Service Worker 接管了控制權(quán),它的激活事件將被激發(fā)

為什么需要這些?為了避免 Web 應(yīng)用程序的兩個(gè)版本同時(shí)在不同的 tab 上運(yùn)行的問題——這在 Web 上是非常常見的,并且可能會(huì)產(chǎn)生非常嚴(yán)重的bug(例如,在瀏覽器中本地存儲(chǔ)數(shù)據(jù)時(shí)使用不同的模式)。

從緩存中刪除數(shù)據(jù)

在激活回調(diào)中發(fā)生的一個(gè)常見任務(wù)是緩存管理。你要在激活回調(diào)中這樣做的原因是,如果你要在安裝步驟中清除所有舊的緩存,任何保留所有當(dāng)前頁(yè)面的舊 Service Worker 將會(huì)突然停止服務(wù)來(lái)自該緩存的文件。

這里提供了一個(gè)如何從緩存中刪除一些不在白名單中的文件的例子(在本例中,有 page-1、page-2 兩個(gè)實(shí)體):

JavaScript中Service Worker生命周期及使用場(chǎng)景的示例分析

要求 HTTPS 的原因

在構(gòu)建 Web 應(yīng)用程序時(shí),通過 localhost 使用 Service Workers,但是一旦將其部署到生產(chǎn)環(huán)境中,就需要準(zhǔn)備好 HTTPS( 這是使用HTTPS 的最后一個(gè)原因)。

使用  Service Worker,可以很容易被劫持連接并偽造響應(yīng)。如果不使用 HTTPs,人的web應(yīng)用程序就容易受到黑客的攻擊。

為了更安全,你需要在通過 HTTPS 提供的頁(yè)面上注冊(cè) Service Worker,以便知道瀏覽器接收的 Service Worker 在通過網(wǎng)絡(luò)傳輸時(shí)未被修改。

瀏覽器支持

瀏覽器對(duì) Service Worker 的支持正在變得越來(lái)越好:

JavaScript中Service Worker生命周期及使用場(chǎng)景的示例分析

Service Workers 特性將越來(lái)越完善及強(qiáng)大

Service Workers 提供的一些獨(dú)特特性包括:

  • 推送通知 —?允許用戶選擇從網(wǎng)絡(luò)應(yīng)用程序及時(shí)更新。

  • 后臺(tái)同步 — 允許延遲操作,直到用戶具有穩(wěn)定的連接。通過這種方式,可以確保用戶想發(fā)送的任何內(nèi)容實(shí)都可以發(fā)送。

  • 定期同步(后續(xù)開放) —  提供管理定期后臺(tái)同步功能的 API。

  • Geofencing (后續(xù)開放) —  可以定義參數(shù),也稱為圍繞感興趣領(lǐng)域的 geofences。當(dāng)設(shè)備通過geofence 時(shí),Web 應(yīng)用程序會(huì)收到一個(gè)通知,該通知允許根據(jù)用戶的地理位置提供更好的體驗(yàn)。

看完了這篇文章,相信你對(duì)“JavaScript中Service Worker生命周期及使用場(chǎng)景的示例分析”有了一定的了解,如果想了解更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI