DOM的优化
由于解释JavaScript的引擎和解释DOM的引擎是相互独立的,从而导致DOM操作天生就很慢(为什么要这么做呢)将DOM单独实现,使得其他技术和语言也能够操作DOM
。
优化方式
减少访问DOM的次数
两个独立的系统只能通过接口来进行连接,相当于每进行一次DOM操作,都需要两个接口通信一次,当访问DOM的次数越多的时候,所消耗的性能也就越高了。
节点Clone
利用element.clone()
来替代element.createElement()
创建相同的元素。(提升不是特别大)
重绘和重排
浏览器下载完所有资源后,将HTML,JavaScript,CSS,图片解析生成两个数据结构
-
DOM树
表示页面结构
-
渲染树
表示DOM节点如何显示
DOM树中的每个节点都至少对应渲染中的一个节点。当DOM树和渲染树构建完成之后,浏览器就开始绘制页面元素了。
重排
元素的几何属性发生变化后,浏览器重新计算元素的几何属性,其他元素的几何属性也会因为该元素变化而改变,浏览器就会使渲染树中受到影响的部分失效,重新来构造渲染树。这个过程就是重排。
重绘
浏览器根据渲染树重新绘制受影响的部分,这个过程是重绘。
某些情况下,改变属性并不会导致重排,比如说改变元素的颜色,并没有改变几何属性就不会让元素重排。也就是常说的,重排必定重绘,重绘不一定重排。
重排的发生情况
- 添加删除可见的DOM元素
- 元素位置的改变
- 元素尺寸的改变
- 内容改变
- 页面渲染器初始化
- 浏览器窗口尺寸的改变
这几点都一个特点,都是有元素的几何属性发生了变化
由于每次重排都会产生计算的消耗,为了优化性能,现代浏览器通过队列化和批量化的执行重排过程。但是当获取布局信息时,会导致浏览器立刻去执行重排操作(浏览器为了返回最新的数据,会强制先去执行队列中的重排操作)。
- offsetTop,offsetleft,offsetWidth,offsetHeight
- scrollTop,scrollleft,scrollWidth,scrollHeight
- clientTop,clientLeft,clientWidth,clientHeight
- getComputedStyle()
重绘和重排的优化
-
减少重绘重排的发生次数
合并一些样式修改,只进行一次重绘和重排
//有可能会有三次重排 el.style.borderLeft = '1px'; el.style.padding = "1px"; el.style.borderRight = "1px"; //合并成一次 el.style.cssText = 'border-left:1px;border-right:1px;padding:1px;'
-
元素脱离文档流
当对元素进行大量修改的时候,可以先让元素脱离文档流,修改完成后在带回文档流中。整个过程只会触发了两次重排。
脱离文档流的几种方法- 隐藏元素
- 使用文档片段(document fragement)
- 将元素copy一份,在copy的这份上进行操作,操作完成后使用copy的元素替换掉原本的元素
减少直接获取布局信息的次数
-
让元素脱离动画流
在播放动画的时候,元素可能会导致大面积的重排,影响的面积越大,性能影响越大。这种情况让其他元素脱离动画流来优化性能
- 设置动画元素的为绝对定位,脱离文档流
- 动画元素移动是,只会去影响到它覆盖的一小部分页面。只会有一小部分页面的重绘,并不会产生大面积的重排
- 动画结束时恢复元素的定位,引发一次重排