共享Web工作者是否在单个页面重新加载、链接导航中保持不变

Do Shared Web Workers persist across a single page reload, link navigation

本文关键字:导航 链接 加载 是否 工作者 Web 单个页 新加载 共享      更新时间:2023-09-26

共享Web工作程序旨在允许来自同一网站(源)的多个页面共享一个Web工作程序。

然而,从规范(或其他关于共享工作者的教程和信息)中,我不清楚如果您在网站上只有一个窗口/选项卡,并且导航到同一网站上的另一个页面,则共享工作者是否会持续存在。

如果共享工作进程的WebSocket连接在导航站点时保持连接,那么这将是最有用的。例如,想象一个股票行情器或聊天区,即使在浏览网站时,它也会持续存在(而不必重新连接WebSocket)。

我已经做了一些测试,以便在实践中找到答案。

Firefox还不支持从Web Workers创建WebSocket连接:https://bugzilla.mozilla.org/show_bug.cgi?id=504553因此,在这个错误得到解决之前,Firefox是不相关的。

IE 10不支持共享网络工作者,所以它也不相关。所以就剩下Chrome了。

下面是一个测试共享web工作者的示例。

首先是HTML:

<!DOCTYPE html>
<html>
<body>
    <a href="shared.html">reload page</a>
    <script>
        var worker = new SharedWorker("shared.js");
        worker.port.addEventListener("message", function(e) {
            console.log("Got message: " + e.data);
        }, false);
        worker.port.start();
        worker.port.postMessage("start");
    </script>
</body>
</html>

然后在shared.js:中实现共享工作者本身

var connections = 0;
self.addEventListener("connect", function(e) {
    var port = e.ports[0];
    connections ++;
    port.addEventListener("message", function(e) {
        if (e.data === "start") {
            var ws = new WebSocket("ws://localhost:6080");
            port.postMessage("started connection: " + connections);
        }
    }, false);
    port.start();
}, false);

Chrome 20中的测试结果(答案):

当页面同时加载在两个独立的选项卡中时,每次重新加载其中一个页面或单击自引用链接时,连接数都会增加。

如果只加载了页面的单个实例,则在重新加载页面或单击链接时,连接计数永远不会改变。

因此,在Chrome 20中:共享Web工作程序不会在页面重新加载和链接导航点击之间持续存在

这似乎与"HTML5 web工作线程在运行时关闭选项卡时会发生什么?"问题基本相同。我认为规范的关键部分是这样的声明:

用户代理可以在工作人员在任何时候,例如响应用户请求,响应CPU配额管理,或者当工作程序停止为活动所需时worker,如果worker即使在其关闭标志之后仍继续执行设置为true。

"主动需要的工人"定义如下:

如果任何文件工作人员文档中的对象处于完全活动状态。

因此,据我所知,如果所有引用工作程序的窗口都关闭了,那么规范要求浏览器终止该工作程序,但不是立即终止。因此,即使它偶尔会起作用,坚持下去也是不可靠的。

在你的例子中,我的方法是通过Ajax加载整个网站-如果你的用户禁用了JS,你将无法运行Web Workers,然后使用History API使用户的页面地址与实际页面相对应(保持搜索引擎和非JS兼容性)。

我成功地使用了一种有点迂回的技术,当我想转到下一个页面但维护SharedWorker时,我会打开一个(希望是不引人注目的)弹出窗口来创建同一个worker,等待它变为活动状态,并向原始端口/窗口发送一条消息,然后导航到新页面,然后在加载该页面时关闭弹出窗口。此策略始终保持至少一个活动连接,因此工作程序永远不会决定关闭。

到目前为止,这项技术似乎相当稳健。尽管看到弹出窗口有些烦人,但对于某些用例来说,这是一个合理的折衷方案。