【前端性能优化】回流与重绘

网友投稿 1536 2022-11-18

【前端性能优化】回流与重绘

【前端性能优化】回流与重绘

目录

​​1. 浏览器页面渲染过程​​​​2. 什么是回流?​​​​3. 什么是重绘?​​​​4. 性能优化​​​​5. 两道相关面试题​​

1. 浏览器页面渲染过程

在说回流与重绘之前,先来看一下浏览器的页面渲染过程:

解析HTML文件,构建DOM树解析CSS文件,构建CSSOM树将DOM树和CSSOM树进行合并,生成渲染树计算渲染树的布局,这实际上是回流的过程将布局渲染到屏幕上,这实际上是重绘的过程

浏览器页面渲染的具体过程参考:​​《浏览器渲染原理与性能优化》​​

2. 什么是回流?

当渲染树中部分或者全部元素的尺寸、结构或者属性发生变化时,浏览器会重新渲染部分或者全部文档的过程就称为回流。

下面这些操作会导致回流:

页面的首次渲染浏览器的窗口大小发生变化元素的内容发生变化元素的尺寸或者位置发生变化元素的字体大小发生变化激活CSS伪类查询某些属性或者调用某些方法添加或者删除可见的DOM元素

在触发回流(重排)的时候,由于浏览器渲染页面是基于流式布局的,所以当触发回流时,会导致周围的DOM元素重新排列,它的影响范围有两种:

全局范围:从根节点开始,对整个渲染树进行重新布局局部范围:对渲染树的某部分或者一个渲染对象进行重新布局

3. 什么是重绘?

当页面中某些元素的样式发生变化,但是不会影响其在文档流中的位置时,浏览器就会对元素进行重新绘制,这个过程就是重绘。

下面这些操作会导致回流:

color、background 相关属性:background-color、background-image 等outline 相关属性:outline-color、outline-width 、text-decorationborder-radius、visibility、box-shadow

注意: 当触发回流时,一定会触发重绘,但是重绘不一定会引发回流。

4. 性能优化

我们可以看出,回流的代价要远比重绘大的多。

所以,对于回流,我们可以在一些时候减少回流:

操作DOM时,尽量在低层级的DOM节点进行操作不要使用​​table​​​布局, 一个小的改动可能会使整个​​table​​进行重新布局使用CSS的表达式不要频繁操作元素的样式,对于静态页面,可以修改类名,而不是样式。使用absolute或者fixed,使元素脱离文档流,这样他们发生变化就不会影响其他元素避免频繁操作DOM,可以创建一个文档片段​​documentFragment​​,在它上面应用所有DOM操作,最后再把它添加到文档中将元素先设置​​display: none​​,操作结束后再把它显示出来。因为在display属性为none的元素上进行的DOM操作不会引发回流和重绘。将DOM的多个读操作(或者写操作)放在一起,而不是读写操作穿插着写。这得益于浏览器的渲染队列机制。

浏览器针对页面的回流与重绘,进行了自身的优化——渲染队列

浏览器会将所有的回流、重绘的操作放在一个队列中,当队列中的操作到了一定的数量或者到了一定的时间间隔,浏览器就会对队列进行批处理。这样就会让多次的回流、重绘变成一次回流重绘。

上面,我们将多个读操作(或者写操作)放在一起,就会等所有的读操作进入队列之后执行,这样,原本应该是触发多次回流,变成了只触发一次回流。

5. 两道相关面试题

(1) documentFragment 是什么?用它跟直接操作 DOM 的区别是什么?

MDN中对​​documentFragment​​的解释:

DocumentFragment,文档片段接口,一个没有父对象的最小文档对象。它被作为一个轻量版的 Document使用,就像标准的document一样,存储由节点(nodes)组成的文档结构。与document相比,最大的区别是DocumentFragment不是真实 DOM 树的一部分,它的变化不会触发 DOM 树的重新渲染,且不会导致性能等问题。

当我们把一个 DocumentFragment 节点插入文档树时,插入的不是 DocumentFragment 自身,而是它的所有子孙节点。

在频繁的DOM操作时,我们就可以将DOM元素插入DocumentFragment,之后一次性的将所有的子孙节点插入文档中。

和直接操作DOM相比,将DocumentFragment 节点插入DOM树时,不会触发页面的重绘,这样就大大提高了页面的性能。

(2) 回流和重绘的触发条件?如何优化动画?

回流和重绘的触发条件,上面已经说到过了。

对于如何优化动画,我们知道,一般情况下,动画需要频繁的操作DOM,就就会导致页面的性能问题,我们可以将动画的​​position​​​属性设置为​​absolute​​​或者​​fixed​​,将动画脱离文档流,这样他的回流就不会影响到页面了。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:tk.mybatis通用插件updateByPrimaryKeySelective无法自动更新列的解决办法
下一篇:docker学习笔记(4)- 应用数据管理(容器外)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~