切換語言為:簡體
如何能讓網頁在網路不穩定或者斷網的情況下依然順暢執行

如何能讓網頁在網路不穩定或者斷網的情況下依然順暢執行

  • 爱糖宝
  • 2024-07-30
  • 2066
  • 0
  • 0

你是否曾經因為網路不穩定而苦惱?是否希望你的網頁在離線時依然能流暢執行?今天,我們將探討如何利用 Workbox 來最佳化你的 Service Worker,提升網頁效能,確保你的 Web 應用在任何環境下都能穩定執行。

如何能讓網頁在網路不穩定或者斷網的情況下依然順暢執行

目前您可能還用不到這篇文章,不過可以先收藏起來。希望將來它能為您提供所需的幫助!

🎈什麼是 Service Worker?

在深入瞭解 Workbox 之前,瞭解 Service Worker 的基礎知識是必要的。Service Worker是執行在瀏覽器背後的獨立執行緒,用於攔截和處理網路請求、管理快取和處理推送通知。它的主要目的是增強 Web 應用的離線體驗和效能。

Service Worker 在使用者訪問網頁時被安裝,並在後臺執行,能夠在不干擾主頁面的情況下執行任務。

Service Worker 的生命週期分為以下3個階段:

1、安裝(Install):當瀏覽器發現新的 Service Worker 指令碼時,會觸發 install 事件。在這個階段,開發者通常會快取應用的靜態資源。

self.addEventListener('install', event => {
    event.waitUntil(
        caches.open('my-cache').then(cache => {
            return cache.addAll([
                '/',
                '/index.html',
                '/styles.css',
                '/script.js'
            ]);
        })
    );
});


2、啟用(Activate):安裝完成後,Service Worker 會進入啟用階段。在這個階段,開發者可以清理舊的快取,確保新的快取策略生效。

self.addEventListener('activate', event => {
    event.waitUntil(
        caches.keys().then(cacheNames => {
            return Promise.all(
                cacheNames.map(cacheName => {
                    if (cacheName !== 'my-cache') {
                        return caches.delete(cacheName);
                    }
                })
            );
        })
    );
});


3、執行(Running):啟用後,Service Worker 進入執行狀態,開始攔截和處理網路請求。開發者可以透過 fetch 事件來控制請求的處理方式。

self.addEventListener('fetch', event => {
    event.respondWith(
        caches.match(event.request).then(response => {
            return response || fetch(event.request);
        })
    );
});


Service Worker主要應用於以下幾個場景:

  1. 離線支援:透過快取靜態資源和動態內容,確保應用在沒有網路連線時仍然可以使用。

  2. 快取管理:提高應用效能,透過快取減少網路請求次數和加快頁面載入速度。

  3. 推送通知:Service Worker 可以處理推送通知,即使使用者沒有開啟應用也能接收訊息。

手動編寫 Service Worker 也可以實現,但是過於複雜,現在有一款比較成熟 npm 庫 Workbox。

為什麼選擇 Workbox?🔥🔥

Workbox 功能強大特性

Workbox 是由 Google 開發的一組庫和工具,幫助開發者輕鬆地將 Service Worker 整合到他們的 Web 應用中。它簡化了快取管理和離線支援,使得 Web 應用能夠在沒有網路連線的情況下依然保持高效能和可靠性。

主要用途包括:

  • 簡化快取管理:透過預定義的策略自動處理資源的快取。

  • 提高效能:加快資源載入速度,減少伺服器負載。

  • 增強離線功能:確保應用在離線狀態下仍能正常執行。

  • 提供外掛與擴充套件:透過各種外掛輕鬆擴充套件功能,如背景同步、Google Analytics整合等。

與手動編寫 Service Worker 的對比,使用 Workbox,開發者只需配置即可,大大提升了開發效率。經過廣泛測試和社羣驗證,提供了高可靠性和效能最佳化的預設實現。

引入 Workbox(最簡單的方法)

引入 Workbox(最簡單的方法)可以透過以下幾個步驟完成。Workbox 是一個強大的庫,用於幫助開發人員簡化構建程序中的離線支援和快取策略。以下是最簡單的方法來引入 Workbox:

1. 使用 Workbox CLI

