服務人員教程

服務工作者是推動移動Web上的漸進Web應用程序發展的一項關鍵技術。它們允許緩存資源和推送通知,這是目前為止本機應用與眾不同的兩個主要區別功能

服務人員簡介

服務人員是漸進式Web應用,因為它們允許緩存資源和推送通知,這是目前為止本機應用與眾不同的兩個主要區別功能。

服務人員是可編程代理在網頁和網絡之間,有效地攔截和緩存網絡請求使您能夠為您的應用創建離線優先體驗

這是一種特殊的網絡工作者, 一種JavaScript與在工作線程上下文上運行的網頁相關聯的文件(與主線程分離)具有非阻塞性,因此可以在不犧牲UI響應性的情況下進行計算。

在單獨的線程上沒有DOM訪問,但無權訪問本地存儲API和XHRAPI,並且只能使用頻道訊息API

服務工作者與其他最新的Web API合作:

他們是僅在HTTPS上可用協議頁面(本地請求除外),這些頁面不需要安全連接即可進行更輕鬆的測試。

後台處理

服務工作者獨立於與其關聯的應用程序運行,並且在它們不活動時可以接收消息。

例如,它們可以工作:

  • 當您的移動應用程序是在後台, 不活躍
  • 當您的移動應用程序是關閉,因此即使沒有在後台運行
  • 什麼時候瀏覽器已關閉,如果應用程序正在瀏覽器中運行

服務工作者非常有用的主要方案是:

  • 它們可以用作緩存層處理網絡請求,並緩存脫機時要使用的內容
  • 允許推送通知

Service Worker僅在需要時運行,而在不使用時停止。

離線支援

傳統上,Web應用程序的脫機體驗非常差。沒有網絡,Web移動應用程序通常將無法運行,而本機移動應用程序可以提供工作版本或某種形式的精美消息。

這不是一個好消息,但這是沒有網絡連接的Chrome中的網頁外觀:

Offline support missing in service workers

唯一可能的好處是,您可以通過單擊恐龍來玩免費遊戲,但很快就會感到無聊。

Dinosaur game chrome

最近,HTML5 AppCache已經承諾允許Web應用程序緩存資源並脫機工作,但是由於缺乏靈活性和令人困惑的行為,很明顯它不能勝任這項工作,無法兌現承諾(並且它已經停產了)。

服務工作者是離線緩存的新標準。

哪種緩存是可能的?

在安裝過程中預緩存資產

可以在第一次打開應用程序時安裝可在整個應用程序中重複使用的資產,例如圖像,CSS,JavaScript文件。

這給出了所謂的App Shell架構

緩存網絡請求

使用提取API我們可以編輯來自服務器的響應,確定服務器是否無法訪問,並從緩存中提供響應。

服務人員生命週期

服務人員要通過3個步驟才能完全正常工作:

  • 登記
  • 安裝
  • 激活

登記

註冊會告訴瀏覽器服務器工作者的位置,並在後台啟動安裝。

註冊放置在其中的Service Worker的示例代碼worker.js

if ('serviceWorker' in navigator) {
  window.addEventListener('load', () => {
    navigator.serviceWorker.register('/worker.js')
    .then((registration) => {
      console.log('Service Worker registration completed with scope: ',
        registration.scope)
    }, (err) => {
      console.log('Service Worker registration failed', err)
    })
  })
} else {
  console.log('Service Workers not supported')
}

即使多次調用此代碼,瀏覽器也只會在服務工作者是新的,以前未註冊或已更新的情況下執行註冊。

範圍

register()調用還接受一個scope參數,該參數是確定服務工作者可以控制應用程序哪一部分的路徑。

它默認為包含服務工作者文件的文件夾中包含的所有文件和子文件夾,因此,如果將其放在根文件夾中,它將可以控制整個應用程序。在子文件夾中,它將僅控制在該路由下可訪問的頁面。

下面的示例通過指定/notifications/文件夾範圍。

navigator.serviceWorker.register('/worker.js', {
  scope: '/notifications/'
})

/很重要:在這種情況下,頁面/notifications如果範圍是

