有没有办法在 Web Worker 中创建 DOM 元素?

新手上路,请多包涵

上下文: 我有一个处理和显示巨大日志文件的 Web 应用程序。它们通常只有 10 万行左右,但也可能长达 400 万行或更多。为了能够滚动浏览该日志文件(用户启动的和通过 JavaScript 启动的)并以良好的性能过滤行,我在数据到达后立即为每一行创建一个 DOM 元素(通过 ajax 在 JSON 中)。我发现这比在后端构建 HTML 的性能更好。之后,我将元素保存在一个数组中,并且只显示可见的行。

对于最多 100k 行,这只需要几秒钟,但对于 500k 行(不包括下载),任何更多的内容最多需要一分钟。我想进一步提高性能,所以我尝试使用 HTML5 Web Workers。现在的问题是我不能在 Web Worker 中创建元素,甚至不能在 DOM 之外创建元素。所以我最终只在 Web Worker 中进行了 json 到 HTML 的转换,并将结果发送到主线程。它在那里被创建并存储在一个数组中。不幸的是,这使性能恶化,现在至少需要 30 秒以上。

问题: 那么有没有什么方法,我不知道,可以在 Web Worker 中的 DOM 树之外创建 DOM 元素?如果不是,为什么不呢?在我看来,这不会产生并发问题,因为创建元素可以并行发生而不会出现问题。

原文由 Joren Van Severen 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.4k
2 个回答

好吧,我根据@Bergi 提供的信息做了更多研究,并在 W3C 邮件列表上找到了以下讨论:

http://w3-org.9356.n7.nabble.com/Limited-DOM-in-Web-Workers-td44284.html

以及回答为什么无法访问 Web Worker 中的 XML 解析器或 DOM 解析器的摘录:

您假设没有任何 DOM 实现代码使用任何类型的非 DOM 对象,或者如果使用的话,这些对象是完全线程安全的。事实并非如此,至少在 Gecko 中是这样。

这种情况下的问题不是在多个线程上触及同一个 DOM 对象。问题是不同线程上的两个 DOM 对象都涉及某个全局第三个对象。

例如,XML 解析器必须做一些在 Gecko 中只能在主线程上完成的事情(DTD 加载,副手;还有一些我以前见过但不记得副手)。

然而,也提到了一种解决方法,即使用解析器的第三方实现, jsdom 就是一个例子。有了这个,您甚至可以访问自己的单独文档。

原文由 Joren Van Severen 发布,翻译遵循 CC BY-SA 3.0 许可协议

那么,有什么我不知道的方法可以在 Web Worker 中的 DOM 树之外创建 DOM 元素吗?

不。

为什么不?在我看来,这不会产生并发问题,因为创建元素可以并行发生而不会出现问题。

不是为了创造它们,你是对的。但是为了将它们附加到主 document - 它们需要发送到不同的内存(就像 blob 可能的那样),以便此后工作人员无法访问它们。但是, WebWorkers 中绝对没有可用的文档处理

数据一到达(通过 ajax 在 JSON 中),我就为每一行创建一个 DOM 元素。之后,我将元素保存在一个数组中,并且只显示可见的行。

构建超过 500k 个 DOM 元素是一项繁重的任务。尝试仅为可见的行创建 DOM 元素。为了提高性能并更快地显示前几行,您还可以将它们的处理分成更小的单元并在其间使用超时。请参阅 如何阻止激烈的 Javascript 循环冻结浏览器

原文由 Bergi 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题