[译] Service workers:PWA应用背后的英雄
寫在前面
- 作者:Flavio Copes
- 原文地址:Service workers: the little heroes behind Progressive Web Apps
- 說明:本人水平有限,在翻譯過程中難免有理解翻譯不準確的地方,為避免錯誤引導大家,希望能夠指,向大家傳遞正確的觀點和知識。
正文
Service workers是PWA應用的核心。它能夠緩存資源以及推送消息,這正是使原生應用與眾不同的最大的兩個特性。
一個service worker就是你的頁面和網絡之間的一個可編程代理,它提供了攔截和緩存網絡請求的能力。這種能力使得你可以為你的web應用創造一種離線體驗。
Service workers是一種特殊的web線程:與web頁面相關聯的一個JavaScript文件,該文件運行在一個worker上下文中,與主線程分開。這就帶來了一種非阻塞的好處-能夠使你的運算在不影響UI響應的情況下進行。
因為它是在一個獨立線程上的,所以沒有DOM訪問。它也不能訪問本地存儲API和XHR API。它只能通過通道消息傳遞API與主線程通信。
Service workers最近與其它的幾個web APIs合作:
- Promises
- Fetch API
- Cache API
它們只能在HTTPS協議的頁面上使用(除了本地請求,這些不需要安全連接。使得測試更加簡單)。 #### 后臺處理 Service workers獨立于與之關聯的應用程序運行,并且在不活動時可以接收消息。
例如,在以下這些情況下它也可以運行:
- 當您的移動應用程序處于后臺時,不活動
- 當您的移動應用程序關閉,甚至不運行在后臺
- 當瀏覽器關閉時,如果應用程序在瀏覽器中運行
Service workers發揮重要作用的場景:
- 它們可以作為緩存層來處理網絡請求,以及在脫機時使用的緩存內容。
- 它們可以推送消息。
一個Service worker只在需要時才運行,當不需要時就會停止。
支持離線
通常,web應用的離線體驗是非常差的。沒有網絡時,移動web應用直接停止工作。另一方面,原生應用能夠提供一個可工作版本或者一些非常好的信息。
這不是一個很好的消息,但是這是一個沒有網絡連接的Chrome網頁的樣子:
Service workers是離線緩存的新標準。
哪種緩存是可能的?
在安裝期間預緩存資源
在整個應用程序中能夠重用的資源,比如圖片、CSS、JS文件,能夠在應用打開的第一時間就被安裝。
這為App Shell架構提供了基礎。
緩存網絡請求
使用Fetch API,我們能夠編輯來自服務的響應,確定服務器是否可訪問,并從緩存中提供響應。
Service Worker的生命周期
一個Service Worker經過三步完成一個完整的功能:
- 注冊
- 安裝
- 激活
注冊
注冊就是告訴瀏覽器這個Service Worker在什么地方以及在后臺運行安裝。
比如,在worker.js中注冊一個Service Worker:
即使代碼被調用多次或者已經被更新了,那么如果這個Service Worker是新的,而且之前沒有被注冊過,瀏覽器將只執行注冊。
范圍
register()函數也將接受一個范圍參數,這個參數是個路徑決定了應用程序的哪一部分可以由Service Worker控制。
它默認包含在包Service Worker文件的文件夾中的所有文件和子文件夾,所以,如果你把它放到根文件中,它將控制整個應用。在子文件中,它將只控制這個路徑下的頁面。
下面的示例通過/notifications/文件夾范圍來注冊worker。
這個/是非常重要的:在這種情況下,頁面/notifications將不會觸發Service Worker,然而如果這個范圍是:
{ scope: '/notifications' } 復制代碼它就會奏效。
注意:Service Worker不能在一個文件中向外提升自己:如果它的文件放在/notifications下,它將不能控制/路徑或者其它任何不在/notifications文件內的路徑。 #### 安裝 如果瀏覽器確定Service Worker已經過時或從未注冊過,它將去安裝它:
這是一個很好的時機,可以讓Service Worker通過初始化緩存來使用。然后使用緩存API緩存應用程序Shell和靜態資源。
激活
一旦Service Worker被成功的注冊或安裝,第三步就是激活。
在這時候,Service Worker將會隨著新的頁面加載而開始工作。
它不能與已經加載的頁面交互,所以Service Worker只有在用戶第二次與應用程序交互或重新加載已經打開的頁面時才有用。
這個事件的一個很好的用例是清理舊的緩存和與舊版本相關的舊版本,這些舊版本在新版本的Service Worker中沒有使用。
更新一個Service Worker
要更新一個Service Worker,你只需要改變其中一個字節。當注冊的代碼運行的時候,它將被更新。
只要一個Service Worker被更新了,直到所有加載了舊Service Worker的頁面都被關閉,它才會出現。
這確保了不會在應用或者頁面已經運行的進程上出現任何問題。
刷新頁面是不夠的,舊的worker仍然在運行,它還沒有被移除。
請求事件
當一個資源在網絡上被請求時就觸發了一個請求事件。
這就讓我們在發起網絡請求時能夠查看緩存。
例如,下面的代碼片段使用緩存API來檢查所請求的URL是否已經存儲在緩存的響應中。如果已經緩存,就會返回緩存的響應。反之,它執行獲取請求并返回它。
后臺同步
后臺同步允許將傳出的連接延遲到用戶擁有一個工作網絡連接。
這是確保用戶能夠使用離線應用的關鍵,當連接打開時,隊列服務器端更新(而不是展示一個無休止的spinning wheel來試圖得到一個信號)。
下面的代碼在service worker中監聽事件。
self.addEventListener('sync', (event) => { if (event.tag == 'event1') { event.waitUntil(doSomething()) } }) 復制代碼doSomething()返回一個promise。如果失敗了,另一個同步事件將被安排自動重試,直到成功。
這也允許應用程序在有可用連接的情況下盡快更新服務器上的數據。
推送事件
在service worker允許web應用程序向用戶提供本機推送通知。
Push和Notifications是兩種不同的概念和技術,組合應用來實現我們所熟知的消息推送。Push提供了允許服務器向 service worker發送信息的機制,而Notifications是service worker向用戶顯示信息的方式。
因為service workers在應用停止的時候仍可以運行,它們可以監聽推送事件。接著向用戶顯示信息,并更新應用狀態。
推送事件是由一個后端發起,并通過瀏覽器推送服務。
下面是一個web worker如何偵聽傳入推送事件的示例:
關于控制臺日志的說明:
如果你在service worker中有任何控制臺消息,確保您打開了由Chrome Devtools提供的保存日志功能。
另外,因為service worker在加載頁面之前就開始操作了,并且控制臺在加載頁面之前將被清除,所以你講不能再輸出中看到任何日志。
總結
以上是生活随笔為你收集整理的[译] Service workers:PWA应用背后的英雄的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: leetcode 268. Missin
- 下一篇: 10进制与16进制之间的转换 delph