Service Worker 淺析

引言

Progressive Web App, 簡稱 PWA,是提高 Web App 的體驗的一種新方法,能給用戶原生應用的體驗。Service Worker 是 PWA 中的重要一部分。Service Worker 能夠監聽當前域下的功能性事件,好比攔截和處理網絡請求、推送通知(push)、後臺同步(sync),今天咱們來了解一下 Service Workercss

什麼是 Service Worker

Service worker (簡稱 SW) 是一個註冊在指定源和路徑下的事件驅動 Worker。它採用 JavaScript 控制關聯的頁面或者網站,攔截並修改訪問和資源請求,細粒度地緩存資源。你能夠徹底控制應用在特定情形(最多見的情形是網絡不可用)下的表現。html

開始編寫一個簡單的 SW

註冊 Service Worker

首先,咱們經過 js 代碼調用瀏覽器的 api,註冊 SW,告訴瀏覽器 SW 文件的位置,Service Worker 支持 promise,因此寫起來很是方便git

// main.js
if (navigator.serviceWorker) {
  window.addEventListener('DOMContentLoaded', () => {
    navigator.serviceWorker
      .register('sw.js')
      .then(function(swReg) {
        console.log('sucess ~', swReg);
      })
      .catch(function(error) {
        console.error('fail !', error);
      })
  }) 
}

sw 存在做用域的概念,上面註冊的做用域爲 '/',若是註冊的 js 文件地址爲 'a/sw.js',則 sw 的做用域爲 '/a'github

開始緩存

接下來的代碼編寫主要集中在 sw.js (sw 加載的 js 文件) 文件中,在 Service Worker 安裝過程當中,咱們進行數據的緩存。緩存文件的重要角色是瀏覽器的 Cache API,將數據緩存下來。web

const cacheName = 'myCache'
const cacheArray = [
  '/index.html',
  '/index.css',
  '/main.js'
]

self.addEventListener('install', function(event) {
  // Perform install steps
  event.waitUntil(
    // 打開一個 Cache 對象
    caches.open(CACHE_NAME)
      .then(function(cache) {
        // 緩存數組中的內容
        return cache.addAll(urlsToCache);
      })
  )
})
由於一個 Worker是使用一個構造函數建立的一個對象運行一個命名的JavaScript文件。這個文件包含將在工做線程中運行的代碼,運行在另外一個全局上下文中,不一樣於當前的window。在 sw.js 中,沒法使用 window、操做 DOM 等,使用 self 關鍵字,來實引用 DedicatedWorkerGlobalScope

若是全部文件都成功緩存,則將安裝 Service Worker。 若有任何文件沒法下載,則安裝步驟將失敗。也意味着 Service Worker 啓動失敗api

event.waitUntil 確保瀏覽器關閉也仍然可以執行數組

緩存和代理請求

Service Worker 可以實現離線功能,主要是擁有代理請求的功能,咱們可以在請求的時候有本身的操做空間,請求優先,請求失敗從 Cache 讀取緩存;請求成功,更新緩存。promise

self.addEventListener('fetch', (event) => {
  if (event.request.mode === 'navigate') {
    return event.respondWith(
      fetch(event.request).catch(() =>                            
      caches.match(OFFLINE_URL))
    )
  }
})
event.respondWith

接收推送消息

在 sw.js 的內部經過事件監聽的方式執行對應的回調函數,接收外部的推送信息,只須要添加 push 事件監聽便可瀏覽器

self.addEventListener('push', function(event) {
  const options = {
    body: 'Yay it works.',
    icon: 'images/icon.png',
    badge: 'images/badge.png'
  }

  self.registration.showNotification(title, options);
})
消息推送,配合 Web Server For Chrome 更方便~

開啓後臺同步功能

在瀏覽器無網絡請狀況下,服務端推送消息,瀏覽器沒法接收到,可是當網絡連通時,瀏覽器就能夠接收到服務端推送的信息。瀏覽器的請求也能夠實現一樣的功能,經過特殊的方式發送請求,網絡連通時,請求才會發出去。緩存

// 請求
navigator.serviceWorker.ready.then((registration) => {
  // 區分不一樣的事件
  const tag = 'tag';
  registration.sync.register(tag).then(() => {
    // do something...
  })
})

// 事件監聽
// sw.js
self.addEventListener('sync', function (e) {
  console.log(e.tag === 'tag')  // true
  e.waitUntil(...)
})

工做週期

Service Worker 生命週期

圖片來源,侵刪

  • 初始化階段: 頁面加載、解析 Service Worker 的 js 文件
  • 安裝階段: 安裝 Service Worker ,一般在安裝中執行緩存
  • 工做階段:監聽各類事件,執行工做
  • 待機階段:網頁關閉,Service Worker 在瀏覽器處於"靜默"的狀態,有事件同送等從新開始,隨後再次"靜默"
  • 更新階段:新的 sw 觸發 install 事件,舊的 sw 出發 activate 事件

Firebase 雲信息傳遞 (FCM)

Firebase 雲信息傳遞 (FCM) 是一種跨平臺消息傳遞解決方案,可供您免費、可靠地傳遞消息。能夠發送通知消息以再次吸引用戶並留住他們。在即時通信等使用情形中,一條消息可將最多 4KB 的有效負載傳送至客戶端應用。

瀏覽器的 Service Worker 的消息推送主要依賴 FCM,服務端消息推送傳遞到 FCM,而後再由 FCM 推送到客戶端。

傳動門

參考連接:

相關文章
相關標籤/搜索