重绘(repaint)和回流(reflow)

重绘(repaint)和回流(reflow)

首先要知道,重排一定会引起重绘,重绘不一定引起重排

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

回流:布局引擎会根据各种样式计算每个盒子在页面上的大小与位置

重绘:当计算好盒模型的位置、大小及其他属性后,浏览器根据每个盒子特性进行绘制

回流的触发时机

回流这一阶段主要是计算节点的位置和几何信息,那么 当页面布局和几何信息发生变化的时候,导致浏览器重新计算元素的几何属性,就需要回流,重新构建渲染树,有下面几种情况:

  • 页面一开始渲染的时候,就是浏览器一开始解析的时候,避免不了

  • 添加/删除DOM元素

  • 元素位置/尺寸(margin,padding,border,height,width…)/内容发生变化

  • 浏览器窗口尺寸变化(因为回流是根据视口的大小来计算元素的位置和大小的)

  • 获取一些特定属性的值的时候:

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

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

重绘的触发时机

当元素的外观属性(如颜色、背景等)发生改变,但不影响布局时的重新绘制过程。 重绘不会影响元素的几何尺寸和位置。重排一定会引起重绘,重绘不一定引起重排

  • 触发了回流时
  • 当DOM修改导致了样式的变化,并且没有影响几何属性时
  • 由于没有导致 DOM 几何属性的变化,因此元素的位置信息不需要更新,所以当发生重绘的时候,会跳过生成布局树建立图层树的阶段,直接到生成绘制列表,然后继续进行分块、生成位图等后面一系列操作

如何避免

  1. 避免频繁使用style,而是采用修改class的方式

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

    避免改变样式,使用class类名去合并样式

    <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>
    
    
  2. 批量操作DOM ,比如读取某元素的offsetWidth属性存到一个临时变量再去使用,而不是频繁使用这个计算属性;利用document.createDocumentFragment()文档片段来添加要添加的节点,处理完之后再插入到实际DOM中

  3. 使用离线DOM,先为元素设置display: none,操作结束后再把它显示出来。因为在display属性为none的元素上进行的DOM操作不会引发回流和重绘

  4. 缓存布局属性值,避免频繁读取会引发回流/重绘的属性,如果确实需要多次使用,就用一个变量缓存起来。

    // 缓存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"
    
    
  5. 使用 CSS3 动画,利用 CSS3 的transformopacityfilter这些属性可以实现合成的效果,也就是CPU加速,可以减少重绘和回流的影响。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值