Cách tích hợp Service Worker vào ứng dụng Next.js

Bạn quan tâm tới những ứng dụng web offline và muốn biết cách đạt được các cấp độ hiệu suất gần với chương trình gốc? Vậy thì không có gì tốt hơn service worker.

Dùng service worker trong Next.js

Service worker là các tập lệnh chạy trên nền để cung cấp những khả năng lưu bộ nhớ đệm mạnh mẽ cùng những tính năng khác cho ứng dụng web hiện đại.

Những tính năng này mang tới trải nghiệm ứng dụng gốc liền mạch và thân thiện người dùng cho trình duyệt web.

Service worker là thành phần cơ bản trong việc tạo Progressive Web Apps (PWAs).

Service worker là gì?

Service worker là một kiểu web worker JavaScriptchạy trên nền, tách biệt với luồng JavaScript chính để nó không bị chặn. Điều này có nghĩa nó không gây ra sự chậm trễ hay gián đoạn trên giao diện hoặc tương tác giữa người dùng với nó.

Service worker là gì?

Service worker hoạt động như proxy server - nằm giữa ứng dụng web và network. Chúng có thể chặn các truy vấn và phản hồi, lưu trữ tài nguyên và cung cấp hỗ trợ offline. Điều này giúp đảm bảo ứng dụng web mang tới sự liền mạch, thân thiện người dùng hơn, ngay cả khi họ không online.

Những ứng dụng chính cho service worker

Có một số ứng dụng dành cho service worker, bao gồm:

  • PWA: Service worker cung cấp sức mạnh tuyệt vời cho Progressive Web App. Chúng triển khai những truy vấn mạng tùy chỉnh, đẩy thông báo, hỗ trợ offline và tải nhanh.
  • Caching: Service worker có thể chứa các asset của ứng dụng - ảnh, code JavaScript, file CSS - trong bộ nhớ cache của trình duyệt. Điều này cho phép trình duyệt truy xuất chúng từ cache của nó, thay vì tìm nạp chúng ở server từ xa trên network. Kết quả, nội dung được tải nhanh hơn. Điều này đặc biệt hữu ích đối với người dùng có kết nối Internet chậm hay không đáng tin cậy.
  • Đồng bộ background: Service worker có thể đồng bộ hóa dữ liệu và chạy những nhiệm vụ trên nền khác, ngay cả khi người dùng không tích cực tương tác với ứng dụng hay khi ứng dụng không mở trong trình duyệt.

Tích hợp service worker trong ứng dụng Next.js

Trước khi đi sâu vào code, bạn cần bết cách service worker hoạt động. Sử dụng service worker có hai giai đoạn chính: registration activation.

Trong suốt giai đoạn đầu tiên, trình duyệt đăng ký service worker. Đây là một ví dụ:

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

registerServiceWorker();

Code này trước tiên sẽ kiểm tra xem liệu trình duyệt có hỗ trợ service worker, điều mà tất cả trình duyệt web hiện đại đều có. Nếu có hỗ trợ, nó tiến hành đăng ký một service worker nằm ở đường dẫn file được chỉ định.

Trong giai đoạn kích hoạt, bạn cần cài đặt và kích hoạt một service worker bằng cách lắng nghe sự kiện install activate qua trình lắng nghe sự kiện JavaScript. Đây là cách bạn có thể đạt được điều này:

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

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

Bạn có thể bao gồm code này ngay sau quá trình đăng ký. Nó sẽ chạy ngay sau khi quá trình đăng ký service worker thành công.

Tạo dự án Next.js

Để bắt đầu, chạy lệnh bên dưới để tạo dự án Next.js cục bộ:

npx create-next-app next-project

Thêm một service worker vào ứng dụng Next.js liên quan tới các bước sau:

  1. Đăng ký một service worker trong môi trường phạm vi toàn cục.
  2. Tạo một file JavaScript service worker trong thư mục chung.

Thêm service worker

Đầu tiên, đăng ký một service worker. Cập nhật file src/pages/_app.js như sau: Đưa code vào trong file đảm bảo service worker đăng ký khi ứng dụng tải và có quyền truy cập tới tất cả asset của ứng dụng.

import { useEffect } from 'react';

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

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

Hook useEffect kích hoạt khi thành phàn được gắn kết. Giống như ví dụ trước, code đầu tiên kiểm tra xem liệu trình duyệt của người dùng có hỗ trợ service worker.

Nếu có, nó đăng ký tập lệnh service worker nằm ở đường dẫn file cụ thể, và chỉ định phạm vi của nó là “/”. Điều này có nghĩa service worker đã kiểm soát toàn bộ tài nguyên trong ứng dụng. Bạn có thể cung cấp phạm vi chi tiết hơn nếu muốn, ví dụ: “/products”.

Nếu đăng ký thành công, nó ghi lại thông báo thành công, cùng với phạm vi của nó. Nếu có lỗi xảy ra trong quá trình đăng ký, code này sẽ bắt lỗi và ghi thông báo lỗi.

Cài đặt và kích hoạt service worker

Thêm code sau vào file mới, 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();

Để kiểm tra xem liệu service worker đã được đăng ký, cài đặt và kích hoạt thành công hay chưa, khởi động máy chủ lập trình & mở ứng dụng trong trình duyệt.

npm run dev

Mở cửa sổ Developer Tools của Chrome, điều hướng tới tab Application. Trong phần Service Workers, bạn sẽ thấy Service Worker đã đăng ký.

Service worker đã đăng ký

Với service worker đã đăng ký, cài đặt & kích hoạt thành công, bạn có thể triển khai một số hàm như lưu bộ nhớ đệm, đồng bộ background hoặc gửi thông báo đẩy.

Lưu trữ tài nguyên với service worker

Lưu trữ asset ứng dụng trên thiết bị người dùng có thể cải thiện hiệu suất bằng cách cho phép truy cập nhanh hơn, nhất là ở những tình huống có kết nối Internet không đáng tin cậy.

Để cache tài nguyên của ứng dụng, bao gồm code sau trong file 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;
        });
      });
    })
  );
});

Khi người dùng lần đầu truy cập trang chủ, code này kiểm tra xem liệu có phản hồi được lưu trữ cho truy vấn này trong cache. Nếu phản hồi được cache tồn tại, dịch vụ này trả nó về client.

Nếu không có phản hồi được lưu trữ tồn tại, service worker tìm nạp nguồn từ máy chủ trên mạng. Nó phản hồi tới client và lưu trữ nó cho những truy vấn sau này.

Để xem các tài nguyên đã lưu trữ, mở tab Application trong các công cụ lập trình. Ở phần Cache Storage, bạn sẽ thấy danh sách các tài nguyên đã lưu trữ. Bạn cũng có thể kiểm tra lựa chọn Offline trong Service Worker và tải lại trang cho trải nghiệm offline.

Kiểm tra cache

Giờ sau khi tới trang chủ, trình duyệt sẽ lưu trữ nguồn trong bộ nhớ cache thay vì cố gắng tạo truy vấn qua internet để tìm nạp dữ liệu.

Nhìn chung, service worker là một công cụ mạnh mẽ để nâng cao hiệu suất của ứng dụng tạo bằng Next.JS. Hi vọng bài viết sẽ giúp bạn biết cách dùng service worker hiệu quả trong app Next.js.

Thứ Bảy, 23/09/2023 14:46
51 👨 1.166
0 Bình luận
Sắp xếp theo