如何在 Next.js 应用程序中集成 Service Worker

Service Worker 是一種在背景執行的腳本,它為現代 Web 應用程式帶來強大的快取功能和其他優勢。

這些功能使網路瀏覽器能夠提供如原生應用程式般順暢且使用者友好的體驗。

Service Worker 是建立漸進式 Web 應用程式 (PWA) 的關鍵要素。

理解 Service Worker

Service Worker 是一種 JavaScript Web Worker,它在後台運行,與主 JavaScript 線程分離,因此是非阻塞的。這意味著它不會導致應用程式的使用者介面或使用者與之互動時產生延遲或中斷。

Service Worker 的作用類似於代理伺服器,它介於 Web 應用程式和網路之間。它們能夠攔截請求和響應、快取資源並提供離線支援。這有助於確保 Web 應用程式的體驗更加流暢和使用者友好,即使使用者處於離線狀態也能正常使用。

Service Worker 的主要應用

Service Worker 有多種應用場景。 其中包括:

  • PWA:Service Worker 為漸進式 Web 應用程式提供強大的功能。它們可以執行客製化的網路請求、推送通知、離線支援和快速載入。
  • 快取:Service Worker 可以將應用程式的資源(例如圖片、JavaScript 程式碼和 CSS 檔案)儲存在瀏覽器的快取儲存中。這樣一來,瀏覽器可以從快取中檢索這些資源,而無需透過網路從遠端伺服器獲取。因此,內容載入速度更快,對於網路連線速度慢或不穩定的使用者來說尤其重要。
  • 背景同步:即使使用者沒有積極地與應用程式互動,或是應用程式沒有在瀏覽器中開啟,Service Worker 仍然可以同步資料並執行其他背景任務。

在 Next.js 應用程式中整合 Service Worker

在深入探討程式碼之前,了解 Service Worker 的工作原理會很有幫助。使用 Service Worker 有兩個關鍵階段:註冊和啟動。

在第一階段,瀏覽器會註冊 Service Worker。以下是一個簡單的範例:

 const registerServiceWorker = async () => {
if ("serviceWorker" in navigator) {
registration = await navigator.serviceWorker.register("/sw.js");
}
};

registerServiceWorker();

這段程式碼首先檢查瀏覽器是否支援 Service Worker,而所有現代 Web 瀏覽器都已支援 Service Worker。如果支援存在,程式碼會繼續註冊位於指定檔案路徑的 Service Worker。

在啟動階段,你需要透過使用 JavaScript 事件監聽器來監聽安裝和啟動事件,從而安裝並啟動 Service Worker。以下是如何實現這一目標的方法:

 registration.addEventListener("install", () => {
console.log("Service worker installed");
});

registration.addEventListener("activate", () => {
console.log("Service worker activated");
});

你可以在註冊流程完成後立即新增這段程式碼。它應在 Service Worker 註冊流程成功後立即執行。

你可以在 GitHub 儲存庫中找到該專案的程式碼。

建立 Next.js 專案

首先,執行以下命令在本地建立 Next.js 專案:

 npx create-next-app next-project 

將 Service Worker 新增至 Next.js 應用程式需要以下步驟:

  • 在全域範圍環境中註冊一個 Service Worker。
  • 在 public 目錄中建立一個 Service Worker JavaScript 檔案。
  • 新增 Service Worker

    首先,註冊一個 Service Worker。按照以下方式更新 src/pages/_app.js 檔案。在此檔案中加入程式碼可確保 Service Worker 在應用程式載入時即註冊,並有權存取應用程式的所有資源。

     import { useEffect } from 'react';

    export default function App({ Component, pageProps }) {
    useEffect(() => {
    if ('serviceWorker' in navigator) {
    navigator.serviceWorker
    .register('/service-worker.js', { scope: "https://www.makeuseof.com/" })
    .then((registration) => {
    console.log(
    'Service worker registered successfully. Scope:',
    registration.scope
    );
    })
    .catch((error) => {
    console.error('Service worker registration failed:', error);
    });
    }
    }, []);

    return <Component {...pageProps} />;
    }

    useEffect Hook 會在元件掛載時觸發。與先前的範例一樣,程式碼首先檢查使用者的瀏覽器是否支援 Service Worker。

    如果支援存在,它會註冊位於指定檔案路徑的 Service Worker 腳本,並將其範圍設定為「/」。這表示 Service Worker 可以控制應用程式中的所有資源。如有需要,你可以提供更細緻的範圍,例如「/products」。

    如果註冊成功,它會記錄一則成功訊息及其範圍。如果註冊過程中發生錯誤,程式碼會捕獲錯誤並記錄錯誤訊息。

    安裝並啟動 Service Worker

    將以下程式碼新增至新的 public/service-worker.js 檔案中。

     const installEvent = () => {
    self.addEventListener('install', () => {
    console.log('service worker installed!!!!');
    });
    };

    installEvent();

    const activateEvent = () => {
    self.addEventListener('activate', () => {
    console.log('service worker activated!!!');
    });
    };

    activateEvent();

    若要測試 Service Worker 是否已成功註冊、安裝和啟動,請啟動開發伺服器並在瀏覽器中開啟你的應用程式。

     npm run dev 

    開啟 Chrome 的開發人員工具視窗(或瀏覽器的對等視窗),然後導覽至「應用程式」分頁。在 Service Workers 區段下,你會看到已註冊的 Service Worker。

    成功註冊、安裝和啟動 Service Worker 後,你就可以實作各種功能,例如快取、背景同步或傳送推播通知。

    使用 Service Worker 快取資源

    在使用者裝置上快取應用程式資源,可以透過允許更快的存取速度來提升效能,尤其是在網路連線不可靠的情況下。

    若要快取應用程式的資源,請在 service-worker.js 檔案中加入以下程式碼。

     const cacheName="test-cache";

    self.addEventListener('fetch', (event) => {
    event.respondWith(
    caches.match(event.request).then((cachedResponse) => {
    return cachedResponse || fetch(event.request).then((response) => {
    return caches.open(cacheName).then((cache) => {
    cache.put(event.request, response.clone());
    return response;
    });
    });
    })
    );
    });

    當使用者第一次造訪首頁時,這段程式碼會檢查快取中是否有針對該請求的快取響應。如果存在快取響應,服務將其返回給用戶端。

    如果沒有快取響應,Service Worker 將透過網路從伺服器取得資源。它會將響應提供給用戶端,並將其快取起來以供未來的請求使用。

    若要查看已快取的資源,請開啟開發人員工具中的「應用程式」分頁。在「快取儲存」區段下,你會看到已快取資源的清單。你也可以勾選 Service Worker 區段下的「離線」選項,然後重新載入頁面來模擬離線體驗。

    現在,當你造訪首頁時,瀏覽器會提供快取儲存中儲存的資源,而不是嘗試發出網路請求來取得資料。

    使用 Service Worker 來提升效能

    Service Worker 是增強 Next.js 應用程式效能的強大工具。它們可以快取資源、攔截請求並提供離線支援,所有這些都有助於改善使用者體驗。

    然而,值得注意的是,Service Worker 的實作和管理也可能很複雜。在使用 Service Worker 之前,仔細考慮它們的潛在優點和缺點非常重要。