在后台同步 Web 应用的数据,以获得更接近原生应用的使用体验
您是否曾遇到过以下任何情况?
- 乘坐火车或地铁时网络连接不稳定或没有网络连接
- 观看过多视频后,流量受到运营商限制
- 居住在带宽难以满足需求的国家/地区
如果您有过这种经历,那么您肯定体会过在网络上完成某些任务时的挫败感,并且想知道为什么特定于平台的应用在这些场景中往往表现更好。平台专用应用可以提前获取新鲜内容,例如新闻报道或天气信息。即使在地铁中没有网络,您仍然可以阅读新闻。
借助定期后台同步,Web 应用可以定期在后台同步数据,从而使 Web 应用的行为更接近于特定平台的应用。
试试看
开发者工具提示是一款使用 Periodic Background Sync API 的 PWA。DevTools Tips PWA 每天都会提取新的开发者工具提示并将其存储在缓存中,以便用户下次打开应用时(无论是否在线)都可以访问这些提示。请务必安装应用,以便使用 Periodic Background Sync API。
前往 GitHub 上的源代码。具体而言,应用会在 registerPeriodicSync() 函数中注册周期性同步。Service Worker 代码是应用监听 periodicsync 事件的地方。
概念和用法
借助周期性后台同步,您可以在启动渐进式 Web 应用或由 Service Worker 支持的网页时显示最新内容。为此,它会在应用或网页未被使用时在后台下载数据。这样可以防止应用的内容在启动后被查看时刷新。更好的是,它可防止应用在刷新之前显示内容微调器。
如果没有定期后台同步,Web 应用必须使用其他方法来下载数据。一个常见的例子是使用推送通知唤醒服务工作线程。用户会收到“有新数据可用”等消息,从而被打断。更新数据本质上是一种副作用。您仍然可以选择使用推送通知来接收真正重要的更新,例如重大突发新闻。
定期后台同步可能会与后台同步混淆。虽然名称相似,但使用场景不同。在其他用途中,后台同步最常用于在之前的请求失败时将数据重新发送到服务器。
如何提高用户互动度
如果处理不当,周期性后台同步可能会浪费用户资源。在发布之前,Chrome 对其进行了试用期,以确保其正确无误。本部分将介绍 Chrome 为尽可能提高此功能的实用性而做出的一些设计决策。
Chrome 做出的第一个设计决策是,只有在用户将 Web 应用安装到设备上并将其作为独立应用启动后,该 Web 应用才能使用周期性后台同步。在 Chrome 常规标签页的上下文中,无法进行定期后台同步。
此外,由于 Chrome 不希望未使用的或很少使用的 Web 应用随意消耗电池电量或数据流量,因此 Chrome 设计了定期后台同步功能,以便开发者必须通过为用户提供价值来获得该功能。具体来说,Chrome 会使用网站互动度得分 (about://site-engagement/) 来确定给定 Web 应用是否可以进行定期后台同步以及同步的频率。换句话说,除非互动度得分大于零,否则根本不会触发 periodicsync 事件,并且互动度得分的值会影响 periodicsync 事件的触发频率。这样可确保在后台同步的只有您正在使用的应用。
周期性后台同步与热门平台上的现有 API 和实践有一些相似之处。例如,一次性后台同步和推送通知允许 Web 应用的逻辑在用户关闭网页后(通过其 Service Worker)继续运行一段时间。在大多数平台上,用户通常会安装一些应用,这些应用会在后台定期访问网络,以提供更好的用户体验,例如进行关键更新、预提取内容和同步数据。同样,定期后台同步也会延长 Web 应用逻辑的生命周期,使其能够定期运行,每次运行时间可能为几分钟。
如果浏览器允许这种情况频繁发生且不受限制,可能会导致一些隐私问题。以下是 Chrome 针对定期后台同步的风险采取的措施:
- 后台同步活动仅在设备之前连接过的网络上进行。Chrome 建议仅连接到由可信方运营的网络。
- 与所有互联网通信一样,定期后台同步会显示客户端的 IP 地址、客户端正在通信的服务器的 IP 地址以及服务器的名称。为了将这种曝光度降低到与应用仅在前台同步时大致相同的水平,浏览器会限制应用的后台同步频率,使其与用户使用该应用的频率保持一致。如果用户不再经常与应用互动,定期后台同步将停止触发。与特定于平台的应用相比,这是一个净改进。
何时可以使用?
使用规则因浏览器而异。总结一下,Chrome 对定期后台同步有以下要求:
- 特定用户互动度得分。
- 是否存在之前使用过的网络。
同步的时间不受开发者控制。同步频率将与应用的使用频率保持一致。(请注意,特定于平台的应用不会执行此操作。)它还会考虑设备的电源和连接状态。
何时应使用此功能?
当 Service Worker 唤醒以处理 periodicsync 事件时,您可以请求数据,但没有义务这样做。在处理事件时,您应考虑网络状况和可用存储空间,并下载不同数量的数据作为响应。您可以使用以下资源来获取帮助:
权限
安装 service worker 后,使用 Permissions 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.periodicSync 检索 PeriodicSyncManager,并对其调用 register()。注册需要同时提供标记和最小同步间隔 (minInterval)。标记用于标识已注册的同步,以便注册多个同步。在以下示例中,标记名称为 'content-sync',minInterval 为 1 天。
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() 在 Web 应用的设置页面中显示有效注册的列表,以便用户启用或停用特定类型的更新。
响应定期后台同步事件
如需响应定期后台同步事件,请向您的 Service Worker 添加 periodicsync 事件处理程序。传递给它的 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');
}
接口
下面简要介绍了 Periodic Background Sync API 提供的接口。
PeriodicSyncEvent。在浏览器选择的时间传递给ServiceWorkerGlobalScope.onperiodicsync事件处理脚本。PeriodicSyncManager。注册和取消注册定期同步,并为已注册的同步提供标记。从 ServiceWorkerRegistration.periodicSync 属性检索此类的实例。ServiceWorkerGlobalScope.onperiodicsync。注册一个处理程序以接收PeriodicSyncEvent。ServiceWorkerRegistration.periodicSync。返回对PeriodicSyncManager的引用。
示例
以下部分展示了使用 Periodic Background Sync API 的一些示例。
更新内容
以下示例使用周期性后台同步来下载新闻网站或博客的最新文章并将其缓存。请注意,标记名称 ('update-articles') 表明了同步的类型。对 updateArticles() 的调用封装在 event.waitUntil() 中,这样服务工作线程就不会在文章下载并存储之前终止。
async function updateArticles() {
const articlesCache = await caches.open('articles');
await articlesCache.add('/api/articles');
}
self.addEventListener('peri>odicsync', (event) = {
if (event.tag === 'update-articles') {
event.waitUntil(updateArticles());
}
});
向现有 Web 应用添加定期后台同步
这组更改是为现有 PWA 添加定期后台同步功能所必需的。此示例包含许多有用的日志记录语句,用于描述 Web 应用中定期后台同步的状态。
调试定期后台同步 API
在本地测试时,很难获得定期后台同步的端到端视图。有关有效注册、大致同步间隔和过去同步事件的日志的信息可在调试 Web 应用的行为时提供有价值的背景信息。幸运的是,您可以通过 Chrome 开发者工具中的一项实验性功能找到所有这些信息。
记录本地活动
开发者工具的定期后台同步部分围绕定期后台同步生命周期中的关键事件进行组织:注册同步、执行后台同步和取消注册。如需获取有关这些活动的信息,请点击开始录制。
在录制期间,DevTools 中会显示与事件对应的条目,并记录每个事件的上下文和元数据。
启用一次记录功能后,该功能将保持启用状态最多三天,从而允许开发者工具捕获可能发生的后台同步的本地调试信息,即使这些同步发生在数小时之后。
模拟事件
虽然记录后台活动很有用,但有时您会希望立即测试 periodicsync 处理程序,而无需等待事件以正常节奏触发。
您可以使用 Chrome 开发者工具中“应用”面板内的 Service Worker 部分来执行此操作。借助 Periodic Sync 字段,您可以为要使用的事件提供标记,并根据需要多次触发该事件。
开发者工具界面的使用
您会在 DevTools 的应用面板中看到定期后台同步部分。