首页 > 其他分享 >带你认识什么是“回流重绘”

带你认识什么是“回流重绘”

时间:2022-10-09 15:22:38浏览次数:67  
标签:触发 浏览器 认识 元素 container 回流 重绘

摘要:要想减少回流和重绘的次数,首先要了解回流和重绘是如何触发的。

本文分享自华为云社区《前端页面之“回流重绘”》,作者:CoderBin。

“回流重绘”是什么?

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

  • 回流:布局引擎会根据各种样式计算每个盒子在页面上的大小与位置;
  • 重绘:当计算好盒模型的位置、大小及其他属性后,浏览器根据每个盒子特性进行绘制。

具体的浏览器解析渲染机制如下所示:

  • 解析HTML,生成DOM树,解析CSS,生成CSSOM树
  • 将DOM树和CSSOM树结合,生成渲染树(Render Tree)
  • Layout(回流):根据生成的渲染树,进行回流(Layout),得到节点的几何信息(位置,大小)
  • Painting(重绘):根据渲染树以及回流得到的几何信息,得到节点的绝对像素
  • Display:将像素发送给GPU,展示在页面上

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

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

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

如何触发

要想减少回流和重绘的次数,首先要了解回流和重绘是如何触发的。

回流触发时机

回流这一阶段主要是计算节点的位置和几何信息,那么当页面布局和几何信息发生变化的时候,就需要回流,如下面情况:

  • 添加或删除可见的DOM元素
  • 元素的位置发生变化
  • 元素的尺寸发生变化(包括外边距、内边框、边框大小、高度和宽度等)
  • 内容发生变化,比如文本变化或图片被另一个不同尺寸的图片所替代
  • 页面一开始渲染的时候(这避免不了)
  • 浏览器的窗口尺寸变化(因为回流是根据视口的大小来计算元素的位置和大小的)

还有一些容易被忽略的操作:获取一些特定属性的值。

offsetTop、offsetLeft、 offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、clientTop、clientLeft、clientWidth、clientHeight

这些属性有一个共性,就是需要通过即时计算得到。因此浏览器为了获取这些值,也会进行回流。

除此还包括getComputedStyle方法,原理是一样的。

重绘触发时机

触发回流一定会触发重绘

可以把页面理解为一个黑板,黑板上有一朵画好的小花。现在我们要把这朵从左边移到了右边,那我们要先确定好右边的具体位置,画好形状(回流),再画上它原有的颜色(重绘)。

除此之外还有一些其他引起重绘行为:

  • 颜色的修改
  • 文本方向的修改
  • 阴影的修改

浏览器优化机制

由于每次重排都会造成额外的计算消耗,因此大多数浏览器都会通过队列化修改并批量执行来优化重排过程。浏览器会将修改操作放入到队列里,直到过了一段时间或者操作达到了一个阈值,才清空队列。

当你获取布局信息的操作的时候,会强制队列刷新,包括前面讲到的offsetTop等方法都会返回最新的数据。

因此浏览器不得不清空队列,触发回流重绘来返回正确的值。

如何减少

我们了解了如何触发回流和重绘的场景,下面给出避免回流的经验:

  • 如果想设定元素的样式,通过改变元素的 class 类名 (尽可能在 DOM 树的最里层)
  • 避免设置多项内联样式
  • 应用元素的动画,使用 position 属性的 fixed 值或 absolute 值(如前文示例所提)
  • 避免使用 table 布局,table 中每个元素的大小以及内容的改动,都会导致整个 table 的重新计算
  • 对于那些复杂的动画,对其设置 position: fixed/absolute,尽可能地使元素脱离文档流,从而减少对其他元素的影响
  • 使用css3硬件加速,可以让transform、opacity、filters这些动画不会引起回流重绘
  • 避免使用 CSS 的 JavaScript 表达式

在使用 JavaScript 动态插入多个节点时, 可以使用DocumentFragment. 创建后一次插入. 就能避免多次的渲染性能。

但有时候,我们会无可避免地进行回流或者重绘,我们可以更好使用它们

例如,多次修改一个把元素布局的时候,我们很可能会如下操作。

const el = document.getElementById('el')
for(let i=0;i<10;i++) {
 el.style.top = el.offsetTop + 10 + "px";
 el.style.left = el.offsetLeft + 10 + "px";
}

