如何在 web worker 中使用 PixiJS

How to use PixiJS in web worker

我需要使用 PixiJS 在 canvas 中显示一个相当复杂的二维形状,为此我想在单独的线程(网络工作者)中创建和定义所有图形元素,以免阻塞UI 的其余部分。

问题是当我像这样在 web worker 文件中导入 PixiJS 时

importScripts('https://cdnjs.cloudflare.com/ajax/libs/pixi.js/4.5.2/pixi.js');

它给我一个错误,因为它访问 DOM 元素(如 window 和文档),这在网络工作者中是不允许的。我该如何解决?

这是错误:

Uncaught ReferenceError: window is not defined
at Object.179../Math.sign (Object.assign.js:3)
at s (_prelude.js:1)
at _prelude.js:1
at Object.<anonymous> (WebGLPrepare.js:101)
at Object.187../accessibility (index.js:44)
at s (_prelude.js:1)
at e (_prelude.js:1)
at _prelude.js:1
at _prelude.js:1
at _prelude.js:1

嗯,我想你不能。 Webworker 有自己的 DedicatedWorkerGlobalScope,无法访问 DOM、window 等。如果你有繁重的计算,例如计算动画,你所能做的就是让 webworker 做数字运算和主线程进行渲染。

Worker和主线程不能共享对象。即使以下解释在技术上不是 100% 正确,您可以想象如果您:

var obj = { a: { b: 100 } };
worker.postMessage(obj);

会更像:

                   //really dirty object clone here
worker.postMessage(JSON.parse(JSON.stringify(obj)));

我想指出的是,您不能与 worker 共享对象,反之亦然。

在此处找到技术上正确的解释:

https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers#Transferring_data_to_and_from_workers_further_details

Philipp 的回答是正确的,我只是想从游戏和网络工作者的角度进一步阐述一下。

根据我的经验,通常很难在游戏中利用网络工作者。特别是如果你使用一个库来处理 canvas / webGL,因为无论如何这都会处理大部分的数字。正如 philipp 提到的,网络工作者是为数字运算而设计的。在 web worker 和主线程之间传递数据是非常昂贵的,所以传递数据并对它们进行微小的操作,不会有好处。

在没有提供直接 link 的情况下,我很久以前就已经读到一些游戏引擎(我认为是构造)使用网络工作者作为他们的寻路模块。所以与直接图形处理无关,而是数值运算。

还有一个关于在 web worker 上下文中使用 canvases 的可能性的提议,所以这显然也是其他人的问题。如果我没记错的话,我相信是这样的:https://developer.mozilla.org/fi/docs/Web/API/OffscreenCanvas

可以在您的 Web Worker 中包含 PixiJS,尽管您不能执行图形操作。

虽然其他两个答案在技术上是正确的,但在不实际渲染图形的情况下将 Pixi 的代码包含在您的 Worker 范围内是合法的用例。一个例子是使用 Pixi 的 PointRectangle 类。就我而言,我编写了几个模块,这些模块依赖于 Pixi 导出的定义并基于它们执行大量计算。

您遇到的错误是因为 Pixi 依赖全局变量 windowdocument 来定义一些与图形相关的常量。为了让 Pixi 完成加载,您可以使用与 Pixi 使用的方法同名的空方法为 windowdocument 提供模拟值。

例如,在使用 PixiJS 4.8.6 时,以下代码对我有效:

window = self
document = {
    createElement () {
        return {
            getContext () {
                return {
                    fillRect () {},
                    drawImage () {},
                    getImageData () {},
                }
            },
        }
    },
}

importScripts('pixi-4-8-6.js');

/* Web Worker code follows */
// ...

根据 Pixi 的版本,您可能需要调整此样板文件。另一种方法是尝试为无头浏览器模拟 documentCanvas 的那些软件包之一。我还没有尝试过,因为上面的代码运行得很好。

Pixi 5 最近问世,它可能彻底改变了这一点。我浏览了代码,看起来他们删除了导致问题的常量定义,所以这个新版本也有可能开箱即用。我知道他们一直在研究让人们更轻松地使用 Workers,并且他们一直在探索 OffscreenCanvas,就像 Hachi 所说的那样。

pixi 团队正在努力添加 headless 环境支持,例如 web worker;见 https://github.com/pixijs/pixijs/issues/7123