重绘:改变色彩(不影响布局)
回流:浏览器为了重新渲染部分或者全部的文档而重新计算文档中元素的位置和几何构造的过程(影响周围元素和dom树)
1:一个dom 元素拥有 3d 或 透视变换的css 属性(persepective, transform)
2:video 标签
3:拥有3d 上下文或加速 2d 上下文的 canvas 节点
4:混合插件 flash
5:自己做的opacity 动画 或 使用一个动画 webkit 变换的元素
6:拥有 translate3d 或 translateZ 这两会使 GPU 加速的属性
7:一个包含复合层子节点的元素。(有点绕,可以这样想:其实本身整个网页页面就是一个图层,html 标签下包含着若干的标签 head, body,… 这样便满足了这个条件了)
8:元素有一个其 z-index 比它低的兄弟节点。由于 z-index 控制的是元素上下层的关系,所以当上下层关系变换的时候就需要一个图层去渲染,因此满足这个条件的元素也会被创建一个图层
但是在我的实验中发现第7 和 8是没有被变成图层的,不知道为嘛…
1:用transform 代替 top,left ,margin-top, margin-left… 这些位移属性
2:用opacity 代替 visibility,但是要同时有translate3d 或 translateZ 这些可以创建的图层的属性存在才可以阻止回流,建议:opacity 加上 transform: translateZ/3d 这个属性之后便不会发生回流和重绘了
3:不要使用 js 代码对dom 元素设置多条样式,选择用一个 className 代替之。
4:如果确实需要用 js 对 dom 设置多条样式那么可以将这个dom 先隐藏,然后再对其设置
5:不要在循环内获取dom 的样式例如:offsetWidth, offsetHeight, clientWidth, clientHeight… 这些。浏览器有一个回流的缓冲机制,即多个回流会保存在一个栈里面,当这个栈满了浏览器便会一次性触发所有样式的更改且刷新这个栈。但是如果你多次获取这些元素的实际样式,浏览器为了给你一个准确的答案便会不停刷新这个缓冲栈,导致页面回流增加。
所以为了避免这个问题,应该用一个变量保存在循环体外。
6:不要使用table 布局,因为table 的每一个行甚至每一个单元格的样式更新都会导致整个table 重新布局
7:尽可能在DOM树的最末端改变class,应该避免通过改变对包装元素类去影响子节点的显示(transform请直接操作最底层元素(奖杯))。
8:对于频繁变化的元素应该为其加一个 transform 属性,对于视频使用video 标签
9: 避免设置多层内联样式,写个外部类这样只回流一次
10: 让多次重排的元素脱离文档流比如动画,使用 position 属性的 fixed 值或 absolute 值
11: 牺牲平滑度换取速度:每次移动1像素改为每次移动3像素
12:使用will-change
属性和pointer-events:none
13:一起变化(同时修改所有需要变化的属性)
14: 既然计算offsetWidth也会引起回流,那么就拿一个变量保存它
15:使用document.createDocumentFragment()插入多个dom
16:包 括:offsetTop、offsetLeft、 offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、 clientTop、clientLeft、clientWidth、clientHeight、getComputedStyle() (currentStyle in IE)。在多次使用这些值时应进行缓存。