每次循环都需要获取多次offset属性,比较糟糕,可以使用变量的形式缓存起来,待计算完毕再提交给浏览器发出重计算请求。

// 缓存offsetLeft与offsetTop的值
const el = document.getElementById('el') 
let offLeft = el.offsetLeft, offTop = el.offsetTop
// 在JS层面进行计算
for(let i=0;i<10;i++) {
 offLeft += 10
 offTop += 10
}
// 一次性将计算结果应用到DOM上
el.style.left = offLeft + "px"
el.style.top = offTop + "px"

我们还可避免改变样式,使用类名去合并样式。

const container = document.getElementById('container')
container.style.width = '100px'
container.style.height = '200px'
container.style.border = '10px solid red'
container.style.color = 'red'

使用类名去合并样式

<style>
 .basic_style {
 width: 100px;
 height: 200px;
 border: 10px solid red;
 color: red;
  }
</style>
<script>
 const container = document.getElementById('container')
 container.classList.add('basic_style')
</script>

前者每次单独操作,都去触发一次渲染树更改(新浏览器不会),都去触发一次渲染树更改,从而导致相应的回流与重绘过程,合并之后,等于我们将所有的更改一次性发出。

我们还可以通过通过设置元素属性display: none,将其从页面上去掉,然后再进行后续操作,这些后续操作也不会触发回流与重绘,这个过程称为离线操作。

 

点击关注,第一时间了解华为云新鲜技术~

标签:触发,浏览器,认识,元素,container,回流,重绘
From: https://www.cnblogs.com/huaweiyun/p/16772243.html

相关文章

  • 初步认识网络
     大学期间学过计算机网络这个课本,当时学的时候,虽然在学,但是里边的很多东西都没有研究明白。随着时间的推移,稀里糊涂的给忘的差不多了。 今天又花了点时间重新看了看网络......
  • 01#对数函数:认识 log 函数
    什么是对数对数用log符号来表示。根据底数的不同,log可以变换成lg、ln。lg是以10为底的对数,ln是以e为底的对数。对数长成下面这个样子,是一个以a为底,y为真数......
  • 分支和循环(if结构的认识和使用)
    1.对if结构的认识a.可以实现一段代码,在只有满足指定条件才可以运行b.语法:if(条件表达式)   {语句};注意不能再if语句后加;(分号)不然无法继续执行下去。 2.if的使用a.单个......
  • 浏览器的渲染过程、回流、重绘
    一、浏览器的渲染过程1.根据HTML生成DOM树浏览器在接收到服务器发来的HTML文件是字节形式的,首先要将字节形式的HTML组建成字符串,然后将字符串转换成token,再将token组装......
  • 回流(重排)和重绘画
    是什么?浏览器解析的DOM树和CSSOM树,接着对DOM树进行遍历,拿到DOM节点,然后再从CSSDOM树中拿到相应节点的样式,最后生成渲染树。回流:渲染树生成之后,每个节点元素的具体位置、......
  • 减少回流与重绘
    一、前情回顾在讨论回流与重绘之前,我们要知道:浏览器使用流式布局模型(FlowBasedLayout)。浏览器会把HTML解析成DOM,把CSS解析成CSSOM,DOM和CSSOM合并就产生了Render......
  • 认识 Iconfont 以及什么是 .eot、.woff、.ttf、.svg
    一、Iconfont1.概述在前端作业中,二十年前只有页面中铺满文字就算上线产品,现如今,不加点俏皮的“图标”会让页面显得很Low很Low。 图标在写这篇文章之前,我一直以为上图中......
  • 认识最大熵模型
    信息熵设\(X\)是取有限个值的随机变量,\(X\in\{x_1,x_2,\cdots,x_n\},\i=1,2,\cdots,n\),则随机变量\(X\)的熵定义为:\[H(X)=-\sum_{i=1}^nP(X=x_i)\log_aP(X=x_i)\]\(H......
  • nat 回流的试验 用于华为防火墙
    ......
  • 回流和重绘
    回流当我们对dom的修改引发了dom几何尺寸的变化(比如修改元素的宽、高或隐藏元素等),浏览器需要重新计算元素的几何属性,然后将计算的结果绘制出来,这个过程就是回流重绘......