Workbox CLI 是最快速且簡單的方式來引入 Workbox 並生成 Service Worker 檔案。

  1. 安裝 Workbox CLI

    你需要全域性安裝 Workbox CLI 工具。開啟終端並執行以下命令:

    npm install -g workbox-cli
  2. 初始化 Workbox

    在你的專案根目錄下,執行以下命令來初始化 Workbox:

    workbox wizard

    這會引導你完成配置過程,並生成一個 workbox-config.js 檔案。

  3. 生成 Service Worker

    執行以下命令生成 Service Worker 檔案:

    workbox generateSW workbox-config.js

    這將建立一個 service-worker.js 檔案,你需要將它註冊到你的應用中。

  4. 註冊 Service Worker

    在你的應用入口檔案(例如 index.jsmain.js)中新增以下程式碼來註冊 Service Worker:

    if ('serviceWorker' in navigator) {
      window.addEventListener('load', () => {
        navigator.serviceWorker.register('/service-worker.js').then(registration => {
          console.log('SW registered: ', registration);
        }).catch(registrationError => {
          console.log('SW registration failed: ', registrationError);
        });
      });
    }

2. 使用 Workbox CDN

如果你不想使用 CLI 工具,你也可以直接透過 CDN 引入 Workbox:

  1. 在 HTML 檔案中新增 Workbox 的 CDN 連結

    在你的 HTML 檔案的 <head> 標籤中新增以下程式碼:

    <script src="https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-sw.js"></script>
  2. 建立和註冊 Service Worker

    建立一個 service-worker.js 檔案並新增以下程式碼:

    importScripts('https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-sw.js');
    
    workbox.precaching.precacheAndRoute(self.__WB_MANIFEST);

    然後在你的應用入口檔案中註冊這個 Service Worker:

    if ('serviceWorker' in navigator) {
      window.addEventListener('load', () => {
        navigator.serviceWorker.register('/service-worker.js').then(registration => {
          console.log('SW registered: ', registration);
        }).catch(registrationError => {
          console.log('SW registration failed: ', registrationError);
        });
      });
    }
  3. 使用 Workbox 外掛(可選)

    你可以根據需要新增其他 Workbox 外掛,例如快取策略:

    workbox.routing.registerRoute(
      ({request}) => request.destination === 'image',
      new workbox.strategies.CacheFirst({
        cacheName: 'images',
        plugins: [
          new workbox.expiration.ExpirationPlugin({
            maxEntries: 50,
            maxAgeSeconds: 30 * 24 * 60 * 60, // 30 天
          }),
        ],
      })
    );

Workbox配置

Workbox 預快取功能

workbox.precaching 物件提供了常用的預快取功能,其中最常用的方法是 workbox.precaching.precacheAndRoute。它的作用跟我們前面實現的 Precacher.precacheAndRoute() 的功能類似, 都是將傳入的資源列表進行預快取,同時對匹配到的預快取請求直接從本地快取中讀取並返回。

workbox.routing.precacheAndRoute([
  {
    url: '/index.html',
    revision: 'asdf'
  },
  '/index.abc.js',
  '/index.bcd.css'
])

Workbox 路由功能全面解析

Workbox 對資源請求匹配和對應的快取策略執行進行了統一管理,採用路由註冊的組織形式,以此來規範化動態快取。Workbox 提供了簡潔的 workbox.routing.registerRoute 方法來註冊路由,規範化動態快取操作。基本用法如下:

workbox.routing.registerRoute(match, handlerCb)

🐱路由匹配規則詳解

workbox.routing.registerRoute 的第一個引數 match 是路由匹配規則,支援以下幾種匹配模式:

  1. 字串匹配:對資源 URL 進行字串匹配。無論是完整 URL 還是相對路徑,都可以匹配到相應資源。

workbox.routing.registerRoute('http://127.0.0.1:8080/index.css', handlerCb)
workbox.routing.registerRoute('/index.css', handlerCb)
workbox.routing.registerRoute('./index.css', handlerCb)

例如,以上註冊的路由都能匹配到 http://127.0.0.1:8080/index.css

  1. 正則匹配:對資源 URL 進行正則匹配。

