与workbox-window.update()不一致的行为

问题描述 投票:2回答:1

平台

"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36"

Workbox版本

5.0.0-rc.0

我正在使用workbox-window update()方法来触发服务工作者更新检查,如workbox issue #2130中所述。这个问题似乎也与workbox issue #2301中的观察结果有关。

<script type="module">
import {Workbox} from 'https://storage.googleapis.com/workbox-cdn/releases/5.0.0-rc.0/workbox-window.prod.mjs';

if ('serviceWorker' in navigator) {
    const wb = new Workbox('/sw.js');
    // Grab the update button from the UI using jQuery and add a listener to it.
    $('#update-button').on('click', function () {
        wb.update();
    });
    ....
}

</script>

如果找到更新,则将加载新的服务工作程序并进入等待状态。我侦听此事件(waitingexternalwaiting都在两种情况下执行相同的操作),并询问用户是否要立即或稍后安装更新。

function handleWaiting(wb) {
    if (confirm("An update is available for this app. Install now?")) {
        wb.messageSW({type: 'SKIP_WAITING'});
    }
}
wb.addEventListener('waiting', event => {
    handleWaiting(wb);
});
wb.addEventListener('externalwaiting', event => {
    handleWaiting(wb);
});

在大多数情况下,会触发waiting事件,并且如果用户接受更新,则会激活服务工作者,我们可以重新加载页面以完成更新过程:

function handleActivated(wb, event) {
    if (event.isUpdate) {
        window.location.reload();
    } else {
        wb.messageSW({ type: 'CLIENTS_CLAIM' });
    }
}
wb.addEventListener('activated', event => {
    handleActivated(wb, event);
});
wb.addEventListener('externalactivated', event => {
    handleActivated(wb, event);
});

如果触发waiting事件,则此过程运行正常。

  1. 对应用程序进行小的更新,导致服务工作者文件发生更改。
  2. 按“检查更新”按钮。
  3. 找到新服务人员,并提示用户安装更新
  4. 页面已重新加载。

但是如果触发了externalwaiting事件,则此代码不起作用。新的服务工作者仍处于等待状态,我可以在Chrome开发工具中看到该状态。

Stuck waiting

旧服务人员收到的跳过等待消息

如果用户确认他们要更新SKIP_WAITING消息,则由较旧的激活的服务工作者定义接收。

这里是我的日志摘录,证明了这一点。

  • 来自应用程序/客户端的日志条目以“ Application”作为前缀,后跟应用程序版本。
  • 来自服务工作者的日志条目以“服务工作者”为前缀,后跟每个服务工作者实例唯一的DOB日期戳。
01 [Application 0.0.1.2019.11.05-48] Checking for updates...
02 [Service Worker 2019-11-05 @ 15:23:14] <<<<<<<<<<<<<<< STARTING >>>>>>>>>>>>>>>
03 [Service Worker 2019-11-05 @ 15:23:14] Yay! Workbox 5.0.0-rc.0 is loaded 😁
04 [Service Worker 2019-11-05 @ 15:23:14] Lifecycle event: [install]
05 [Application 0.0.1.2019.11.05-48] Service Worker lifecycle event: 06 [externalinstalled]
07 [Application 0.0.1.2019.11.05-48] Service Worker lifecycle event: [externalwaiting]
08 [Application 0.0.1.2019.11.05-48] handle waiting...
09 [Service Worker 2019-11-05 @ 15:20:03] Message event: [SKIP_WAITING]

在线

  1. 用户刚刚按下了“检查更新”按钮。
  2. 2019-11-05 @ 15:23:14上发现了一个新的服务工作者版本,正在对其进行解析。我们将其称为SWv2。
  3. Workbox由SWv2加载。
  4. SWv2 install事件处理程序已执行。
  5. 将执行[Workbox]窗口externalinstalled事件处理程序。
  6. 将执行[Workbox]窗口externalwaiting事件处理程序。
  7. 工作箱窗口externalwaiting事件处理程序使用SKIP_WAITING发送workboxWindow.messageSW()消息>
  8. Service Worker v1(加载到2019-11-05 @ 15:20:03上)收到跳过等待消息。没发生什么事。 SWv2保持等待状态。
  9. 与普通等待事件的对比

在以下日志中,您可以看到正在等待服务的工作人员收到SKIP_WAITING消息:v 2019-11-05 @ 16:07:32。因此,更新过程成功完成。

[Application 0.0.1.2019.11.05-52] Checking for updates...
[Service Worker 2019-11-05 @ 16:07:32] <<<<<<<<<<<<<<< STARTING >>>>>>>>>>>>>>>
[Service Worker 2019-11-05 @ 16:07:32] Yay! Workbox 5.0.0-rc.0 is loaded 😁
[Service Worker 2019-11-05 @ 16:07:32] Lifecycle event: [install]
[Application 0.0.1.2019.11.05-52] Service Worker lifecycle event: [installed]
[Application 0.0.1.2019.11.05-52] Service Worker lifecycle event: [waiting]
[Application 0.0.1.2019.11.05-52] handle waiting...
[Service Worker 2019-11-05 @ 16:07:32] Message event: [SKIP_WAITING]
[Application 0.0.1.2019.11.05-52] Service Worker lifecycle event: [redundant]
[Application 0.0.1.2019.11.05-52] Service Worker lifecycle event: [activating]
[Application 0.0.1.2019.11.05-52] Service Worker lifecycle event: [controlling]
[Service Worker 2019-11-05 @ 16:07:32] Lifecycle event: [activate]
[Application 0.0.1.2019.11.05-52] Service Worker lifecycle event: [activated]
[Application 0.0.1.2019.11.05-52] Reloading this window...
[Application 0.0.1.2019.11.05-53] <<<<<<<<<<<<<<< STARTING >>>>>>>>>>>>>>>
[Application 0.0.1.2019.11.05-53] Preloading 125 images...
[Application 0.0.1.2019.11.05-53] ServiceWorker registered!

有时它会挂起来...

[有时,当有新的Service Worker版本可用时,事情只会卡住。永远不会触发waitingexternalwaiting事件处理程序。

Chrome Dev Tools "trying to install"

发生这种情况时,控制台中没有错误,新版本的Service Worker也没有问题。

解除粘滞状态的唯一方法是停止活动的Service Worker,取消注册并重新加载。

为什么如此重要?

在我敢发布此应用之前,我需要确保更新过程在所有平台上均能正常工作...

如果用户在发布更新时遇到这些问题中的任何一个,他们将很难获得它,并且我将无能为力。乘以安装数量==令人头疼。

这全部归结为三个问题:

重要性顺序:
  1. 如何处理externalwaiting,以便加载并激活新版本的Service Worker?如何确保等待服务的工作人员收到SKIP_WAITING消息?
  2. 为什么生命周期事件在普通品种和外部品种之间有所不同?
    • 出于测试目的,我每次都对服务工作者进行相同的更新(预缓存文件的新版本)。
    • 我只在一个标签中加载过该应用。
    • 从普通事件到外部事件的切换似乎是随机的。
  3. 为什么流程有时会在生命周期的等待阶段之前卡住,我该怎么办?

平台“ Mozilla / 5.0(X11; Linux x86_64)AppleWebKit / 537.36(KHTML,例如Gecko)Chrome / 78.0.3904.70 Safari / 537.36”工作箱版本5.0.0-rc.0我正在使用工作箱窗口update() ...

google-chrome-devtools progressive-web-apps workbox workbox-window
1个回答
0
投票

请注意,现在已在“工作箱”窗口中解决了此问题。有更新的高级食谱:

© www.soinside.com 2019 - 2024. All rights reserved.