渐进式 Web 应用:离线

渐进式 Web 应用:离线

Informace o této programovací laboratoři

subjectNaposledy aktualizováno zář 18, 2024
account_circleNapsal zaměstnanec společnosti Google

1. 欢迎

在本实验中,您将使用一个现有的 Web 应用,并使其能够离线运行。这是渐进式 Web 应用研讨会的一系列配套 Codelab 中的第一个。本系列还有 7 个 Codelab。

学习内容

  • 手动编写 Service Worker
  • 向现有 Web 应用添加 Service Worker
  • 使用 Service Worker 和 Cache Storage API 使资源可离线使用

注意事项

  • HTML 和 JavaScript 基础知识

所需条件

2. 进行设置

首先,克隆或下载完成此 Codelab 所需的起始代码:

如果您克隆了代码库,请确保您位于 starter 分支中。该 ZIP 文件还包含相应分支的代码。

此代码库需要 Node.js 14 或更高版本。获得代码后,在代码的文件夹中通过命令行运行 npm ci,以安装所需的所有依赖项。然后,运行 npm start 以启动 Codelab 的开发服务器。

源代码的 README.md 文件提供了对所有分发文件的说明。此外,以下是您将在整个 Codelab 中使用的关键现有文件:

密钥文件

  • js/main.js - 主要应用 JavaScript 文件
  • service-worker.js - 应用的服务工作线程文件

3. 离线测试

在进行任何更改之前,我们先进行测试,以表明该 Web 应用目前无法离线运行。为此,您可以让计算机离线并重新加载 Web 应用,也可以执行以下操作(如果您使用的是 Chrome):

  1. 打开 Chrome 开发者工具
  2. 切换到“应用”标签页
  3. 切换到“Service Worker”部分
  4. 勾选“离线”复选框
  5. 刷新网页,但不关闭 Chrome 开发者工具

Chrome 开发者工具的“应用”标签页已打开,其中“服务工作线程”处于选中状态,“离线”复选框处于选中状态

在测试网站并成功使其无法离线加载后,接下来就可以添加一些在线功能了!取消选中“离线”复选框,然后继续执行下一步。

4. 下播后延续互动

现在,可以添加基本的服务工作线程了!此过程将分两步进行:注册 service worker 和缓存资源。

注册 Service Worker

我们已经有了一个空的 Service Worker 文件,因此为了确保更改生效,我们将在应用中注册该文件。为此,请将以下代码添加到 js/main.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 {
      // Capture the registration for later use, if needed
      let reg;

      // Use ES Module version of our Service Worker in development
      if (import.meta.env?.DEV) {
        reg = await navigator.serviceWorker.register('/service-worker.js', {
          type: 'module',
        });
      } else {
        // In production, use the normal service worker registration
        reg = await navigator.serviceWorker.register('/service-worker.js');
      }

      console.log('Service worker registered! 😎', reg);
    } catch (err) {
      console.log('😥 Service worker registration failed: ', err);
    }
  });
}

说明

此代码会在页面加载后注册空的 service-worker.js Service Worker 文件,前提是网站支持 Service Worker。

预缓存资源

为了让 Web 应用在离线状态下正常运行,浏览器需要能够响应网络请求并选择将这些请求路由到何处。为此,请将以下内容添加到 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);
    }),
  );
});

现在,返回浏览器,关闭预览标签页,然后重新打开。您应该会看到与 Service Worker 中的不同事件对应的 console.log

接下来,再次离线并刷新网站。您应该会看到,即使处于离线状态,该网页也会加载!

说明

在 service worker 的安装事件期间,使用 Cache Storage API 打开一个命名缓存。然后,使用 cache.addAll 方法将 precacheResources 中指定的文件和路由加载到缓存中。之所以称为“预缓存”,是因为它会在安装时预先缓存一组文件,而不是在需要或请求这些文件时再进行缓存。

一旦 service worker 控制了网站,所请求的资源就会像通过代理一样通过 service worker。每个请求都会触发一个提取事件,该事件会在相应服务工作线程中搜索缓存以查找匹配项,如果找到匹配项,则会使用缓存的资源进行响应。如果没有匹配项,则正常请求资源。

缓存资源可避免网络请求,从而使应用能够离线运行。现在,应用在离线时也能成功做出响应,并返回 200 状态代码!

5. 恭喜!

您已了解如何使用 Service Worker 和缓存存储 API 使 Web 应用离线运行。

本系列中的下一个 Codelab 是使用 Workbox