workbox.routing.registerRoute(//index.css$/, handlerCb)

這個規則可以匹配以下同域資源:

  • http://127.0.0.1:8080/index.css

  • http://127.0.0.1:8080/a/index.css

但無法匹配跨域資源。為匹配跨域資源需明確指定域名:

workbox.routing.registerRoute(
  /^https://third-party-site.com/.*/index.css$/,
  handlerCb
)
  1. 自定義方法匹配:根據需求實現複雜的資源請求匹配規則。

const match = ({url, event}) => {
  return url.pathname === '/index.html'
}

match 方法接收 urlevent 引數,其中 urlURL 類例項,eventfetch 事件回撥引數。

🐱資源請求處理方法

第二個引數 handlerCb 決定如何響應匹配到的請求,可以從網路、快取獲取資源或在 Service Worker 中直接生成響應。

const handlerCb = ({url, event, params}) => {
  return Promise.resolve(new Response('Hello World!'))
}

handlerCb 方法接收的物件包含以下屬性:

  • url:經過 URL 類例項化的 event.request.url

  • eventfetch 事件回撥引數。

  • params:自定義匹配方法返回的值。

注意handlerCb 必須是非同步函式,返回一個 Promise,該 Promise 的解析結果必須是一個 Response 物件。

Workbox 的路由功能透過統一管理資源請求匹配和快取策略,顯著提升了前端開發的效率和使用者體驗。

Workbox快取策略(🔥🔥核心點,非常重要)

Workbox 提供了一系列靈活且強大的快取策略,幫助開發者最佳化Web應用的效能。以下是幾種常用的快取策略以及它們的詳細說明和應用場景:

  • NetworkFirst:網路優先

  • CacheFirst:快取優先

  • NetworkOnly:僅使用正常的網路請求

  • CacheOnly:僅使用快取中的資源

  • StaleWhileRevalidate:從快取中讀取資源的同時傳送網路請求更新本地快取

const {NetworkFirst, CacheFirst, StaleWhileRevalidate} = workbox.strategies;

workbox.routing.registerRoute(/\api/, new workbox.strategies.NetworkFirst())

Stale-while-revalidate

當請求的路由有對應的 Cache 快取結果就直接返回,在返回 Cache 快取結果的同時會在後臺發起網路請求拿到請求結果並更新 Cache 快取,如果本來就沒有 Cache 快取的話,直接就發起網路請求並返回結果,這對使用者來說是一種非常安全的策略。

  1. 在第一次請求獲取資源時,從網路中提取資源,將其放入快取中並返回網路響應。

  2. 對於後續請求,首先從快取提供資源,然後“在後臺”從網路重新請求該資源,並更新資源的快取條目。

  3. 對於此後的請求,您將收到在上一步中從快取中放置的最後一個網路提取的版本。

如何能讓網頁在網路不穩定或者斷網的情況下依然順暢執行

Cache First

當匹配到請求之後直接從 Cache 快取中取得結果,如果 Cache 快取中沒有結果,那就會發起網路請求,拿到網路請求結果並將結果更新至 Cache 快取,並將結果返回給客戶端。這種策略比較適合結果不怎麼變動且對實時性要求不高的請求。

如何能讓網頁在網路不穩定或者斷網的情況下依然順暢執行

Network First

優先嚐試拿到網路請求的返回結果,如果拿到網路請求的結果,就將結果返回給客戶端並且寫入 Cache 快取,如果網路請求失敗,那最後被快取的 Cache 快取結果就會被返回到客戶端,這種策略一般適用於返回結果不太固定或對實時性有要求的請求,為網路請求失敗進行兜底。

如何能讓網頁在網路不穩定或者斷網的情況下依然順暢執行

Cache Only

始終從快取中獲取資源,不發起網路請求。

如何能讓網頁在網路不穩定或者斷網的情況下依然順暢執行

Network Only

始終從網路請求資源,不使用快取。

如何能讓網頁在網路不穩定或者斷網的情況下依然順暢執行

擴充套件延伸:Workbox自定義策略

在某些情況下,您可能希望使用自己的其他策略來響應請求,或者只是透過模板在 Service Worker 中生成請求。
為此可以提供一個非同步返回 Response 物件的函式 handler 。

const handler = async ({ url, event }) => {
  return new Response(`Custom handler response.`);
};

workbox.routing.registerRoute(new RegExp(matchString), handler);

需要注意的是,如果在 match 回撥中返回一個值,它將 handler 作為 params 引數傳遞到回撥中。

const match = ({ url, event }) => {
  if (url.pathname === '/example') {
    return {
      name: 'Workbox',
      type: 'guide',
    };
  }
};

const handler = async ({ url, event, params }) => {
  // Response will be "A guide to Workbox"
  return new Response(`A ${params.type} to ${params.name}`);
};

workbox.routing.registerRoute(match, handler);

如果 URL 中的某些資訊可以在 match 回撥中解析一次並在中使用,則這可能會對 handler 有所幫助。

總結

希望這篇文章對你理解使用 Workbox 功能有所幫助。如果你有任何疑問或見解,歡迎在評論區分享或提問,讓我們共同進步!

0則評論

您的電子郵件等資訊不會被公開,以下所有項目均必填

OK! You can skip this field.