一、浏览器渲染原理和关键渲染路径
浏览器渲染原理:
读取html,css文本,构建DOM树。(DOM ,CSSOM)- DOMtree
关键渲染路径:
javascript(触发视觉变化) - style(样式计算,css改变) - Layout(布局)- Paint(绘制)- Composite(合层)
二、 回流与重绘, 如何避免布局抖动
布局关心的是位置和大小。(如css:height,offset改变位置,大小),所以如果只是更改background,opcity,不需要Layout(布局),只需Paint(重绘)。
回流:首次加载叫布局。再次叫回流。影响回流的操作:
1、 添加/删除 元素
2、 操作styles,display:none
3、 offsetLeft,offsetTop ,scrollTop,clientWidth。使用这些属性,会引起强制布局更新
4、 移动元素位置
5、 修改浏览器大小,字体
通过Chrome devtools,performance性能检测主线程任务查看回流的过程
连续的读写DOM属性(width,offsetTop等),会引起强制的布局更新,强制布局更新会造成页面抖动 layout thrashing
使用FastDom 解决布局抖动, https://github.com/wilsonpage/fastdom
三、复合线程(compositor thread)与图层(layers)
复合就是把页面拆成多个图层,图层之间是互不影响的。只绘制自己的那个图层,再进行复合。图层拆分默认是浏览器来做,如果某个元素对其他元素影响比较大,建立独立图层。
查看图层
2.png
四、减少重绘 repaint
可以利用图层,避免回流,只触发复合,不触发回流与重绘。可以采用如下样式代替:
position:transform:translate(x,y)
Scale:transform:scale(n)
Rotation:transform:rotate(n deg)
Opacity:Opacity : 0….1
Css属性 will-change: transform - 告诉浏览器提到单独的图层
先看一个有回流的动画
打开页面 Chrome devtools,performance 录制功能
没有回流的动画
修改css 样式
.box {
display: flex;
justify-content: space-around;
will-change: transform;
}
.box .img {
width: 300px;
height: 300px;
}
.img:hover {
transform: scale(1.5, 1);
transition: all 2s;
}
再进行performance 录制功能
查看主线程 task任务此时没有布局和绘制了,查看网页图层多了一个box图层
查看重绘:Chrome devtools ctrl shift p -> show rendering
JS操作避免回流、重绘
1、避免使用JS一个样式修改完接着改下一个样式,最好一次性更改CSS样式,或者将样式列表定义为class的名称
2、避免频繁操作DOM,使用文档片段创建一个子树,然后再拷贝到文档中
3、先隐藏元素,进行修改后再显示该元素,因为display:none上的DOM操作不会引发回流和重绘
4、避免循环读取offsetLeft等属性,在循环之前把它们存起来
5、对于复杂动画效果,使用绝对定位让其脱离文档流,否则会引起父元素及后续元素大量的回流
网友评论