渲染过程:
1. 解析HTML(HTML Parser)
2. 构建DOM树(DOM Tree)
3. 构建渲染树(Render Tree)
4. 绘制渲染树(Painting)
解释:
通过请求得到的 HTML 经过解析(HTML parser)生成 DOM Tree。而在 CSS 解析完毕后,需要将解析的结果与 DOM Tree 的内容一起进行分析建立一棵 Render Tree,最终用来进行绘图(Painting)。
图示:
回流(reflow)与重绘(repaint)
回流(reflow)
当渲染树(render Tree)中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建。这就称为回流(reflow),也就是重新布局(relayout)。
每个页面至少需要一次回流,就是在页面第一次加载的时候。在回流的时候,浏览器会使渲染树中受到影响的部分失效,并重新构造这部分渲染树,完成回流后,浏览器会重新绘制受影响的部分到屏幕中,该过程成为重绘。
重绘(repaint)
当render tree中的一些元素需要更新属性,而这些属性只是影响元素的外观,风格,而不会影响布局的,比如 background-color 。则就叫称为重绘。
值得注意的是,回流必将引起重绘,而重绘不一定会引起回流。
明显,回流的代价更大,简单而言,当操作元素会使元素修改它的大小或位置,那么就会发生回流。
回流何时触发:
- 调整窗口大小(Resizing the window)
- 改变字体(Changing the font)
- 增加或者移除样式表(Adding or removing a stylesheet)
- 内容变化,比如用户在input框中输入文字(Content changes, such as a user typing text in an input box)
- 激活 CSS 伪类,比如 :hover (IE 中为兄弟结点伪类的激活)(Activation of CSS pseudo classes such as :hover (in IE the activation of the pseudo class of a sibling))
- 操作 class 属性(Manipulating the class attribute)
- 脚本操作 DOM(A script manipulating the DOM)
- 计算 offsetWidth 和 offsetHeight 属性(Calculating offsetWidth and offsetHeight)
- 设置 style 属性的值 (Setting a property of the style attribute)
所以对于页面而言,我们的宗旨就是尽量减少页面的回流重绘,简单的一个栗子:
// 下面这种方式将会导致回流reflow两次 var newWidth = aDiv.offsetWidth + 10; // Read aDiv.style.width = newWidth + ‘px‘; // Write var newHeight = aDiv.offsetHeight + 10; // Read aDiv.style.height = newHeight + ‘px‘; // Write // 下面这种方式更好,只会回流reflow一次 var newWidth = aDiv.offsetWidth + 10; // Read var newHeight = aDiv.offsetHeight + 10; // Read aDiv.style.width = newWidth + ‘px‘; // Write aDiv.style.height = newHeight + ‘px‘; // Write
上面四句,因为涉及了 offsetHeight 操作,浏览器强制 reflow 了两次,而下面四句合并了 offset 操作,所以减少了一次页面的回流。
减少回流、重绘其实就是需要减少对渲染树的操作(合并多次多DOM和样式的修改),并减少对一些style信息的请求,尽量利用好浏览器的优化策略。
文章节选:http://www.cnblogs.com/coco1s/p/5439619.html