前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >前端性能优化 | 回流与重绘

前端性能优化 | 回流与重绘

原创
作者头像
anyup
发布2023-11-24 11:01:53
4230
发布2023-11-24 11:01:53
举报
文章被收录于专栏:精通前端精通前端

一、回流与重绘的概念

在 HTML 中,每个元素都可以理解成一个盒子,在浏览器解析过程中,会涉及到回流与重绘:

  • 回流(reflow):当DOM的结构发生改变或者某个元素的样式发生变化时,浏览器需要重新计算并重新布局(layout)页面中的元素,这个过程就称为回流。回流会导致浏览器重新计算元素的位置和大小,然后重新绘制到屏幕上,是一种相对耗费资源的操作。
  • 重绘(repaint):当页面元素的样式(如颜色、背景等)发生变,但并不影响其布局时,浏览器只需要重新绘制(repaint)这些元素,而无需重新计算元素的布局,这个过程称为重绘。重绘的性能开销较小,因只是简单地更新元素的样式。

回流和重绘都会带来性能消耗,因此在前端开发中,要尽可能减少回流和重绘的次数,以提高页面的渲染性能。

要了解回流与重绘的产生,首先需要了解浏览器解析渲染机制,如下所示:

浏览器的解析渲染机制可以分为以下几个步骤:

  1. HTML解析:当浏览器接收到 HTML 文档后,会对其进行解析。解析器会将 HTML 文档按照标签的层次结构转换成一个 DOM 树(文档对象模型)。 DOM 树表示了文档的结构,每个 HTML 标签都对应着 DOM 树中的一个节点。
  2. CSS解析:浏览器会解析 CSS 样式表,构建 CSSOM (CSS对象模型)。 CSSOM 表示了文档的样式信息,每个 CSS 样式规则都对应着 CSSOM 中的一个对象。
  3. 渲染树构建:将 DOM 树和 CSSOM 合并构建渲染树(Render Tree)。渲染树只包含需要显示的元素,隐藏的元素不会包含在渲染树中。渲染树不包含 CSS 中的一些影响布局但不显示的元素,比如:display:none的元素。
  4. 布局(Layout):布局阶段确定渲染树中每个节点的精确位置和大小,按照文档流模型进行布局。计算节点的几何属性,比如位置、大小等。
  5. 绘制(Paint):根据渲染树的布局信息,将每个节点转换为屏幕上的实际像素,通过绘制进行渲染。
  6. 栅格化(Rasterization):将绘制得到的图像划分成图块,然后将每个图块转化成屏幕上的像素。
  7. 合成(Composition):将图块按照正确的顺序合并,形成最终的页面图像。

以上步骤并非严格的顺序执行,其中一些步骤可能会并行进行,以提高效率。在渲染过程中,如果发生了样式改变,浏览器会重新执行布局和绘制操作,更新渲染结果。

所以在页面初始渲染阶段,回流不可避免的触发,可以理解成页面一开始是空白的元素,后面添加了新的元素使页面布局发生改变

当我们对 DOM 的修改引发了 DOM 几何尺寸的变化(比如修改元素的宽、高或隐藏元素等)时,浏览器需要重新计算元素的几何属性,然后再将计算的结果绘制出来

当我们对 DOM 的修改导致了样式的变化(colorbackground-color),却并未影响其几何属性时,浏览器不需重新计算元素的几何属性、直接为该元素绘制新的样式,这里仅仅触发了重绘。

二、回流与重绘的触发条件

回流的触发条件

触发条件:当渲染树中部分或者全部元素的尺寸、结构或者属性发生变化

以下这些操作会导致回流

  1. 添加或删除DOM元素:当添加、删除、修改DOM元素时,会导致整个或部分页面的布局发生变化,从而触发回流。
  2. 修改元素的位置、尺寸或层级关系:修改元素的位置、尺寸或层级关系(如改变元素的宽度、高度、margin、padding、top、left、z-index等)会导致元素重新布局,从而触发回流。
  3. 文字内容的变化:当文字内容的变化导致元素尺寸发生变化时,会触发回流。例如,动态改变一个段落的文字内容,会导致段落元素重新计算并布局。
  4. 浏览器窗口的变化:当浏览器窗口的大小变化时,需要重新计算并布局页面中的元素,从而触发回流。
  5. 获取某些元素的样式或者布局信息:例如通过JavaScript获取元素的offsetWidthoffsetHeightoffsetTopoffsetLeftscrollTopscrollLeft等属性,这些操作会导致浏览器强制进行回流。

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

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

