重識 PWA 進階到 workbox3


看到PWA,似曾相識,但又感覺很模糊,於是乎,又重新翻閱文檔,學習了一遍,順便把相關知識學習了一下,比如service worker,workbox3

PWA 概念:

全稱:Progressive Web APP, 漸進式 Web 應用。

實際上是通過 Web 技術編寫出的一個網頁應用,加上App ManifestService Worker來實現PWA的安裝和離線緩存等功能。

解決了哪些問題?

  • 可以添加至主屏幕,點擊主屏幕圖標可以實現啟動動畫及隱藏地址欄
  • 實現離線緩存功能
  • 實現了消息推送

PWA 的實現-Manifest 實現添加至主屏幕

首先在index.htmlhead中引入manifest.json文件,盡可能早的引入

<head>
    ...
    <meta name="viewport" content="width=device-width, user-scalable=no" />
    <link rel="manifest" href="manifest.json">
    <link rel="stylesheet" type="text/css" href="main.css">
    ...
</head>

然后編寫manifest.json文件,參考文檔:https://developer.mozilla.org/zh-CN/docs/Web/Manifest

{
  "name": "Minimal PWA", // 必填 顯示的插件名稱
  "short_name": "PWA Demo", // 可選  在APP launcher和新的tab頁顯示,如果沒有設置,則使用name
  "description": "The app that helps you understand PWA", //用於描述應用
  "display": "standalone", // 定義開發人員對Web應用程序的首選顯示模式。standalone模式會有單獨的
  "start_url": "/", // 應用啟動時的url
  "theme_color": "#313131", // 桌面圖標的背景色
  "background_color": "#313131", // 為web應用程序預定義的背景顏色。在啟動web應用程序和加載應用程序的內容之間創建了一個平滑的過渡。
  "icons": [ // 桌面圖標,是一個數組
    {
    "src": "icon/lowres.webp",
    "sizes": "48x48",  // 以空格分隔的圖片尺寸
    "type": "image/webp"  // 幫助userAgent快速排除不支持的類型
  },
  {
    "src": "icon/lowres",
    "sizes": "48x48"
  },
  {
    "src": "icon/hd_hi.ico",
    "sizes": "72x72 96x96 128x128 256x256"
  },
  {
    "src": "icon/hd_hi.svg",
    "sizes": "72x72"
  }
  ]
}

PWA的實現-Service Worker 實現離線緩存

Service worker,是 Chrome 團隊提出和力推的一個 WEB API,就像介於服務器和網頁之間的攔截器,能夠攔截進出的http請求,從而完全控制你的網站。

最主要的特點:

  • 在頁面中注冊並安裝成功后,運行於瀏覽器后台,不受頁面刷新的影響,可以監聽和攔截作用域范圍內所有頁面的 HTTP 請求。
  • 網站必須使用 HTTPS,處於安全考慮,避免被攻擊。除了使用貝蒂開發環境調試。
  • 運行於瀏覽器后台,可以控制打開的作用域范圍下所有的頁面請求
  • 單獨的作用域范圍,單獨的運行環境和執行線程
  • 不能操作頁面 DOM ,但是可以通過事件機制來處理
  • 事件驅動型服務線程

瀏覽器支持情況:

生命周期

解析成功(parsed)、正在安裝(installing)、安裝整個(installed)、正在激活(activating)、激活成功(activated)、廢棄(redundant)

若 installing 事件失敗或 activeing 事件失敗,service worker 都會被廢棄。

實現離線緩存

首先在index.html中注冊sw.js

<script async src="/js/script.js"></script>     
<script>
  // 注冊 service worker
  if ('serviceWorker' in navigator) {           
    navigator.serviceWorker.register('/sw.js', {scope: '/'}).then(function (registration) {
      // 注冊成功
      console.log('ServiceWorker registration successful with scope: ', registration.scope);
    }).catch(function (err) {                   
      // 注冊失敗 :(
      console.log('ServiceWorker registration failed: ', err);
    });
  }
</script>

編寫sw.js

var cacheStorageKey = 'cachesName'
var cacheList = [
  // 注冊成功后要立即緩存的資源列表
]

// 當瀏覽器解析完sw文件時觸發install事件
self.addEventListener('install', function(e) {
  // install事件中一般會將cacheList中要換存的內容通過addAll方法,拉一遍放入caches中
  e.waitUntil(
    caches.open(cacheStorageKey).then(function(cache) {
      return cache.addAll(cacheList)
    })
  )
})

// 激活時觸發activate事件
self.addEventListener('activate', function(e) {
  // active事件中通常做一些過期資源釋放的工作,匹配到就從caches中刪除
  var cacheDeletePromises = caches.keys().then(cacheNames => {
    return Promise.all(cacheNames.map(name => {
      if (name !== cacheStorageKey) {
        return caches.delete(name);
      } else {
        return Promise.resolve();
      }
    }));
  });

  e.waitUntil(
    Promise.all([cacheDeletePromises])
  )
})

