每日一句
The moon lightens the dark sky while many lanterns shine bright colors on the earth.
释义:天上明月高照,地上彩灯万盏。
一旦渲染树构建完成,就要开始绘制(paint)页面元素了。
概念
当DOM的变化引发了元素几何属性的变化,比如改变元素的宽高,元素的位置,导致浏览器不得不重新计算元素的几何属性,并重新构建渲染树,这个过程称为“重排”或叫“回流”。完成重排后,要将重新构建的渲染树渲染到屏幕上,这个过程就是“重绘”。
简单的说,重排负责元素的几何属性更新,重绘负责元素的样式更新。而且,重排必然带来重绘,但是重绘未必带来重排。比如,改变某个元素的背景,这个就不涉及元素的几何属性,所以只发生重绘。
重绘repaint 或 redraw
重绘触发条件:比如元素的外观属性color,background-color等
会导致重绘的属性
| 属性: | -- | -- | -- |
|---|---|---|---|
| color | border-style | visibility | background |
| text-decoration | background-image | background-position | background-repeat |
| outline-color | outline | outline-style | border-radius |
| outline-width | box-shadow | background-size |
重排reflow
触发重排的条件:任何页面布局和几何属性的改变都会触发重排
-
1、页面渲染初始化;(无法避免)
-
2、添加或删除可见的DOM元素;
-
3、元素位置的改变,或者使用动画;
-
4、元素尺寸的改变——大小,外边距,边框;
-
5、浏览器窗口尺寸的变化(resize事件发生时);
-
6、填充内容的改变,比如文本的改变或图片大小改变而引起的计算值宽度和高度的改变;
-
7、读取某些元素属性:
| 引起回流属性和方法 | -- | -- | -- |
|---|---|---|---|
| width | height | margin | padding |
| display | border-width | border | position |
| overflow | font-size | vertical-align | min-height |
| clientWidth | clientHeight | clientTop | clientLeft |
| offsetWidth | offsetHeight | offsetTop | offsetLeft |
| scrollWidth | scrollHeight | scrollTop | scrollLeft |
| scrollIntoView() | scrollTo() | getComputedStyle() | |
| getBoundingClientRect() | scrollIntoViewIfNeeded() |
为什么获取一些属性或调用方法也会导致回流?
因为以上属性和方法都需要返回最新的布局信息,因此浏览器不得不触发回流重绘来返回正确的值。
操作DOM其实是非常耗性能的,所以我们不仅要避免去操作DOM,还要减少访问DOM的次数。
如何优化,提升网页性能
如何减少重排(Reflow)与重绘(Repaint)?
具体:
-
合并对
DOM样式的修改,采用css class来修改 -
需要对DOM进行多次访问,尽量使用局部变量缓存该DOM
-
避免使用table布局,可能很⼩的⼀个⼩改动会造成整个table的重新布局
-
CSS选择符从右往左匹配查找,避免节点层级过多
-
DOM离线处理,减少回流重绘次数
使用
display: none,上面我们说到了 (display: none) 将元素从渲染树中完全移除,元素既不可见,也不是布局的组成部分,之后在该DOM上的操作不会触发回流与重绘,操作完之后再将display属性改为显示,只会触发这一次回流与重绘。
visibility : hidden的元素只对重绘有影响,不影响重排。
-
通过documentFragment 创建一个
dom文档片段,在它上面批量操作dom,操作完成之后,再添加到文档中,这样只会触发一次重排。 -
使用
absoult或fixed让元素脱离普通文档流,使用绝对定位会使的该元素单独成为渲染树中body的一个子元素,重排开销比较小,不会对其它节点造成太多影响。 -
使用css3硬件加速,可以让
transform、opacity、filters这些动画不会引起回流重绘 。但是对于动画的其它属性,比如background-color这些,还是会引起回流重绘的,不过它还是可以提升这些动画的性能。
常见的触发硬件加速的css属性:
transform、opacity、filters、 Will-change
- 图层能够阻⽌该节点的渲染⾏为影响别的节点。⽐如对于
video标签来说,浏览器会⾃动将该节点变为图层。