回流与重绘

发布于 2021-03-18  40 次阅读


回流:当render tree的一部分或者全部元素因改变了自身的宽高,布局,显示或隐藏,或元素内部的文字结构发生变化,导致需要重新构建页面的时候,回流就产生了。如设置width为100%,而拉动浏览器改变屏幕大小时.

重绘:当一个元素自身的宽高,布局,及显示或隐藏没有改变,而只是改变了元素的外观风格的时候,就产生了重绘。

结论:回流必定触发重绘,而重绘不一定出发回流。

如何避免回流:1、不使用能够触发回流的属性;2、建立一个图层,让回流在图层里面进行,限制回流和重绘的范围,减少浏览器的运算工作量。

有哪些可替换的属性可以优化回流与重绘呢,一共有一下9点:
1:用transform 代替 top,left ,margin-top, margin-left... 这些位移属性
2:用opacity 代替 visibility,但是要同时有translate3d 或 translateZ 这些可以创建的图层的属性存在才可以阻止回流
但是第二点经过我的实验,发现如果不加 transform: translateZ(0) 配合opacity的话还是会产生回流的,而只用visibility 就只会产生重绘不会回流
而  opacity 加上 transform: translateZ/3d  这个属性之后便不会发生回流和重绘了
3:不要使用 js 代码对dom 元素设置多条样式,选择用一个 className 代替之。
4:如果确实需要用 js 对 dom 设置多条样式那么可以将这个dom 先隐藏,然后再对其设置
5:不要在循环内获取dom 的样式例如:offsetWidth, offsetHeight, clientWidth, clientHeight... 这些。浏览器有一个回流的缓冲机制,即多个回流会保存在一个栈里面,当这个栈满了浏览器便会一次性触发所有样式的更改且刷新这个栈。但是如果你多次获取这些元素的实际样式,浏览器为了给你一个准确的答案便会不停刷新这个缓冲栈,导致页面回流增加。
所以为了避免这个问题,应该用一个变量保存在循环体外。
6:不要使用table 布局,因为table 的每一个行甚至每一个单元格的样式更新都会导致整个table 重新布局
7:动画的速度按照业务按需决定
8:对于频繁变化的元素应该为其加一个 transform 属性,对于视频使用video 标签
9:必要时可以开启 GPU 加速,但是不能滥用


一沙一世界,一花一天堂。君掌盛无边,刹那成永恒。