Javascript 有没有一种方法可以在WebWorker中创建出DOM元素?

Javascript 有没有一种方法可以在WebWorker中创建出DOM元素?,javascript,jquery,html,web-worker,Javascript,Jquery,Html,Web Worker,上下文: 我有一个web应用程序,可以处理和显示巨大的日志文件。它们通常只有大约10万行长,但可能多达400万行或更多。为了能够滚动浏览该日志文件(包括用户启动的日志文件和通过JavaScript的日志文件)并以良好的性能过滤行,我在数据到达后(通过ajax以JSON格式)立即为每行创建一个DOM元素。我发现这比在后端构建HTML的性能更好。之后,我将元素保存在一个数组中,只显示可见的行 对于最大100k线路,这只需要几秒钟,但对于500k线路(不包括下载),任何更多的都需要一分钟。我想进一步提

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

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


问题:有没有我不知道的方法,在DOM树之外,在Web Worker中创建DOM元素?若否,原因为何?在我看来,这不会产生并发问题,因为创建元素可能会并行进行,不会出现问题。

据我所知,很遗憾,web工作者无法访问DOM。

您必须了解web工作者的本质。使用线程编程很难,尤其是在共享内存的情况下;奇怪的事情会发生。JavaScript不具备处理任何类型的线程式交错的能力


webworkers的做法是没有共享内存。这显然导致了一个结论,即您不能访问DOM。

我看不出有任何理由不能使用web workers构造html字符串。但我也不认为会有多大的性能提升

这与网络工作者无关,但与您试图解决的问题有关。以下是一些可能有助于加快速度的事情:

  • 使用文档片段。在数据进入时向它们添加元素,并每隔一段时间(比如每秒一次)将片段添加到DOM中。这样,您就不必在每次加载一行文本时都触摸DOM(并导致重画)

  • 在后台加载,只在用户点击滚动区域底部时解析行

  • 那么,有没有我不知道的方法,在DOM树之外,在Web Worker中创建DOM元素

    没有

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

    不是为了创造它们,你是对的。但是,如果要将它们附加到主
    文档中
    ,则需要将它们发送到不同的内存中(就像blob可能出现的情况一样),以便以后工作人员无法访问它们。然而

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


    构建超过500k的DOM元素是一项繁重的任务。尝试仅为可见的行创建DOM元素。为了提高性能并更快地显示前几行,您还可以将它们的处理划分为更小的单元,并在其间使用超时。请参见

    好的,我对@Bergi提供的信息进行了更多的研究,并在W3C邮件列表上发现了以下讨论:

    下面的摘录回答了为什么Web Worker中无法访问XML解析器或DOM解析器的原因:

    您假设DOM实现代码都不使用任何排序 非DOM对象,或者如果它这样做了,那么这些对象将完全 线程安全。但事实并非如此,至少在壁虎身上是如此

    本例中的问题不是所涉及的同一个DOM对象 多线程。问题是不同线程上有两个DOM对象 它们都接触到了第三个物体

    例如,XML解析器必须做一些Gecko可以做的事情 只能在主线程上执行(DTD加载,立即;有 我以前见过的很少有人,但我不会马上回忆起来)


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

    因此您无法在webworker中直接创建DOM-但是,可能还有另一种选择,可以在主线程之外执行相当多的处理

    查看我刚刚创建的jsPerf:

    本质上,您可以发出具有从DOM获得的所有相同值的POJSO,并在接收到消息后将其转换为DOM对象(毕竟,这是您在返回HTML时所做的事情;POJSO只是由于不需要进一步的字符串处理而降低了开销)。通过这种方式,您甚至可以执行诸如发出事件侦听器之类的操作(例如,在事件名称前面加上“!”,并将值映射到某个模板提供的视图参数)


    同时,如果没有可用的DOM解析器,您将需要自己的东西来根据需要转换模板,或者将模板编译为快速的格式。

    您的设计中有几个反模式:

  • 创建DOM对象有相当大的开销,而且 一次就可能创造出数百万个
  • 试图让web工作人员管理DOM正是web所需要的 工人们不适合工作。它们执行所有其他操作,以便DOM事件循环保持响应
  • 您可以使用光标模式在任意大的数据集之间滚动

  • DOM向具有起始位置的工作程序发布消息