重绘的触发条件

触发条件:当页面中某些元素的样式发生变化,但是不会影响其在文档流中的位置

以下这些操作会导致重绘

  1. 修改元素的颜色、背景色、边框颜色等样式属性:例如,将一个元素的背景色由红色改为蓝色,这样只会引发元素的重绘,而不会触发布局的改变。
  2. 修改元素的透明度:当修改元素的透明度(opacity)时,会引发元素的重绘。
  3. 改元素的文本样式:例如,修改元素的字体、字号、字重等文本样式属性,会触发元素的重绘。
  4. 添加或修改元素的阴影效果:当元素的阴影效果发生变化时,会引发元素的重绘。
  5. 修改元素的visibility属性:当修改元素的visibility属性为hiddenvisible时,会引发元素的重绘。

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

三、如何减少回流与重绘

浏览器优化机制

浏览器针对回流和重绘,本身也具备一定的优化机制,但是仅是最基础的。

  1. 批量处理:浏览器会将多次的回流和重绘操作合并为一次,减少性能开销。
  2. 延迟回流:对于多次数量的DOM操作,浏览器会将它们缓存在一起,然后一次性进行回流处理,这样可以减少回流的次数。

减少回流与重绘的措施

了解了回流与重绘的触发条件,我们可以尽量避免不该有的操作,减少回流与重绘,提高浏览器渲染性能

  1. 使用CSS动画代替JavaScript动画:CSS动画是利用浏览器的硬件加速,性能更高效。尽量使用transformopacity属性进行动画效果,避免使用会触发回流的属性,如widthheight
  2. 批量修改样式:尽量避免频繁地修改元素的样式,可以将多个样式的修改集中到一次操作中,例如使用CSS的class进行批量修改。
  3. 使用文档碎片(Document Fragment):当需要频繁地操作DOM时,可以使用文档碎片来进行缓存,然后再一次性地将文档碎片添加到DOM树中,减少回流次数。
  4. 避免强制同步布局:在读取布局相关的属性(如offsetTopoffsetLeftclientWidth等)之前,先将其缓存起来,避免多次读取导致浏览器强制进行同步布局。
  5. 使用transform和position属性:尽量使用transform属性进行元素的平移、旋转、缩放等操作,使用position属性进行定位,避免引起回流的属性,如topleftwidthheight等。
  6. 避免频繁改变窗口大小:改变窗口大小会触发回流,所以尽量避免频繁改变窗口大小。
  7. 使用节流和防抖技术:对于一些频繁触发的事件(如scrollresize),可以使用节流和防抖技术来控制事件的触发频率,减少回流和重绘。
  8. 使用translateZ触发GPU加速:对于需要频繁变动的元素,例如动画元素,可以使用translateZ(0)触发GPU加速,减少回流和重绘。

结语

在本篇文章中,我们详细探索了浏览器的回流和重绘,以及如何减少它们对页面性能的影响。回流和重绘是由于对页面进行布局和渲染的过程中,浏览器需要重新计算元素的几何信息和重新绘制元素造成的。

我们学习到了回流和重绘的定义和区别,以及触发回流和重绘的常见操作。同时,我们提供了一些减少回流和重绘的优化措施,如使用transform属性进行动画、使用position属性进行定位、缓存布局信息等。

通过采取这些措施,我们可以减少页面的回流次数,提高页面性能和用户体验。

总之,了解回流和重绘的原理,并且采取相应的优化措施,对于开发优化性能的网页和应用程序至关重要。希望通过本篇文章的内容,能够帮助大家更好地理解和应用这些知识,从而创建出更高效、流畅的用户界面。

我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、回流与重绘的概念
  • 二、回流与重绘的触发条件
    • 回流的触发条件
      • 重绘的触发条件
      • 三、如何减少回流与重绘
        • 浏览器优化机制
          • 减少回流与重绘的措施
          • 结语
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档