代码编织梦想

一、重绘和回流

1. 定义

  • 重绘(Repaint):指的是当元素样式的改变不影响其在文档流中的位置时,浏览器会重新绘制这个元素,使其呈现新的样式,但不影响布局。
  • 回流(Reflow):指的是当元素的尺寸、位置或某些属性发生改变时,浏览器需要重新计算元素的几何属性并重新布局,然后再进行绘制,这个过程称为回流。

2. 产生原因

  • 重绘产生原因:当元素的样式属性(如颜色、背景等)发生改变,但不影响元素在文档流中的位置时,浏览器会触发重绘。
  • 回流产生原因:当元素的几何属性发生变化时,例如尺寸、位置、边距等改变,或者添加、删除、隐藏元素时,浏览器会触发回流。

3. 区别

  • 重绘不影响布局,只是重新绘制元素样式,性能开销较小。
  • 回流会触发重绘,但反之不一定,因为回流会导致布局的变化,可能会影响其他元素的位置和尺寸,性能开销较大。

二、优化回流频繁导致的性能开销

从重绘和回流的定义来看,回流是性能开销比较大的场景,而且对于会频繁触发回流的页面,性能问题更明显,导致降低渲染速度,从而出现卡顿。

2.1 常见导致回流的场景

包括但不限于:

  1. 修改元素的几何属性
  • 改变元素的尺寸(宽度、高度)
  • 改变元素的位置(top、left、right、bottom)
  • 修改元素的边框大小(border)
  • 改变元素的内边距(padding)
  • 修改元素的外边距(margin)
  • 调整元素的布局属性(display、float、position)
  1. 添加、删除、隐藏元素
  • 添加新的元素到文档中
  • 从文档中移除元素
  • 修改元素的可见性(visibility、display: none)
  1. 修改字体属性
  • 改变文字的大小(font-size)
  • 修改字体的样式(font-weight、font-style)
  • 调整文字的对齐方式(text-align、vertical-align)
  1. 获取某些布局信息
  • 获取元素的尺寸、位置等属性(offsetWidth、offsetHeight、getBoundingClientRect())
  • 计算元素的样式(clientWidth、clientHeight、scrollWidth、scrollHeight)
  1. 修改表格相关属性
  • 添加或删除表格的行、列
  • 修改表格的宽度、高度
  1. 修改 Flexbox 和 Grid 布局属性
  • 改变 Flexbox 的 flex 属性
  • 调整 Grid 的列数、行数等属性
  1. 页面的初始渲染
  • 当页面首次加载时,浏览器需要对页面进行初始化渲染,这个过程也会触发回流。
  1. 浏览器窗口尺寸变化
  • 浏览器窗口大小改变时,会触发所有元素的回流,因为页面的布局需要根据新的窗口大小重新计算。

在前端开发中,应该尽量避免频繁触发这些导致回流的场景,以提高页面的性能和用户体验。

2.2 为什么获取某些布局信息也会导致回流

  1. 获取元素的尺寸、位置等属性(offsetWidth、offsetHeight、getBoundingClientRect())
  2. 计算元素的样式(clientWidth、clientHeight、scrollWidth、scrollHeight)

这些获取布局信息的操作会导致回流的主要原因是因为浏览器需要计算元素的几何属性,而这些属性的计算需要考虑到整个文档流的布局。因此,当你获取这些属性时,浏览器会强制进行重新布局以确保返回的值是最新的。

具体来说:

  • offsetWidth 和 offsetHeight:返回元素相对于包含块的宽度和高度,包含了元素的边框和内边距,但不包括外边距和滚动条。强调,不包括外边距和滚动条。
  • clientWidth 和 clientHeight:返回元素内部可视区域的宽度和高度,不包括边框、外边距、滚动条。强调,相比 offsetHeight,clientHeight 不包括边框。
  • scrollWidth 和 scrollHeight:返回元素的内容区域的宽度和高度,包括被隐藏的部分,但不包括边框、内边距和外边距。
  • getBoundingClientRect():返回一个 DOMRect 对象,包含元素的位置、尺寸等信息。

当你调用这些属性时,浏览器需要根据当前文档流的布局重新计算元素的相关属性,如果文档流中的其他元素发生了变化,就会导致回流。因此,在性能要求较高的情况下,应该尽量减少对这些属性的频繁访问,或者在一次操作中一次性获取需要的多个属性,以减少回流的次数。

这里额外介绍一下关于 offsetHeight、clientHeight、scrollHeight 的区别:

下面是一个简单的示例:

<div id="container
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_58540586/article/details/136969130

前端性能优化第二篇-回流和重绘_raaabbit的博客-爱代码爱编程

前端性能优化第二篇-回流和重绘 先给自己持续更新的专栏打个广告,欢迎大家读一读专栏中的其他文章,戳一戳->前端性能优化 浏览器渲染过程 先请今天的主角“回流”和“重绘”在后台等一下,我们先来看看浏览器渲

getBoundingClientRect函数获取视图位置的坑-爱代码爱编程

  最近在做一个功能,把新手引导的提示定位在申请的上方,申请的位置是会根据前面功能的不展示而向前移动的,所以位置是不固定的,因此新手引导的位置要根据申请元素的位置来定位。 我使用了getBoundingClientRect函数来获取申请dom元素距离视图的距离。 getTypeHighLightDom(item) { cons

重绘和回流深入浅出-爱代码爱编程

我们首先来回顾一下渲染流水线的流程: 回流 回流也叫重排。当 Render Tree 中部分或全部, 因元素的尺寸、布局、隐藏等改变而需要重新构建,浏览器重新渲染的过程称为 回流。 页面第一次渲染(初始化)DOM树变化(如:增删节点)Render树变化(如:padding改变)浏览器窗口resize当你查询布局信息,包括offsetLeft、offs

getClientRects() 和 getBoundingClientRect() 的用法和区别-爱代码爱编程

getClientRects() getClientRects()的作用是获取元素占据页面的所有矩形区域: var rectCollection = object.getClientRects(); getClientRects() 返回一个TextRectangle集合,就是TextRectangleList对象。TextRectangle对象包含

前端性能优化小结-爱代码爱编程

前言 移动互联网时代,用户对于网页的打开速度要求越来越高。首屏作为直面用户的第一屏,其重要性不言而喻。优化用户体验更是我们前端开发非常需要 focus 的东西之一。 从用户的角度而言,当打开一个网页,往往关心的是从输入完网页地址后到最后展现完整页面这个过程需要的时间,这个时间越短,用户体验越好。所以作为网页的开发者,就从输入url到页面渲染呈现这个过程中

你了解getBoundingClientRect()?-爱代码爱编程

getBoundingClientRect()方法 今天朋友问到了这个方法,为了防止以后使用忘记,先写下来,哦哈哈哈哈~。 官方解释:Element.getBoundingClientRect()方法返回元素的大小及其相对于视口的位置。 语法:rectObject = object.getBoundingClientRect(); 返回对象:DOM