{
  scope: '/notifications'
}

它會工作的。

注意:服務工作者無法從文件夾“自身”升級:如果將其文件放在下面/notifications,它無法控制/路徑或不在下面的任何其他路徑/notifications

安裝

如果瀏覽器確定服務工作者已過時或之前從未註冊過,它將繼續進行安裝。

self.addEventListener('install', (event) => {
  //...
});

這是準備服務工作者使用的好事件,初始化緩存, 和緩存應用程序外殼和靜態資產使用緩存API

激活

一旦成功註冊並安裝了服務工作者,激活階段便是第三步。

此時,服務工作者將能夠處理新的頁面加載。

它無法與已加載的頁面進行交互,這意味著服務工作者僅在用戶第二次與應用程序進行交互或重新加載已打開的頁面之一時才有用。

self.addEventListener('activate', (event) => {
  //...
});

此事件的一個好用例是清除舊的緩存和與舊版本關聯但在服務工作者的新版本中未使用的內容。

更新服務人員

要更新Service Worker,您只需要在其中更改一個字節,並且在運行註冊碼時,它將對其進行更新。

更新Service Worker之後,直到關閉所有附加了舊Service Worker的頁面後,它才能變得可用。

這樣可以確保在已經運行的應用程序/頁面上沒有任何損壞。

刷新頁面是不夠的,因為舊的工作程序仍在運行並且尚未刪除。

取得事件

一種提取事件在網絡上請求資源時觸發。

這使我們能夠在緩存中查看在發出網絡請求之前。

例如,以下代碼段使用緩存API檢查請求URL是否已存儲在緩存的響應中,如果是這種情況,則返回緩存的響應。否則,它將執行獲取請求並返回它。

self.addEventListener('fetch', (event) => {
  event.respondWith(
    caches.match(event.request)
      .then((response) => {
        if (response) { //entry found in cache
          return response
        }
        return fetch(event.request)
      }
    )
  )
})

後台同步

後台同步允許將傳出連接推遲到用戶具有有效的網絡連接之前。

這是確保用戶可以脫機使用該應用程序並對其執行操作,並在連接打開時將服務器端更新排隊的關鍵,而不是顯示試圖獲取信號的無休止的紡車。

navigator.serviceWorker.ready.then((swRegistration) => {
  return swRegistration.sync.register('event1')
});

此代碼在Service Worker中偵聽該事件:

self.addEventListener('sync', (event) => {
  if (event.tag == 'event1') {
    event.waitUntil(doSomething())
  }
})

doSomething()返回承諾。如果失敗,則將安排另一個同步事件自動重試,直到成功。

這也允許應用程序在有可用的連接時立即從服務器更新數據。

推送事件

服務工作者可以通過以下方式使Web應用程序向用戶提供本機“推送通知”:

推送和通知實際上是兩種不同的概念和技術,但結合起來可以提供我們所知道的推送通知。推送提供了一種機制,該機制允許服務器將信息發送給服務人員,而通知是服務人員可以向用戶顯示信息的方式。

由於Service Worker即使在應用程序未運行時也可以運行,因此他們可以偵聽即將到來的推送事件,並提供用戶通知或更新應用程序的狀態。

推事件由後端通過瀏覽器推服務啟動,例如由火力基地

這是服務工作者如何偵聽傳入的推送事件的示例:

self.addEventListener('push', (event) => {
  console.log('Received a push event', event)

const options = { title: ‘I got a message for you!’, body: ‘Here is the body of the message’, icon: ‘/img/icon-192x192.png’, tag: ‘tag-for-this-notification’, }

event.waitUntil( self.registration.showNotification(title, options) ) })

關於控制台日誌的註釋

如果您有任何控制台日誌語句(console.log和朋友)在服務工作者中,請確保您打開了Preserve log提供的功能Chrome DevTools, 或同等學歷。

否則,由於服務工作者在加載頁面之前就執行了操作,並且在加載頁面之前已清除了控制台,因此在控制台中將看不到任何日誌。

免費下載我的JavaScript初學者手冊


更多瀏覽器教程: