浏览器渲染流程为:
- 1.解析HTML Source 生成DOM树
- 2.解析CSS 生成CSSDOM树
- 3.将DOM树和CSSOM树结合 取出不可见元素 生成渲染树(Render Tree)
- 4.Layout(布局): 根据生成的渲染树 进行布局 得到节点的几何信息(宽度、高度和位置等)
- 5.Painting(重绘): 根据渲染树以及回流得到的集合信息 将REnder Tree 的每个像素渲染到屏幕上
什么是重绘(repaints)
- 当渲染树的一些元素需要更新属性 而这些属性只是修改样式外观风格的(比如颜色.背景色等),不会影响网页布局的 这就被成为重绘。 引起重绘的一些行为:
- 颜色的修改
- 文本方向的修改
- 阴影的修改
注: 回流必定引起重绘,而重绘不一定引起回流 由此看来: 回流的代价比重绘更高
什么是回流(reflow)
- 当渲染树(Render Tree)中的一部分或者全部 因为元素的规模尺寸、布局、隐藏等改变而需要重新构建布局,这就是回流。
- 每个页面至少会回流一次 也就是 网页首次加载时的一次
- 回流时 浏览器会使渲染树中受到影响的部分失效 并重新构造这部分渲染树
- 回流完成后 浏览器会重新绘制受影响的部分 这是重绘过程
回流触发时机举例:
-
添加或者删除可见的DOM元素
-
元素的位置发生变化
-
元素的尺寸发生变化(包括内外边距、边框大小、高宽度等)
-
内容发生变化 (如文本变化或图片被另一个不同尺寸的图片所替代)
-
页面一开始加载的时候
-
浏览器窗口尺寸发生变化 这时候网页布局会根据视口的大小重新计算元素位置和大小 再编排
-
还有容易被忽略的操作: 获取一些特定属性的值
三大家族:
1. offsetTop、offsetLeft、 offsetWidth、offsetHeight
2. scrollTop、scrollLeft、scrollWidth、scrollHeight
3. clientTop、clientLeft、clientWidth、clientHeight
这些属性有一个共性,就是需要通过即时计算得到。因此浏览器为了获取这些值,也会进行回流
如何避免和减少回流与重绘
- 减少对渲染树的操作 ]
- 减少对一些style信息的请求 尽量利用好浏览器的优化策略
- 添加css样式 而不是 使用js控制样式
- 将需要多次重排的元素 使用 position 或者 fixed 固定好位置 让元素脱离文档流 他的变化不会影响带其他元素
- 尽量不要使用table布局 因为表格里的内容量不好把控
- IE中避免使用 JavaScript 表达式
- 让元素脱离动画流 减少回流的 渲染树 的规模
- 尽量将需要改变DOM的操作一次完成