多个 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 操作的主要内容,如果未能解决你的问题,请参考以下文章