Ứng dụng web tiến bộ: Chuyển sang chế độ ngoại tuyến

1. Chào mừng

Trong phòng thí nghiệm này, bạn sẽ lấy một ứng dụng web hiện có và làm cho ứng dụng đó hoạt động ngoại tuyến. Đây là chương trình đầu tiên trong chuỗi các lớp học lập trình đồng hành cho hội thảo Ứng dụng web tiến bộ. Có thêm 7 lớp học lập trình khác trong chuỗi này.

Kiến thức bạn sẽ học được

  • Tự viết một Trình chạy dịch vụ
  • Thêm Trình chạy dịch vụ vào ứng dụng web hiện có
  • Sử dụng Trình chạy dịch vụ và API Bộ nhớ đệm để đặt các tài nguyên ở chế độ có thể sử dụng khi không có mạng

Những điều bạn cần biết

  • HTML và JavaScript cơ bản

Bạn cần có

2. Thiết lập

Hãy bắt đầu bằng cách sao chép hoặc tải mã dành cho người mới bắt đầu xuống để hoàn tất lớp học lập trình này:

Nếu bạn sao chép kho lưu trữ, hãy đảm bảo bạn đang ở trên nhánh starter. Tệp zip cũng chứa mã cho chi nhánh đó.

Cơ sở mã này yêu cầu Node.js 14 trở lên. Sau khi có mã, hãy chạy npm ci từ dòng lệnh trong thư mục của mã để cài đặt tất cả các phần phụ thuộc mà bạn cần. Sau đó, chạy npm start để khởi động máy chủ phát triển cho lớp học lập trình.

Tệp README.md của mã nguồn cung cấp nội dung giải thích cho tất cả tệp được phân phối. Ngoài ra, sau đây là các tệp chính hiện có mà bạn sẽ làm việc với trong suốt lớp học lập trình này:

Tệp khóa

  • js/main.js – Tệp JavaScript của ứng dụng chính
  • service-worker.js - Tệp trình chạy dịch vụ của ứng dụng

3. Kiểm tra ngoại tuyến

Trước khi thực hiện bất kỳ thay đổi nào, hãy kiểm tra để cho thấy rằng ứng dụng web hiện không hoạt động khi không có mạng. Để thực hiện việc này, hãy đưa máy tính của chúng tôi ngoại tuyến rồi tải lại ứng dụng web, hoặc nếu bạn đang sử dụng Chrome:

  1. Mở Công cụ dành cho nhà phát triển Chrome
  2. Chuyển sang thẻ Ứng dụng
  3. Chuyển sang phần Trình chạy dịch vụ
  4. Đánh dấu vào hộp Ngoại tuyến
  5. Làm mới trang mà không cần đóng Công cụ dành cho nhà phát triển Chrome

Đã mở thẻ Ứng dụng công cụ của Chrome Dev cho nhân viên dịch vụ và đánh dấu vào hộp Ngoại tuyến

Khi trang web được thử nghiệm thành công và không tải được khi không có mạng, đã đến lúc thêm một số chức năng trực tuyến! Bỏ đánh dấu hộp đánh dấu ngoại tuyến và tiếp tục thực hiện bước tiếp theo.

4. Không cần mạng

Đã đến lúc thêm một trình chạy dịch vụ cơ bản! Quá trình này sẽ diễn ra theo hai bước: đăng ký trình chạy dịch vụ và tài nguyên lưu vào bộ nhớ đệm.

Đăng ký Worker Worker

Đã có tệp trình chạy dịch vụ trống. Vì vậy, để đảm bảo các thay đổi xuất hiện, hãy đăng ký ứng dụng đó trong ứng dụng của chúng tôi. Để làm như vậy, hãy thêm mã sau vào đầu js/main.js:

import swURL from 'sw:../service-worker.js';

// Register the service worker
if ('serviceWorker' in navigator) {
  // Wait for the 'load' event to not block other work
  window.addEventListener('load', async () => {
    // Try to register the service worker.
    try {
      const reg = await navigator.serviceWorker.register(swURL);
      console.log('Service worker registered! 😎', reg);
    } catch (err) {
      console.log('😥 Service worker registration failed: ', err);
    }
  });
}

Giải thích

Mã này sẽ đăng ký tệp trình chạy dịch vụ service-worker.js trống khi trang đã tải và chỉ khi trang web hỗ trợ trình chạy dịch vụ.

Lưu trước tài nguyên

Để ứng dụng web hoạt động khi không có mạng, trình duyệt cần phải phản hồi các yêu cầu mạng và chọn nơi định tuyến các yêu cầu đó. Để làm như vậy, hãy thêm mục sau vào service-worker.js

// Choose a cache name
const cacheName = 'cache-v1';
// List the files to precache
const precacheResources = ['/', '/index.html', '/css/style.css', '/js/main.js', '/js/app/editor.js', '/js/lib/actions.js'];

// When the service worker is installing, open the cache and add the precache resources to it
self.addEventListener('install', (event) => {
  console.log('Service worker install event!');
  event.waitUntil(caches.open(cacheName).then((cache) => cache.addAll(precacheResources)));
});

self.addEventListener('activate', (event) => {
  console.log('Service worker activate event!');
});

// When there's an incoming fetch request, try and respond with a precached resource, otherwise fall back to the network
self.addEventListener('fetch', (event) => {
  console.log('Fetch intercepted for:', event.request.url);
  event.respondWith(
    caches.match(event.request).then((cachedResponse) => {
      if (cachedResponse) {
        return cachedResponse;
      }
      return fetch(event.request);
    }),
  );
});

Bây giờ, hãy quay lại trình duyệt, đóng thẻ xem trước rồi mở lại thẻ. Bạn sẽ thấy console.log tương ứng với các sự kiện khác nhau trong trình chạy dịch vụ!

Tiếp theo, hãy ngoại tuyến lần nữa và làm mới trang web. Bạn sẽ thấy thanh này tải mặc dù bạn đang ngoại tuyến!

Giải thích

Trong sự kiện cài đặt của trình chạy dịch vụ, bộ nhớ đệm đã đặt tên được mở bằng API Bộ nhớ đệm. Các tệp và tuyến đường được chỉ định trong precacheResources sau đó được tải vào bộ nhớ đệm bằng cách sử dụng phương thức cache.addAll. Quá trình này gọi là tìm nạp trước vì bộ nhớ đệm này lưu trước bộ nhớ đệm trong tập hợp các tệp trong thời gian cài đặt thay vì được lưu vào bộ nhớ đệm khi cần và được yêu cầu.

Khi trình chạy dịch vụ đang kiểm soát trang web, các tài nguyên được yêu cầu sẽ chuyển qua trình chạy dịch vụ, chẳng hạn như proxy. Mỗi yêu cầu kích hoạt một sự kiện tìm nạp, trong trình chạy dịch vụ này, tìm kiếm một bộ nhớ đệm cho một kết quả trùng khớp, nếu có kết quả trùng khớp, sẽ phản hồi bằng tài nguyên trong bộ nhớ đệm. Nếu không khớp, tài nguyên sẽ được yêu cầu bình thường.

Tài nguyên lưu vào bộ nhớ đệm cho phép ứng dụng hoạt động khi không có mạng bằng cách tránh các yêu cầu mạng. Giờ đây, ứng dụng có thể phản hồi bằng mã trạng thái 200 khi không có mạng!

5. Xin chúc mừng!

Bạn đã tìm hiểu cách đưa ứng dụng web ngoại tuyến bằng trình chạy dịch vụ và API bộ nhớ đệm.

Lớp học lập trình tiếp theo trong chuỗi bài học là Làm việc với Workbox