DOM对象自己也是一个js对象,因此严格来讲,并非操做这个对象慢,而是说操做了这个对象后,会触发一些浏览器行为,好比布局(layout)和绘制(paint)css
一个浏览器有许多模块,其中负责呈现页面的是渲染引擎模块,比较熟悉的有WebKit和Gecko等,这里也只会涉及这个模块的内容。浏览器
先用文字大体阐述下这个过程:布局
其中DOM tree和Render tree上的节点并不是一一对应,好比一个"display:none"
的节点就只会存在于DOM tree上,而不会出如今Render tree上,由于这个节点不须要被绘制。性能
paint是一个耗时的过程,然而layout是一个更耗时的过程,咱们没法肯定layout必定是自上而下或是自下而上进行的,甚至一次layout会牵涉到整个文档布局的从新计算。字体
可是layout是确定没法避免的,因此咱们主要是要最小化layout的次数。code
在考虑如何最小化layout次数以前,要先了解何时浏览器会进行layout。对象
layout(reflow)通常被称为布局,这个操做是用来计算文档中元素的位置和大小,是渲染前重要的一步。在HTML第一次被加载的时候,会有一次layout以外,js脚本的执行和样式的改变一样会致使浏览器执行layout,这也是本文的主要要讨论的内容。队列
通常状况下,浏览器的layout是lazy的,也就是说:在js脚本执行时,是不会去更新DOM的,任何对DOM的修改都会被暂存在一个队列中,在当前js的执行上下文完成执行后,会根据这个队列中的修改,进行一次layout。文档
然而有时但愿在js代码中马上获取最新的DOM节点信息,浏览器就不得不提早执行layout,这是致使DOM性能问题的主因。it
以下的操做会打破常规,并触发浏览器执行layout: