重绘与重排

浏览器渲染过程

  • HTML代码被HTML解析器解析成DOM树
  • CSS代码被css解析器解析成CSSOM树
  • 结合DOM树与CSSOM树,生成渲染树
  • 生成布局(flow),即将所有渲染树的所有节点进行平面合成
  • 将布局绘制(paint)在屏幕上

在这些过程中,生成布局与布局绘制最耗费性能,因此我们应该减少不必要的这两种操作.

重绘

重绘: 我们对DOM的修改造成元素样式的改变,但并未造成元素几何属性的变化(比如修改元素的背景色或字体颜色)。因此浏览器并不需要重新生成布局,只会重新绘制,这个过程就叫做重绘

重排

重排: 我们对DOM的修改造成了元素几何属性的变化(比如元素的位置或元素的宽高)。浏览器会重新生成布局,并重新进行绘制。所以重排会造成重绘,而重绘不一定会重排。

什么时候会触发回流或重绘?

  • 添加或删除可见的DOM元素

  • 元素的位置发生变化

  • 元素的尺寸发生变化(包括外边距、内边框、边框大小、高度和宽度等)

  • 内容发生变化,比如文本变化或图片被另一个不同尺寸的图片所替代。

  • 页面渲染初始化

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

  • 最复杂的一种:获取某些属性,引发回流

    (1) offset(Top/Left/Width/Height)
    (2) scroll(Top/Left/Width/Height)
    (3) cilent(Top/Left/Width/Height)
    (4) width,height
    (5) 调用了getComputedStyle()或者IE的currentStyle

如何减少重绘与重排

  • 减少DOM操作
    例如: 在ul中插入多个li
    一般操作:通过for循环不断创建li,并将其添加到ul中,但这样操作每次for循环都会造成重排,非常浪费性能.
<ul id="ul">
    <li></li>
  </ul>
  <script>
    var uls = document.getElementById('ul')
    for(let i = 0;i<=5;i++){
      var li = document.createElement('li')
      uls.appendChild(li)
    }
  </script>

优化操作: 先将UL设置为display:none,再对其进行操作,因为display:none上的DOM操作不会引发回流和重绘

<ul id="ul">
   <li></li>
 </ul>
 <script>
   var uls = document.getElementById('ul')
   ul.display = 'none'
   for(let i = 0;i<=5;i++){
     var li = document.createElement('li')
     uls.appendChild(li)
   }
   ul.display = 'block'
 </script>
  • 批量修改DOM元素
    例如: 给div添加样式
<div id="id">
   这是测试数据
 </div>
 <script>
   var Div = document.getElementById('id')
   Div.style.color = 'red'
   Div.style.backgroundColor = 'green'
   Div.style.fontSize = '24px'
 </script>

优化写法:避免使用JS一个样式修改完接着改下一个样式,最好一次性更改CSS样式,或者将样式列表定义为class的名称

<style>
   .add{
     color: red;
     background-color: green;
     font-size: 24px;
   }
 </style>
 <div id="id">
   这是测试数据
 </div>
 <script>
   var Div = document.getElementById('id')
   Div.classList.add('add')
 </script>
  • 减少使用以下几何属性: offsetTop,scrollTop,clientTop
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值