天天看點

Service Work簡介

什麼是Service Work

author: 果果 data:2020.04.25 15:50

背景
随着web的快速發展,使用者對于站點的體驗期望也是越來越來高,作為一個前端工程師,就必須為性能的提高而耗費心
思;CDN、CSS Sprite、檔案的合并壓縮、異步加載、資源緩存等方式的目的就是減少使用者的感覺,提高使用者的體驗;
           
service work
衆所周知,浏覽器中的js都是運作在單一主線程上的,在同一時間内隻能做一件事情。這個時候web work出現了,它是
獨立于主線程之外的,但是它是臨時的,最後service work來了,我們來看一下她有哪些功能和特性;
一個獨立的 worker 線程,獨立于目前網頁程序,有自己獨立的 worker context。
1、一旦被 install,就永遠存在,除非被手動 unregister
2、用到的時候可以直接喚醒,不用的時候自動睡眠
3、可程式設計攔截代理請求和傳回,緩存檔案,緩存的檔案可以被網頁程序取到(包括網絡離線狀态)
4、離線内容開發者可控
5、能向用戶端推送消息
6、不能直接操作 DOM
7、必須在 HTTPS 環境下才能工作
8、異步實作,内部大都是通過 Promise 實作
           

一塊來大展身手

1、必須是https環境,本地調試localhost或者127.0.0.1環境也是可以的,
2、依賴于cache api進行實作的
3、依賴于h5的fetch Api
4、依賴于promise進行實作
           
注冊service
if ('serviceWorker' in navigator) {
    window.addEventListener('load', function () {
        const sw = navigator.serviceWorker;
        sw.register('/pwa/sw.js', {scope: '/pwa/'})
    	.then(function (registration) {
            // 注冊成功
            console.log('ServiceWorker registration successful with scope: ', registration);
                })
        .catch(function (err) {
            // 注冊失敗
            console.log('ServiceWorker registration failed: ', err);
        }); 
    });
 }
           

1、先判斷浏覽器是否支援sw,否則就免談了,

2、在頁面load時候,注冊./sw.js的service work,頁面每次加載都會注冊,浏覽器會根據注冊情況作出相應的處理

3、scope參數就是一個作用域,預設作用于目前站點

注冊成功
Service Work簡介
單純的注冊成功是沒有什麼用的,如何來緩存呢?這就需要我們依賴于cache來進行緩存了
console.log('******************sw.js**************************')
const version = 1;
const cacheStorageKey = "testCache-" + version;

// 這是需要預緩存的資源,也可以是appshell,可以通過webpack的插件來生成
const cacheList = ["/", "index.html", 'data.json'];

// 注冊成功的時候,以版本名為key主動緩存靜态資源
console.log(self)
self.addEventListener("install", function(e) {
  console.log("Cache event!");
  e.waitUntil(
    caches.open(cacheStorageKey).then(function(cache) {
      console.log("Adding to Cache:", cacheList);
      return cache.addAll(cacheList);
    })
    .then(function() {
      // 注冊成功跳過等待,酌情處理
      // console.log('Skip waiting!')
      // return self.skipWaiting()
    })
  );
});

// 當新的serviceWorker被激活時,删除舊版本的緩存
self.addEventListener("activate", event => {
  console.log("Activate event");
  event.waitUntil(
    caches
      .keys()
      .then(cacheNames => {
        return cacheNames.filter(cacheName => cacheStorageKey !== cacheName);
      })
      .then(cachesToDelete => {
        return Promise.all(
          cachesToDelete.map(cacheToDelete => {
            return caches.delete(cacheToDelete);
          })
        );
      })
      .then(() => {
        console.log("Clients claims.");
        // 立即接管所有頁面,酌情處理
        // 會導緻新的sw接管舊的頁面,同時舊版本的緩存已被清空
        self.clients.claim();
      })
  );
});

// 發起請求時去根據uri去比對緩存,無法命中緩存則發起請求
self.addEventListener("fetch", function(e) {
  e.respondWith(
    caches.match(e.request).then(function(response) {
      return response || fetch(e.request);
    })
  );
});

self.addEventListener("message", event => {
  if (event.data === "skipWaiting") {
    console.log("Skip waiting!");
    self.skipWaiting();
  }
});
           
我們緩存的資源都在哪裡了呢?都在cache的緩存裡
Service Work簡介

測試一下

1、在不開啟service work的情況下通路資源

Service Work簡介

2、使用service work通路資源

Service Work簡介

結語

技術交流,共同進步,歡迎fork和star!
           

倉庫位址

參考連結

繼續閱讀