对 Chrome 71 中的 cache.addAll() 和 importScripts() 进行了调整

使用服务工作器Cache Storage API 的开发者应留意以下两项 Chrome 71 中即将推出的一些小更改。这两项变更都使 Chrome 的实现方式与 规范和其他浏览器。

禁止使用异步 importScripts()

importScripts() 会指示主 Service Worker 脚本暂停其当前执行,从 指定网址,并在当前全局范围下运行该网址以完成操作。完成上述操作后 主 Service Worker 脚本继续执行。importScripts() 可以派上用场 出于组织方面的原因,您需要把主 Service Worker 脚本分成小段,或者 提取第三方代码来向 Service Worker 添加功能。

浏览器会尝试缓解“下载并运行某些同步文件”可能带来的性能问题, 代码”可以自动缓存通过 importScripts() 提取的任何内容,这意味着在 初始下载,执行导入的代码所需的开销很小。

不过,要实现这一点,浏览器需要知道已导入代码 进入 Service Worker 后 安装。 根据 Service Worker 规范, 调用 importScripts() 应仅在顶层同步执行期间有效 Service Worker 脚本,或(如果需要)在 install 处理程序内异步执行。

在 Chrome 71 之前,在 install 处理程序外部异步调用 importScripts() 会导致 工作。从 Chrome 71 开始,这些调用 抛出运行时异常(除非之前在 install 处理程序中导入了相同的网址), 与其他浏览器中的行为一致

与以下代码不同:

// This only works in Chrome 70 and below.
self.addEventListener('fetch', event => {
  importScripts('my-fetch-logic.js');
  event.respondWith(self.customFetchLogic(event));
});

您的 Service Worker 代码应如下所示:

// Move the importScripts() to the top-level scope.
// (Alternatively, import the same URL in the install handler.)
importScripts('my-fetch-logic.js');
self.addEventListener('fetch', event => {
  event.respondWith(self.customFetchLogic(event));
});

弃用传递给 cache.addAll() 的重复网址

如果将 Cache Storage API 与 Service Worker 结合使用,则 Chrome 71 以符合相关规范。当同一网址 多次传递到对 cache.addAll()、 规范规定,该调用返回的 promise 应拒绝。

对于 Chrome 71 之前的版本,系统不会检测此类网址,因此实际上会忽略重复的网址。

<ph type="x-smartling-placeholder">
</ph> Chrome 控制台中警告消息的屏幕截图 <ph type="x-smartling-placeholder">
</ph> 从 Chrome 71 开始,控制台中会记录一条警告消息。

此日志记录是 Chrome 72 的序言,在 Chrome 72 中,重复的网址不仅仅是已记录的警告 会导致 cache.addAll() 拒绝。如果您调用 cache.addAll() 作为 promise 链的一部分 传递给 InstallEvent.waitUntil(), 拒绝这种情况可能会导致 Service Worker 安装失败。

以下是您可能会遇到麻烦的方法:

const urlsToCache = [
  '/index.html',
  '/main.css',
  '/app.js',
  '/index.html', // Oops! This is listed twice and should be removed.
];

self.addEventListener('install', event => {
  event.waitUntil(
    caches.open('my-cache').then(cache => cache.addAll(urlsToCache))
  );
});

此限制仅适用于传递到 cache.addAll() 的实际网址,以及缓存 最终是两个具有不同网址的等效响应(例如 '/''/index.html'), 不会触发拒绝操作。

广泛测试 Service Worker 实现

Service Worker 已广泛实现 涵盖所有主要“常青”浏览器 。如果您针对多种浏览器定期测试渐进式 Web 应用,或者 有大量用户并未使用 Chrome,那么您可能已经检测到 并更新代码但或许您还没注意到 因此,我们想在切换 Chrome 的行为前对更改进行说明。