关于回流reflow和重绘repaint的笔记
repaint(重绘) ,repaint发生更改时,元素的外观被改变,且在没有改变布局的情况下发生,如改变outline, visibility, opacity(opacity替代visibility可以减少repaint,进而优化性能),z-index, background, color,box-shadow,transform3d不会影响到dom结构渲染。
既不引起回流也不引起重绘的属性:transform, cursor, perspective, windows
https://csstriggers.com/opacity
reflow(回流,重排),与repaint区别就是他会影响到dom的结构渲染,同时他会触发repaint,他会改变他本身与所有父辈元素(祖先),这种开销是非常昂贵的,导致性能下降是必然的,页面元素越多效果越明显。
什么会引起回流?
- 页面渲染初始化
- 窗口尺寸发生改变
- DOM结构改变,比如增加或删除某个可见的节点
- 元素的位置发生改变
- 元素的尺寸发生改变(padding,margin,border, width, height)
- 内容变化,比如文本变化或者图片源发生改变
- 改变字体大小
- 激活 CSS 伪类,比如 :hover (IE 中为兄弟结点伪类的激活)
- 最复杂的一种:获取某些属性,引发回流。
- offset(Top/Left/Width/Height)
- scroll(Top/Left/Width/Height)
- cilent(Top/Left/Width/Height)
- width, height
-
scrollIntoView()、scrollIntoViewIfNeeded()
-
getComputedStyle()
-
getBoundingClientRect()
-
scrollTo()
重绘不会带来重新布局,并不一定伴随回流。回流是更明显的一种改变,渲染树需要重新计算;回流的危害在于重新对DOM树进行渲染,那么,脱离文档流(position:absolute,fixed;float:left,right)之后,进行的任何操作,都不会造成回流了。如果没有对页面进行优化(存在大量回流),那么页面因为回流所花费的时间,导致用户体验感大打折扣;只要修改DOM或修改了元素的形状或大小,就会触发Reflow,单纯修改元素的颜色只需Repaint一下(调用操作系统Native GUI的API绘制)。
回流一定伴随着重绘,重绘却可以单独出现。所以一般会有一些优化方案,如:
-
减少逐项更改样式,最好一次性更改style,或者将样式定义为class并一次性更新
-
避免循环操作dom,创建一个documentFragment或div,在它上面应用所有DOM操作,最后再把它添加到window.document
-
避免多次读取offset等属性。无法避免则将它们缓存到变量
-
将复杂的元素绝对定位或固定定位,使得它脱离文档流,否则回流代价会很高
减少回流的几点建议:
1. 减少不必要的DOM深度。因为无论你改变DOM节点树上任何一个层级都会影响节点树的每个层级——从根结点一直到修改的子节点。不必要的节点深度将导致执行回流时花费更多的时间。
2. 精简css,去除没有用处的css
3.
如果你想让复杂的表现发生改变,例如动画效果,使用position-absolute或position-fixed来实现它,也即是让其脱离文档流,不影响父级;
现代浏览器也可以使用CSS3
transition实现动画效果,比改变像素值来的高性能。
4. 避免不必要的复杂的css选择符,尤其是使用子选择器,或消耗更多的CPU去做选择器匹配。
5. 页面的元素适当定高,例如如果div内容可能有高度差异的动态内容载入; 页面刷新载入的时候,应避免页面元素的晃动、位移等,这些都是额外的重绘,会让你的CPU和风扇兴奋的
6. 图片:如果你的<img>
不设定尺寸、同时外部容器没有定死高宽,则图片在首次载入时候,占据空间会从0到完全出现,左右上下都可能位移,发生大规模的重绘。
- 构建dom树的过程即根据html代码自上而下进行构建,当遇到script文件加载/执行会阻塞后面dom树的构建(javascript可能会改变dom树),而遇到css文件,不会阻塞dom树构建,会阻塞render树的构建。
- 当浏览器遇到需要加载资源的标签时(img、video等),不会等待资源加载完成,而是继续向后渲染。(当资源加载完毕时,浏览器会重新渲染这部分)
回流&重绘:https://347830076.github.io/myBlog/javascript/%E6%B5%8F%E8%A7%88%E5%99%A8%E6%B8%B2%E6%9F%93%E5%8E%9F%E7%90%86%E6%B5%81%E7%A8%8B.html#%E5%87%8F%E5%B0%91%E5%9B%9E%E6%B5%81%E5%92%8C%E9%87%8D%E7%BB%98
添加 3D 动画硬件加速的方法
- transform
- opacity
- filters
- will-change
.item { transform: translateZ(0); /* 或者 will-change: transform; */ }