在后台同步和更新 PWA

使用服务辅助角色,渐进式 Web 应用 (PWA) 可以在后台完成工作,即使用户未使用该应用,也可以提供更好的脱机体验。

请考虑以下用例:

  • 一个电子邮件应用,允许用户撰写邮件并随时发送,即使在脱机时也是如此。
  • 一个新闻应用,每天提取新文章,供用户稍后在打开应用时阅读。
  • 一个音乐应用,允许用户下载歌曲以供脱机收听。

通过使用以下 API,可以使用 PWA 实现这三种用例:

  • 后台同步 API
  • 定期后台同步 API
  • 后台提取 API

尽管这些 API 具有类似的名称,但它们在性质上有所不同。

使用后台同步 API 将数据与服务器同步

使用后台同步 API 允许用户继续使用应用并执行操作,即使他们处于脱机状态。

例如,电子邮件应用可以允许其用户随时撰写和发送邮件。 应用前端可以尝试立即发送消息,如果设备脱机,服务辅助角色可以捕获失败的请求,并使用后台同步 API 延迟任务,直到连接。

使用后台同步 API 的另一个示例是在后台为用户加载内容。

注意

后台同步 API 应用于少量数据。 后台同步 API 要求服务辅助角色在数据传输的整个持续时间内保持活动状态。 后台同步 API 不应用于提取大型文件,因为设备可以决定终止服务辅助角色,以延长电池使用时间。 请改用 后台提取 API

检查支持

后台同步 API 在 Microsoft Edge 中可用,但应确保后台同步 API 在运行应用的其他浏览器和设备中受支持。 若要确保后台同步 API 受支持,请测试 对象是否 ServiceWorkerRegistration 具有 sync 属性:

navigator.serviceWorker.ready.then(registration => {
    if (registration.sync) {
        // Background Sync is supported.
    } else {
        // Background Sync isn't supported.
    }
});

若要详细了解 ServiceWorkerRegistration 接口,请参阅 MDN 上的 ServiceWorkerRegistration

请求同步

首先要做的是请求同步。这可以由应用前端或服务辅助角色完成。

  • 如果想要让用户负责稍后或不同步,则从前端请求同步是很好的。
  • 如果希望该服务对用户透明,请从服务辅助角色请求同步。 在这种情况下,服务辅助角色可以检测失败的提取请求并立即请求同步。

若要请求同步,需要 ServiceWorkerRegistration 和 标记名称。 在应用前端代码中,执行以下操作:

async function requestBackgroundSync() {
    const registration = await navigator.serviceWorker.ready;
    await registration.sync.register('my-tag-name');
}

或者,从服务辅助角色执行此操作:

async function requestBackgroundSync() {
    await self.registration.sync.register('my-tag-name');
}

上面的 my-tag-name 字符串应该是标识此同步请求的唯一标记,以便可以完成多个请求。

对同步事件做出响应

一旦可以使用连接且服务辅助角色正在运行,就会向服务辅助角色发送事件 sync ,该服务辅助角色可以使用该事件来同步必要的数据。 sync可以使用以下代码侦听事件:

self.addEventListener('sync', event => {
    if (event.tag === 'my-tag-name') {
        event.waitUntil(doTheWork());
    }
});

在上面的示例代码中,在服务辅助角色中添加了一个 sync 事件侦听器。 调用侦听器时,代码会检查标记是否是在前端中注册的标记,然后调用 doTheWork。 此函数应返回 Promise。

通常,函数 doTheWork 会将用户脱机时无法发送的信息发送到服务器。 从前端将此信息存储在 IndexedDB 存储中可能很有用,以便稍后可以在运行时从服务辅助角色 doTheWork 中检索它。

有关 事件、 ServiceWorkerRegistrationSyncManager 接口的详细信息Sync,请参阅后台同步草稿规范后台同步 API 文档

演示应用

“我的电影列表 PWA ”是一个演示应用,它使用后台同步 API 在用户处于脱机状态时提取电影信息。

“我的电影列表”PWA 演示应用

测试后台同步:

  1. 安装应用。

  2. 使用搜索输入字段搜索电影。

  3. 脱机。 为此,请打开 DevTools (F12) ,然后选中“ 应用程序>服务辅助角色>脱机 ”复选框。

    使用 DevTools 模拟脱机

  4. 在其中一个电影结果中,选择“ 详细信息”。

  5. 应用中会显示一条消息,通知你处于脱机状态,稍后将自动检索电影详细信息。

    脱机消息

  6. 联机。 为此,请在 DevTools 中清除 “应用程序>服务辅助角色>脱机 ”复选框。

  7. 重新加载应用。 现在会显示电影详细信息。

若要查看示例代码,请查看 movies-db-pwa 存储库。

调试与 DevTools 的后台同步

若要测试后台同步代码,无需脱机,然后联机,然后等待 Microsoft Edge 触发 sync 事件。 相反,DevTools 允许模拟后台同步事件。

sync模拟事件:

  1. 打开 DevTools (F12) 。
  2. 选择“ 应用程序>服务辅助角色”。
  3. 在“ 同步 输入”字段中键入注册同步时使用的标记名称。
  4. 选择“ 同步” 按钮。

在应用程序面板中模拟后台同步

还可以在 DevTools 中记录应用生成的后台同步活动,如下所示:

  1. 打开 DevTools (F12) 。
  2. 选择“ 应用程序>后台同步”。
  3. 选择 “开始录制事件”。

同步注册和调度显示在事件日志表中:

