通过 Periodic Background Sync API 获得更丰富的离线体验

在后台同步 Web 应用的数据,获得更接近应用的体验

Joe Medley
Joe Medley

您是否出现过以下任何情况?

  • 乘坐火车或地铁时断网或没有网络连接
  • 观看过多视频后受到运营商的限制
  • 所居住的国家/地区带宽很难满足需求

如果确实出现了问题,那您肯定也已经感受到 并想知道为什么针对特定平台的应用往往能更好地运行 。针对具体平台的应用可以提取新鲜内容,例如新闻报道或天气 提前获取相关信息即使地铁中没有网络,您也可以阅读 新闻。

定期后台同步可让网络应用定期同步数据 后台数据,使 Web 应用更接近于平台特定行为的行为 应用。

试试看

您可以通过实时演示定期进行后台同步 app。 在使用它之前,请确保:

  • 您使用的是 Chrome 80 或更高版本。
  • 安装 然后才能启用定期后台同步。

概念和用法

通过定期后台同步功能,您可以在运行渐进式 Web 应用时 或 Service Worker 支持的页面启动。为此,它会通过 当应用或页面未被使用时从后台运行。这样可以防止应用出现 使内容在启动后被观看时刷新。更棒的是, 防止应用在刷新前显示内容旋转图标。

如果没有定期进行后台同步,Web 应用必须使用其他方法 下载数据。一个常见示例是使用推送通知来唤醒服务 worker。用户被消息(如“有新数据可用”)打断。 更新数据本质上是一种副作用。您仍然可以选择 使用推送通知来发布真正重要的更新 重大新闻。

定期的后台同步很容易与后台同步混淆。尽管他们 具有相似名称,那么它们的应用场景也不同。除此之外, 后台同步最常用于在以下情况下将数据重新发送到服务器: 上一个请求已失败。

提高用户互动度

操作不当,定期进行后台同步可能会浪费用户的 资源。在发布之前,Chrome 为其设置了试用期, 确定这是对的。本部分将介绍 Chrome 的一些设计决策 使此功能尽可能实用。

Chrome 浏览器的第一个设计决策是,网络应用只能使用定期 在后台进行同步,并且已经 将其作为单独的应用启动无法定期进行后台同步 在 Chrome 的常规标签页中查看。

