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參數就是一個作用域,默認作用於當前站點

註冊成功

在這裏插入圖片描述

單純的註冊成功是沒有什麼用的,如何來緩存呢?這就需要我們依賴於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的緩存裏

在這裏插入圖片描述

測試一下

1、在不開啓service work的情況下訪問資源

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-gDHsQojh-1587817517699)(.\不適用work.jpg)]

2、使用service work訪問資源

在這裏插入圖片描述

結語

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

倉庫地址

參考鏈接

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章