记录后台同步事件

使用定期后台同步 API 定期获取新内容

定期后台同步 API 允许 PWA 定期在后台检索新内容,以便用户在以后再次打开应用时可以立即访问它。

使用定期后台同步 API 时,PWA 无需 (下载新内容,例如用户在使用应用时) 新文章。 下载内容可能会减慢体验,因此,请改为在更方便的时间检索内容。

注意

仅当设备位于已知网络 (即设备在) 之前已连接到的网络时,才会发生定期同步。 Microsoft Edge 会限制同步的频率,以匹配用户使用应用的频率。

检查支持

若要检查运行应用的浏览器和设备是否支持此 API,请测试 对象 ServiceWorkerRegistration 是否具有 periodicSync 属性:

navigator.serviceWorker.ready.then(registration => {
    if (registration.periodicSync) {
        // Periodic Background Sync is supported.
    } else {
        // Periodic Background Sync isn't supported.
    }
});

向用户请求权限

定期后台同步需要用户的权限。 对于给定的应用程序,请求此权限只发生一次。

若要要求用户获得执行定期后台同步的权限,请使用权限 API,如下所示:

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.
}

若要详细了解权限 API,请参阅 MDN 上的权限 API

注册定期同步

若要注册定期同步,需要定义最小间隔和唯一的标记名称。 唯一标记名称允许注册多个定期后台同步。

async function registerPeriodicSync() {
    await registration.periodicSync.register('get-daily-news', {
        minInterval: 24 * 60 * 60 * 1000
    });
}

minInterval上述代码中使用的 对应于 1 天(以毫秒为单位)。 这只是一个最小间隔,Microsoft Edge 在向服务辅助角色发出定期同步事件(例如网络连接以及用户是否定期使用应用)的警报之前考虑了其他因素。

响应定期同步事件

当Microsoft Edge 确定是运行定期同步的好时机时,Microsoft Edge 会向服务辅助角色发送 periodicsync 事件。 可以使用注册同步时指定的相同标记名称来处理此 periodicsync 事件。

self.addEventListener('periodicsync', event => {
    if (event.tag === 'get-daily-news') {
        event.waitUntil(getDailyNewsInCache());
    }
});

函数 getDailyNewsInCache 是服务辅助角色可从服务器中提取新内容并将其存储在缓存中的位置。 此函数应返回一个 Promise,指示同步是成功还是失败。

有关 事件、 ServiceWorkerRegistrationPeriodicSyncManager 接口的详细信息PeriodicSync,请参阅:

演示应用

DevTools 提示 是使用定期后台同步 API 的 PWA。 [DevTools 提示] PWA 每天提取新的开发人员工具提示并将其存储在缓存中,以便用户可以在下次打开应用时访问它们,无论他们是否处于联机状态。

DevTools Tips 应用

转到 GitHub 上的源代码。 具体而言,应用在 registerPeriodicSync 函数中注册定期同步。 服务辅助角色代码是应用侦periodicsync听事件的位置。

调试与 DevTools 的定期后台同步

可以使用 DevTools 来模拟 periodicsync 事件,而不是等待最小间隔。

模拟事件:

  1. 打开 DevTools (F12) 。
  2. 选择“ 应用程序>服务辅助角色”。
  3. 在“ 定期 同步”输入字段中键入注册定期同步时使用的标记名称。
  4. 选择“ 定期同步 ”按钮。

在应用程序面板中模拟定期后台同步

还可以在 DevTools 中记录应用生成的定期后台同步活动:

  1. 打开 DevTools (F12) 。
  2. 选择“ 应用程序>定期后台同步”。
  3. 选择 “开始录制事件”。

定期同步注册和调度显示在事件日志表中。

记录定期后台同步事件

当应用或服务辅助角色未运行时,使用后台提取 API 提取大型文件

后台提取 API 允许 PWA 将大量数据下载完全委托给浏览器引擎。 这样,应用和服务辅助角色就不必在下载过程中运行。

此 API 适用于允许用户下载大型文件 ((如音乐、电影或播客)的应用,) 脱机用例。 由于下载委托给浏览器引擎,该引擎知道如何处理不起的连接,甚至连接完全丢失,因此可以在必要时暂停和恢复下载。

检查支持

若要检查是否支持此 API,请测试全局对象上是否存在 BackgroundFetchManager 构造函数:

if (self.BackgroundFetchManager) {
    // Background Fetch is supported.
} else {
    // Background Fetch isn't supported.
}

启动后台提取

启动后台提取:

navigator.serviceWorker.ready.then(async registration => {
    const fetch = await registration.backgroundFetch.fetch('my-download-id', 
                                                           fileUrls, options);
});

上面的 应 my-download-id 是此后台提取的唯一字符串标识符。 fileUrls 是要下载的文件列表,这是字符串 URL 的数组。 和 options 是一个对象,可用于在浏览器中自定义下载活动的外观。

有关函数 fetch 的详细信息,请参阅 BackgroundFetchManager.fetch () Background Fetch 简介

使用应用 Badging API 和通知 API 重新吸引用户

使用应用 Badging API 和通知 API 可让用户知道后台任务、下载或新内容已完成,而不会中断其工作流。 使用锁屏提醒和通知可以增加用户对应用的重新参与度。

使用 Microsoft Edge 时,锁屏提醒显示在任务栏中的应用图标上,通知与系统通知中心集成。

若要了解如何使用这些 API,请参阅 使用锁屏提醒、通知和推送消息重新吸引用户