DOM操作与性能优化

我们总是在强调DOM操作是很慢的,尽量避免过多的去操作DOM,所以React的virtual DOM出现很是改变前端的整个想法吧。但是其中的原理呢?此文就此做一探讨。

DOM即Document Object Model,文档对象模型,DOM可以以一种独立于平台和语言的方式访问和修改一个文档的内容和结构。换句话说,这是表示和处理一个HTML或XML文档的常用方法。文档对象模型 (DOM) 是一个平台,一个中立于语言的应用程序编程接口 (API),允许程序访问并更改文档的内容、结构和样式。通过 JavaScript,您可以重构整个 HTML 文档。您可以添加、移除、改变或重排页面上的项目。要改变页面的某个东西,JavaScript 就需要获得对 HTML 文档中所有元素进行访问的入口。这个入口,连同对 HTML 元素进行添加、移动、改变或移除的方法和属性,都是通过文档对象模型来获得的(DOM)。

https://www.w3.org/DOM/#what W3文档

为什么DOM操作很慢

http://www.html5rocks.com/zh/tutorials/internals/howbrowserswork/

从上文中,学到了很多:

上图为,呈现引擎工作流程

以webkit来解释下面的一切。

关注点在于:DOM tree 、 Render tree 、 painting

https://leozdgao.me/why-dom-slow/ 这篇文章已经讲的很好了。

简单的讲就是: 我们操作DOM和其它东西是会引起layout的,而layout是很耗时的,会引起整个页面的重新渲染。所以也可以使用一些手段避免太多次的layout。

触发浏览器执行layout:

  • 通过js获取需要计算的DOM属性
  • 添加或删除DOM元素
  • resize浏览器窗口大小
  • 改变字体
  • css伪类的激活,比如:hover
  • 通过js修改DOM元素样式且该样式涉及到尺寸的改变

https://csstriggers.com/ 通过这网站了解哪些操作会引起layout

layout

布局是一个递归的过程。它从根呈现器(对应于 HTML 文档的 元素)开始,然后递归遍历部分或所有的框架层次结构,为每一个需要计算的呈现器计算几何信息。

一般情况下,浏览器的layout是lazy的,也就是说:在js脚本执行时,是不会去更新DOM的,任何对DOM的修改都会被暂存在一个队列中,在当前js的执行上下文完成执行后,会根据这个队列中的修改,进行一次layout。这也很重要的一个点。

Dirty 位系统

避免对所有细小更改都进行整体布局,浏览器采用了一种“dirty 位”系统。如果某个呈现器发生了更改,或者将自身及其子代标注为“dirty”,则需要进行布局。理解为脏检查。

有两种标记:“dirty”和“children are dirty”。“children are dirty”表示尽管呈现器自身没有变化,但它至少有一个子代需要布局。

全局布局和增量布局

所以就是可以局部更新,那么VD就好理解了。

全局布局是指触发了整个呈现树范围的布局,触发原因可能包括:

  • 影响所有呈现器的全局样式更改,例如字体大小更改。
  • 屏幕大小调整。

其中还涉及细节的优化,就不详谈了。

绘制

绘制也分为:全局绘制和增量绘制。详细内容当然看HTML5rock的原文了。

一些优化

  • 缓存选择器的结果,减少DOM查询
  • 少DOM元素的嵌套深度并优化css,去除无用的样式对减少layout的计算量
  • 在DOM查询时,querySelector和querySelectorAll应该是最后的选择,它们功能最强大,但执行效率很差,如果可以的话,尽量用其他方法替代。

https://jsperf.com/getelementsbyclassname-vs-queryselectorall/162 DOM查询效率比较
https://jsperf.com/getelementbyid-vs-queryselector/218

React和其它的比较

性能比较:对几种方式做简单了解即可,毕竟只是做了简单的实践而已,写的太少了。自己去对比没有什么意义。

  • 初始渲染:Virtual DOM > 脏检查 >= 依赖收集
  • 小量数据更新:依赖收集 >> Virtual DOM + 优化 > 脏检查(无法优化) > Virtual DOM 无优化
  • 大量数据更新:脏检查 + 优化 >= 依赖收集 + 优化 > Virtual DOM(无法/无需优化)>> MVVM 无优化

参考: http://www.alloyteam.com/2015/10/react-virtual-analysis-of-the-dom/

其余优化手段

既然讲了性能优化,那么再看下常常谈论的优化手段也是很有必要的。

基本的就是所熟知的雅虎出的性能优化规则吧:

分开来看就是:网络方面的优化、图片优化、css优化、JS优化、渲染优化

参考: