【读书笔记】高性能JavaScript:最小化重排和重绘
当浏览器下载完所有组件后,会生成两个树: DOM树和渲染树,DOM树描述的是节点的结构,而渲染树则描述DOM树如何展示,所以DOM树的变化会影响渲染树。
当我们的DOM操作影响了元素的几何属性,比如说宽高。浏览器会使渲染树中受影响部分失效,并且重新构造渲染树,这个过程叫做重排,重排结束后,浏览器会重新渲染受影响部分内容到屏幕,这过程叫做重绘。
而重排和重绘都会造成严重的性能消耗。
解决这部分问题主要有三种方式:
1、改变元素的display属性,从文档中(dom树)临时删除元素,修改完元素后再次挂载。
var myDom = document.getElementById('myDom')
myDom.style.display = "none"
appendDataToElement(myDom,data)// 封装的改变DOM方法
myDom.style.display = "block"
2、创建文档片段
var fragment = document.createDocumentFragment()
appendDataToElement(fragment,data)// 封装的改变DOM方法
document.getElementById('myDom').appendChild(fragment)
3、为修改部分创建一个备份
var old = document.getElementById('myDom')
var clone = old.cloneNode(true)
appendDataToElement(clone,data)// 封装的改变DOM方法
old.parentNode.replaceChild(clone,old)
不可否认的上述方法仍然会使浏览器重排重绘,但当需要大量DOM操作时,上述方法能够大大的减少浏览器的重排重绘,从而提高性能。
此外通过上述代码,我们可以看见上述的核心在于让需要修改的DOM 元素脱离文档流,修改完成后再次插入原来的位置,所以还有其他很多的 方法同样可以实现相同的效果。
注: 通过上面的例子,我们还可以针对减少重排重绘提出更多的性能优化方案,如,我们经常会做出一些下拉菜单,又是这可能会将此菜单下面的所有元素往下推,毫无疑问的这回极大的消耗性能,所有更优的做法是使用css的定位属性,使得下拉菜单脱离文档流,这样需要重绘的元素就大大减少了。
注:文章转自《高性能JavaScript》一书,并加上自己的部分描述