多个 Small DOM 操作 vs 一个 large DOM 操作

Posted

技术标签:

【中文标题】多个 Small DOM 操作 vs 一个 large DOM 操作【英文标题】:Multiple Small DOM operation vs One large DOM operation 【发布时间】:2012-02-03 17:25:23 【问题描述】:

这更多是关于最佳实践的问题。在尝试在 Web 应用程序中应用类似 MVC 的设计模式时,我经常发现自己想知道应该如何更新视图。

例如,如果我要更新具有 X 个元素的 View_1。是否更好:

A:遍历每个 X 元素,找出需要更新的元素,并以非常精细的粒度应用 DOM 更改。

B:使用 Model 或其他数据结构提供的数据为整个 View 及其所有封闭元素重新生成标记,并在一次 DOM 操作中替换 View_1 的根元素?

如果我弄错了,请纠正我。我听说渲染引擎通常比多个较小的 DOM 操作更有效地一次性替换大块 DOM。如果是这种情况,那么方法 B 是优越的。然而,即使使用模板引擎,我有时仍然很难避免为未更改的部分视图重写标记。

在重命名之前,我查看了 Bespin 项目的源代码。我清楚地记得他们实现了某种渲染循环机制,其中 DOM 操作被排队并以固定的时间间隔应用,就像游戏如何管理它们的帧一样。这类似于方法 A。我也可以看到这种方法背后的基本原理。以这种方式应用的小型 DOM 操作使 UI 保持响应(对于 Web 文本编辑器尤其重要)。同样,通过仅更新需要更改的元素,可以提高应用程序的效率。静态文本和美学元素可以保持不变。

这些是我支持双方的论点。你们有什么感想?我们是在某个地方寻找一种快乐的媒介,还是一种方法总体上更优越?

另外,有没有关于这个特定主题的好书/论文/网站?

(假设有问题的网络应用程序交互繁重,有许多动态更新)

【问题讨论】:

【参考方案1】:

确实,渲染引擎处理大块的更改通常比处理多个小的更改要快。

tl;dr:bespin 方式是理想的,如果可以,请在工人中进行。

根据更改量的大小,您可能希望尝试启动一个工作程序并计算工作程序内部的更改,因为长时间运行的 JS 会锁定 UI。您可以考虑使用以下流程:

    使用 dom 树的一部分以及父 ID 创建一个对象。 将对象字符串化为 JSON 开始工作 将字符串化的对象传入worker 接收并解析字符串。 努力更改您传入的 dom 树的所有必要部分。 再次对对象进行字符串化。 将对象传回主线程。 解析并提取新的 dom 树。 再次插入 dom。

如果有很多变化和一棵小树,这会更快。如果它是一棵大树并且更改很少,那么仅在真实 DOM 树的副本中进行本地更改会更快,然后一次更新 DOM。

还可以阅读有关页面速度的谷歌网站:

https://code.google.com/speed/articles/

尤其是这篇文章:

https://code.google.com/speed/articles/javascript-dom.html

【讨论】:

【参考方案2】:

在使用各种网络技术 3 年后,我想我终于在两种方法之间找到了一个很好的平衡点:虚拟 DOM

像 vdom、Elm、mithril.js 和 Facebook React 这样的库在某种程度上跟踪实际 DOM 的精简抽象,找出需要更改的内容,并尝试应用尽可能小的 DOM 更改。

例如

https://github.com/Matt-Esch/virtual-dom/tree/master/vdom

【讨论】:

以上是关于多个 Small DOM 操作 vs 一个 large DOM 操作的主要内容,如果未能解决你的问题,请参考以下文章

Virtual DOM 真的比操作原生 DOM 快吗?

Angular VS jQuery

《对象及DOM知识点及其应用1》

第二次作业动手动脑的解答

50 行代码的 HTML 编译器

DOM 操作