self.addEventListener('fetch', function(e) {
  // 在此編寫緩存策略, 需要根據不同文件的擴展名把不同的資源通過不同的策略緩存在caches中,各種css,js,html,圖片,都需要單獨搞一套緩存策略

  e.respondWith(
    // 可以通過匹配緩存中的資源返回
    caches.match(e.request)
    // 也可以從遠端拉取
    fetch(e.request.url)
    // 也可以自己造
    new Response('自己造')
    // 也可以通過吧fetch拿到的響應通過caches.put方法放進chches
  )
})

workbox3

workbox3,Google官方 PWA 框架,解決的就是 Service Worker 編寫太過復雜的問題。

// 首先引入workbox框架
importScripts('https://storage.googleapis.com/workbox-cdn/releases/3.3.0/workbox-sw.js');

workbox.precaching([
  // 注冊成功后要立即緩存的資源列表
])

// 緩存策略: networkFirst、cacheFirst、staleWhileRevalidate
workbox.routing.registerRoute(
  new RegExp(''.*\.html'),
  workbox.strategies.networkFirst()
);

workbox.routing.registerRoute(
  new RegExp('.*\.(?:js|css)'),
  workbox.strategies.cacheFirst()
);

workbox.routing.registerRoute(
  new RegExp('https://your\.cdn\.com/'),
  workbox.strategies.staleWhileRevalidate()
);

生成緩存策略,可以采用workbox-build npm 包或者workbox-webpack-plugin方式自動生成。

緩存策略:

  • stateWhileRevalidate:當請求的路由有對應的 Cache 緩存結果就直接返回,在返回 Cache 緩存結果的同時會在后台發起網絡請求拿到請求結果並更新 Cache 緩存,如果本來就沒有 Cache 緩存的話,直接就發起網絡請求並返回結果,這對用戶來說是一種非常安全的策略
  • networkFirst:當請求路由是被匹配的,就采用網絡優先的策略,也就是優先嘗試拿到網絡請求的返回結果,如果拿到網絡請求的結果,就將結果返回給客戶端並且寫入 Cache 緩存,如果網絡請求失敗,那最后被緩存的 Cache 緩存結果就會被返回到客戶端,這種策略一般適用於返回結果不太固定或對實時性有要求的請求,為網絡請求失敗進行兜底。
  • cacheFirst:當匹配到請求之后直接從 Cache 緩存中取得結果,如果 Cache 緩存中沒有結果,那就會發起網絡請求,拿到網絡請求結果並將結果更新至 Cache 緩存,並將結果返回給客戶端。這種策略比較適合結果不怎么變動且對實時性要求不高的請求
  • networkOnly:強制使用正常的網絡請求,並將結果返回給客戶端,這種策略比較適合對實時性要求非常高的請求。
  • cacheOnly:直接使用 Cache 緩存的結果,並將結果返回給客戶端,這種策略比較適合一上線就不會變的靜態資源請求。
  • 如果以上策略都不滿足需求,還可以自定義策略

參考文檔

  • 講講PWA
    • 背景
    • What's PWA?
    • PWA的實現
      • Manifest實現添加至主屏幕
      • service worker實現離線緩存
      • serice worker實現消息推送
    • 總結:PWA的優勢和存在的問題
    • 參考文檔
  • Vue筆記九:pwa技術在vue的使用(workbox/sw-precache)
    • 歷史背景
    • sw-precache 和 workbox
    • 緩存機制
    • 安全性
  • Workbox 3.0 – Web 站點輕松做到離線可訪問
    • 概述
    • 用法
    • precache (預緩存)靜態文件
    • 處理/和/index.html
    • 忽略請求參數
    • 生成預緩存列表
      • workbox 命令行
      • workbox-build npm 包
      • workbox-webpack-plugin
    • 路由請求緩存
      • 字符串方式
      • 正則表達式fangs
      • 回調函數方式
    • 路由請求緩存策略
      • state while revalidate
      • network first
      • cache first
      • network only
      • cache only
    • 自定義策略
    • 第三方請求的緩存
    • workbox 配置
      • 配置緩存名稱
      • 指定 development 環境
      • 配置日志 level: debug、log、warning、error
    • workbox 插件
    • 自定義插件
    • webpack 中使用 workbox 實現 PWA
  • Workbox3 - ServiceWorker可以如此簡單
    • 科普ServiceWorker
    • 一個完整的ServiceWorker
    • workbox3
    • 經驗之談
  • Service Worker 生命周期
    • 解析成功(parsed)、正在安裝(installing)、安裝整個(installed)、正在激活(activating)、激活成功(activated)、廢棄(redundant)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM