DOM对象其实也是一个内存对象,为什么对DOM的操作这么慢?
其实是因为DOM操作会引起浏览器的render和paint操作,
而这两个操作比较耗时,所以造成对DOM操作比较慢。
关于render和paint的概念需要理解一下浏览器呈现一
个页面需要哪些操作。
浏览器如何呈现一个页面
一个完整的页面包含html和css以及js,从浏览器加载完这些资源文件到呈现一个完整的页面需要经过很多的步骤。
- 首先html解析器会解析html,生成一个DOM树,css解析器解析css文件同样生成一个属性结构的数据。
- dom tree和css rule tree生成render tree,render tree中的节点不仅仅包含了节点的内容,还包括节点的样式属性
- 浏览器对dom tree进行layout计算,这一步进行的操作是计算布局信息,包括各个节点的位置以及大小。
- 根据前面的结果进行页面的绘制。
哪些操作会引起浏览器的render和paint呢?
前面说到过,对DOM操作的慢是因为操作DOM的时候会引起浏览器的
render和paint,那么哪些操作会引起这些render和paint的行为呢?
- 通过js获取需要计算的DOM属性
- 添加删除DOM元素
- resize浏览器窗口大小
- css伪类的激活
- 改变字体
- 通过js修改DOM元素的样式并涉及到尺寸的改变
如何减少render和paint
离线操作DOM
当需要大量的操作DOM元素的时候,为了避免浏览器多次layout和paint,可以cloneNode,将DOM操作变成纯粹的内存操作
操作完成之后替换原来的DOM元素。如果是添加多个节点,将所有DOM节点都在内存中拼装完成之后再append到DOM中。隐藏之后再操作
对隐藏DOM元素进行操作是不会触发浏览器的layout和repaint的,其实display:none的元素根本就不会出现在render tree中,操作完成之后
再将其显示在页面上。
设置某些css样式也会造成页面的reflow和repaint, css样式对于浏览器render的影响