此外,由于 Chrome 不希望无谓地使用 消耗电量或数据,Chrome 设计了定期后台同步, 开发者必须为用户提供价值,才能赚取收入。具体而言, Chrome 使用的是网站互动得分 (about://site-engagement/),用于确定是否可定期进行后台同步以及多久进行一次 特定 Web 应用。也就是说,除非互动事件发生,否则系统不会触发 periodicsync 事件, 得分大于零,其值会影响 触发 periodicsync 事件。这样可以确保只有应用程序在 是您正在使用的应用

定期后台同步与现有 API 有一些相似之处, 热门平台上的做法例如,一次性后台同步和 推送通知允许 Web 应用逻辑存在更长时间(通过其 Service Worker)。在大多数平台上 安装定期访问网络的应用 以便针对关键更新提供更好的用户体验 预提取内容、同步数据等。同样,定期后台同步 可延长 Web 应用逻辑的生命周期,使其定期运行, 可能每次只会持续几分钟

如果浏览器允许这种情况频繁出现且不受限制, 也可能会导致一些隐私问题Chrome 如何解决此问题 定期后台同步的风险:

  • 后台同步活动只会在设备已连接到的网络中发生 。Chrome 建议仅连接到 值得信任的各方。
  • 与所有互联网通信一样,定期的后台同步可揭示 IP 地址的 包括客户端地址、与它通信的服务器、 服务器。为了将这种暴露量降低到 在前台运行时进行同步,那么浏览器会限制 应用的后台同步频率,以适应用户使用该应用的频率。如果 用户停止频繁地与应用互动,定期进行后台同步 将停止触发。这是相对于平台特定领域的现状而言的净改进 。

何时可以使用?

使用规则因浏览器而异。从以上内容可以看出,Chrome 将 定期后台同步需满足以下要求:

  • 特定的用户互动度得分。
  • 之前使用过的网络。

同步的时间并非由开发者控制。通过 同步频率将与应用的使用频率一致。(请注意, 针对具体平台的应用目前无法执行此操作。)它还会考虑设备的电量 连接状态。

应在何时使用?

当您的 Service Worker 唤醒以处理 periodicsync 事件时,您将获得 请求数据的机会,但不是请求数据的义务。处理时 您应该将网络条件和可用存储空间 并下载不同数量的数据作为响应。您可以使用 以下资源可帮助您:

权限

安装 Service Worker 后,请使用权限 API来查询 价格为 periodic-background-sync。您可以从窗口或 Service Worker 上下文。

const status = await navigator.permissions.query({
  name: 'periodic-background-sync',
});
if (status.state === 'granted') {
  // Periodic background sync can be used.
} else {
  // Periodic background sync cannot be used.
}

注册定期同步

如前所述,定期后台同步需要一个 Service Worker。检索 使用 ServiceWorkerRegistration.periodicSyncPeriodicSyncManager 并调用 其中 register() 项。注册时至少需要一个标记 同步间隔 (minInterval)。该标记用于标识已注册的同步操作 以便可以注册多次同步。在下面的示例中,代码名称为 'content-sync'minInterval是一天。

const registration = await navigator.serviceWorker.ready;
if ('periodicSync' in registration) {
  try {
    await registration.periodicSync.register('content-sync', {
      // An interval of one day.
      minInterval: 24 * 60 * 60 * 1000,
    });
  } catch (error) {
    // Periodic background sync cannot be used.
  }
}

验证注册

调用 periodicSync.getTags() 可检索一组注册标记。通过 以下示例使用标记名称来确认缓存更新是否有效,以避免 再次更新。

const registration = await navigator.serviceWorker.ready;
if ('periodicSync' in registration) {
  const tags = await registration.periodicSync.getTags();
  // Only update content if sync isn't set up.
  if (!tags.includes('content-sync')) {
    updateContentOnPageLoad();
  }
} else {
  // If periodic background sync isn't supported, always update.
  updateContentOnPageLoad();
}

您还可以使用 getTags() 在您的网页中显示有效注册列表 应用的设置页面,以便用户启用或停用特定类型的 更新。

响应定期的后台同步事件

要响应定期后台同步事件,请添加 periodicsync 事件 传递给 Service Worker。传递给它的 event 对象将包含一个 tag 参数与注册期间使用的值匹配。例如,如果 以名称“'content-sync'”注册了定期后台同步,则 event.tag 将是 'content-sync'

self.addEventListener('periodicsync', (event) => {
  if (event.tag === 'content-sync') {
    // See the "Think before you sync" section for
    // checks you could perform before syncing.
    event.waitUntil(syncContent());
  }
  // Other logic for different tags as needed.
});

取消注册同步

要结束已注册的同步,请调用 periodicSync.unregister() 并提供 同步。

const registration = await navigator.serviceWorker.ready;
if ('periodicSync' in registration) {
  await registration.periodicSync.unregister('content-sync');
}

接口

下面简要介绍定期后台提供的接口 同步 API。

  • PeriodicSyncEvent。在ServiceWorkerGlobalScope.onperiodicsync 浏览器选择的时间。
  • PeriodicSyncManager。注册和取消注册定期同步,并为已注册的操作提供标记 同步。从 ServiceWorkerRegistration.periodicSync 中检索此类的实例 属性。
  • ServiceWorkerGlobalScope.onperiodicsync。注册用于接收 PeriodicSyncEvent 的处理程序。
  • ServiceWorkerRegistration.periodicSync。返回对 PeriodicSyncManager 的引用。

示例

更新内容

以下示例使用定期后台同步来下载和缓存新闻网站或博客的最新文章。请注意标记名称,它表示同步的类型 ('update-articles')。对 updateArticles() 的调用封装在 event.waitUntil() 中,这样 Service Worker 在下载和存储文章之前不会终止。

async function updateArticles() {
  const articlesCache = await caches.open('articles');
  await articlesCache.add('/api/articles');
}

self.addEventListener('periodicsync', (event) => {
  if (event.tag === 'update-articles') {
    event.waitUntil(updateArticles());
  }
});

向现有 Web 应用添加定期后台同步

这组更改添加到 定期后台同步到现有 PWA。此示例包含一些有用的日志记录语句,这些语句描述了 Web 应用中定期后台同步的状态。

调试

获取定期后台同步的端到端视图可能并非易事 同时进行本地测试有关有效注册、大致同步的信息 间隔和过往同步事件日志可在调试时提供有价值的背景信息 行为幸运的是,您可以在这里找到 通过 Chrome 开发者工具中的一项实验性功能来实现

录制本地活动

开发者工具的定期后台同步部分围绕关键事件进行整理 在定期后台同步生命周期内:注册同步、执行 后台同步和取消注册等操作。若要获取有关这些事件的信息, 点击开始录制

<ph type="x-smartling-placeholder">
</ph> 开发者工具中的记录按钮 <ph type="x-smartling-placeholder">
</ph> 开发者工具中的记录按钮

记录时,开发者工具会显示与事件对应的条目, 上下文和元数据。

<ph type="x-smartling-placeholder">
</ph> 记录定期后台同步数据的示例 <ph type="x-smartling-placeholder">
</ph> 记录定期后台同步数据的示例

启用一次录制功能后,该功能会保持启用状态长达三天。 允许开发者工具捕获有关后台同步的本地调试信息 甚至是未来几小时后可能发生的事件。

模拟事件

虽然记录后台活动可能很实用, 您想立即测试 periodicsync 处理程序,而不是等待 按正常节奏触发

您可以通过以下位置的“Application”面板内的 Service Workers 部分执行此操作: Chrome 开发者工具。通过定期同步字段,您可以为 事件使用,并根据需要触发该事件任意次数。

“Service Worker”部分会显示“定期同步”文本字段和按钮。

使用开发者工具界面

从 Chrome 81 开始,您会在 Chrome 应用的定期后台同步部分中看到 开发者工具 Application 面板。

显示“定期后台同步”部分的“应用”面板