淺談重繪與回流

瀏覽器的的渲染過程

渲染過程

下面我們來說說之間的具體過程:
1,瀏覽器會把html解析成DOM樹,DO樹的構(gòu)建是一個深度遍歷的過程(當前節(jié)點的所有子節(jié)點遍歷完成才會去構(gòu)建當前節(jié)點下一個兄弟節(jié)點)
2,在構(gòu)建DOM樹的同時,瀏覽器也會把css解析成css樹
3,合并DOM樹和css樹,生成render樹。在這哥過程中,瀏覽器會自動忽略 head 元素,以及display屬性為none的元素。
4,瀏覽器在拿到render樹后,計算出每個節(jié)點在屏幕中的位置。這個過程就是回流的過程
5,遍歷render樹,并且根據(jù)css的設(shè)置元素的外觀風格,這個過程就是在完成重繪的過程。

我們來看張表
表頭 回流 重繪
定義 render樹中的一部分或者全部因為大小邊距等問題發(fā)生改變而需要重建的過程叫做回流 當元素的一部分屬性發(fā)生變化,如外觀背景色不會引起布局變化而需要重新渲染的過程叫做重繪
ps:

display: none與 visibility:hidden雖然都是隱藏元素。但前者是使元素從dom結(jié)構(gòu)中消失,后者是dom中依然存在只是不在界面顯示。因此前者為回流(需要改變dom結(jié)構(gòu)),后者為重繪。

那在什么情況會發(fā)生重繪亦或是回流?

---在不同的狀況下發(fā)生及發(fā)生的程度都不一樣:
1.頁面初始渲染

  1. 改變字體,改變元素尺寸(寬,高,內(nèi)外邊距,邊框,改變元素位置等)
    各種情況:
    設(shè)置style屬性的值
    激活偽類,舉個栗子:hover
    操作class屬性
    css3的某些屬性,
    https://csstriggers.com/ 接合此處的鏈接更加深入了解,還有哪些屬性是觸發(fā)回流和重繪的
如果修改的屬性不影響布局則不會發(fā)生回流。

3.改變元素內(nèi)容(文本或圖片等或比如用戶在input框找中輸入文字)
4.添加/刪除可見的dom元素(注意:如果刪除本身就是display:none的元素是不會發(fā)生回流的)
5.fixed定位元素,在拖動滾動條的時候會一直回流

  1. 調(diào)整窗口大小 (Resizing the window)
  2. 計算offsetWidth 和 offsetHeight 屬性***
    ***:這里我們要提到一個隊列flush隊列
    瀏覽器是聰明的,當對以下屬性進行操作的時候:
    包括:offsetTop, offsetLeft, offsetWidth, offsetHeight, scrollTop, scrollLeft, scrollWidth. scrollHeight, clientTop, clientLeft, clientWidth, clientHeight, getComputedStyle()
    currentStyle in IE.
    瀏覽器不會馬上操作他們,而是會先緩存在隊列里面,有一定的時間順序去執(zhí)行這些操作,但是在這過程中我們需要去獲取在該隊中的屬性時,瀏覽器為取得正確的值就會觸發(fā)回流,這樣就使得瀏覽器的優(yōu)化失效了。
    所以我們在多次使用這些值得時候應(yīng)進行緩存。

那我們應(yīng)該如何減少回流和重繪,去提高瀏覽器的優(yōu)化的效果。

一,修改html元素中對應(yīng)的class名,利用class替換樣式
<style type = "text/css" >
.changeStyle{width: 200px;height: 200px;}
</style >
< script type = "text/javascript" >
  $(document).ready(function ()
  {
      var el = $('id');
      //1
      el.css('width', '200px');
      el.css('height', '200px');
      //2
      el.css({
          'width' : '200px;',
          'height' : '200px;'
      });
      //3 
      el.addClass('changeStyle');
  });
</script >
二,csstext(利用CSSText屬性合并所有改變,然后一次性寫入)
var s = document.body.style; 
s.padding = "2px"; // 回流+重繪
s.border = "1px solid red"; // 再一次 回流+重繪 
s.color = "blue"; // 再一次重繪
s.backgroundColor = "#ccc"; // 再一次 重繪 
s.fontSize = "14px"; // 再一次 回流+重繪 
// 添加node,再一次 回流+重繪
document.body.appendChild(document.createTextNode('abc!’));

----------------------------------------------------------------------------

// 不好的寫法
var left = 1;
var top = 1;
el.style.left = left + "px";
el.style.top = top + "px";
// 比較好的寫法 
el.className += " className1";
// 比較好的寫法 
el.style.cssText += "; left: " + left + "px; top: " + top + "px;";
三,display:none(隱藏元素,應(yīng)用修改,重新顯示)
var list = document.getElementById("list");

list.style.display = 'none’;

appendDataToElement(list,data);

list.style.display = 'block';
四,cloneNode (將原始元素拷貝到一個脫離文檔的節(jié)點中,修改副本,完成后在替換回去;)
var old = document.getElementById("list");

var clone = old.cloneNode(true);

appendDataToElement(clone,data);

old.parentNode.replaceChild(clone,old);
五,document.createDocumentFragment(); (使用文檔片段(document fragment)在當前dom之外構(gòu)建一個子樹,再插回去);
var fragment = document.createDocumentFragment();
var list = document.getElementById("list");
for (var i = 0; i < 10; i++)
{
    var _li = document.createElement("li");
    _li.onmouseover = function ()
    {
        this.style.backgroundColor = "#22b909";
        this.style.width = "120px";
        this.style.height = "50px";
    }
    _li.onmouseout = function ()
    {
        this.style.backgroundColor = "";
        this.style.width = "100px";
        this.style.height = "40px";
    }
    fragment.appendChild(_li);
}
list.appendChild(fragment);
六,使用transform

css的最終表現(xiàn)分為以下四步:Recalculate Style => Layout => Paint Setup and Paint => Composite Layers
其實就是 查找并計算樣式 => 排布 => 繪制 => 組合層。
由于transform是位于Composite Layer層, 而width,left,margin等則是位于Layout層,Layout層發(fā)生改變必定導致Paint Setup and Paint => Composite Layers,
所以相對而言使用transform實現(xiàn)的動畫效果肯定比使用改變位置的這些效果更加流暢

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容