重排和重绘

简介: 重排和重绘

浏览器的渲染过程


1.解析HTML,生成DOM树

2.解析CSS,生成CSS规则树(CSSOM)

3.合并DOM和CSSOM,生成渲染树(Render-Tree)

4.计算渲染树的布局(Layout)

5.将布局渲染到屏幕上(paint)


什么是重排和重绘


重排:当DOM的变化引发了元素几何属性的变化,比如改变元素的宽高,元素的位置,导致浏览器不得不重新计算元素的几何属性,并重新构建渲染树,这个过程称为“重排”。


重绘:当各种盒子的位置、大小以及其他属性,例如颜色、字体大小等属性都确定下来后,浏览器根据他们的特性重新绘制一遍时,就叫重绘


简单来说,涉及元素的几何更新时,叫重排。而只涉及样式更新而不涉及几何更新时,叫重绘。对于两者来说,重排必定引起重绘,但是重绘并不一定引起重排。所以,当涉及重排时,浏览器会将上述的步骤再次执行一遍。


什么操作会引起重排和重绘


显然,触发重排的一般都是几何因素,这是比较好理解的:


  • 页面第一次渲染 在页面发生首次渲染的时候,所有组件都要进行首次布局,这是开销最大的一次重排
  • 浏览器窗口尺寸改变
  • 元素位置和尺寸发生改变的时候
  • 新增和删除可见元素
  • 内容发生改变(文字数量或图片大小等等)
  • 元素字体大小变化
  • 还有其他一些操作也可能引发重排


查询某些属性或调用某些方法


  • offset(Top|Left|Width|Height)
  • scroll(Top|Left|Width|Height)
  • client(Top|Left|Width|Height)
  • getComputedStyle()


我们可能不太理解为什么这些操作也能引起重排,这里我先简单解释一下。因为现在的浏览器已经非常完善了,会自动帮我们做一些优化。当我们用js操作DOM的时候,浏览器并不是立马执行的,而是将操作存储在一个队列中。当达到一定数量或者经过一定时间以后浏览器再统一的去执行队列中的操作。那么回到我们刚才的问题,为什么查询这些属性也会导致重排?因为当你查询这些属性时,浏览器就会强制刷新队列,因为如果不立马执行队列中的操作,有可能得到的结果就是错误的。所以相当于你强制打断了浏览器的优化流程,引发了重排。  

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    #test {
      width: 100px;
      height: 100px;
      background-color: red;
      position: relative;
    }
  </style>
</head>
<body>
  <div id="test">
 
  </div>
  <button onclick="reflow()">click</button>
  <script>
    function reflow() {
      var div = document.querySelector("#test");
      console.log(div.offsetLeft);
    }
  </script>
</body>
</html>

上述代码,当我们点击按钮后,浏览器立马重新计算CSSOM,但是并没有触发重排

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    #test {
      width: 100px;
      height: 100px;
      background-color: red;
      position: relative;
    }
  </style>
</head>
<body>
  <div id="test">
 
  </div>
  <button onclick="reflow()">click</button>
  <script>
    function reflow() {
      var div = document.querySelector("#test");
      div.style.left = '200px';
      console.log(div.offsetLeft);
      div.style.left = '100px';
      console.log(div.offsetLeft);
      div.style.left = '200px';
      console.log(div.offsetLeft);
      div.style.left = '100px';
      console.log(div.offsetLeft);
    }
  </script>
</body>
</html>


上述代码触发了4次重排

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    #test {
      width: 100px;
      height: 100px;
      background-color: red;
      position: relative;
    }
  </style>
</head>
<body>
  <div id="test">
 
  </div>
  <button onclick="reflow()">click</button>
  <script>
    function reflow() {
      var div = document.querySelector("#test");
      div.style.left = '200px';
      div.style.left = '100px';
      div.style.left = '200px';
      div.style.left = '100px';
      console.log(div.offsetLeft);
      console.log(div.offsetLeft);
      console.log(div.offsetLeft);
      console.log(div.offsetLeft);
    }
  </script>
</body>
</html>


上述代码只触发了一次重排

目录
相关文章
|
9月前
|
前端开发
重绘 ( Repaint) 和回流 ( Reflow)
首先了解 重绘 ( Repaint) 和回流 ( Reflow)其实是关乎到浏览器性能的问题 重绘和回流是渲染步骤中的⼀⼩节,但是这两个步骤对于性能影响很大 重绘和回流的过程都需要浏览器耗费大量的计算资源,过多的使用会导致网页性能下降
49 1
|
1月前
|
缓存 JavaScript 前端开发
掌握重排和重绘,让你的网页飞得更高!
掌握重排和重绘,让你的网页飞得更高!
|
1月前
|
JavaScript
重排和重绘的区别,什么情况下会触发这两种情况
重排和重绘的区别,什么情况下会触发这两种情况
12 0
|
1月前
|
JavaScript 前端开发
|
1月前
重排和重绘的区别,什么情况下会触发这两种情况?
重排和重绘的区别,什么情况下会触发这两种情况?
52 0
|
11月前
|
缓存 JavaScript 前端开发
浏览器:重绘(repaint)与回流/重排(reflow)
浏览器:重绘(repaint)与回流/重排(reflow)
73 0
|
6月前
|
移动开发 JavaScript 前端开发
重绘和重排
重绘和重排
55 0
|
7月前
|
前端开发 JavaScript
重排和重绘的区别?
重排和重绘的区别?
|
7月前
|
缓存 前端开发 JavaScript
重绘与重排(回流)
重绘与重排(回流)
42 0
|
10月前
|
缓存 JavaScript 前端开发
【怎么理解回流与重绘?以及触发场景】
【怎么理解回流与重绘?以及触发场景】
121 0