瀏覽器原理

介紹下重繪和回流(Repaint & & Reflow ),以及如何進(jìn)行優(yōu)化

參考文檔: https://mp.weixin.qq.com/s/_NrFbrucJRrA8fS40dCkow

    1. 瀏覽器渲染機(jī)制
      瀏覽器采用流式布局模型(Flow Based Layout)
      瀏覽器會(huì)把 HTML 解析成 DOM,把 CSS 解析成 CSSOM,DOM 和 CSSOM 合并就
      產(chǎn)生了渲染樹(Render Tree)。
      有了 RenderTree,我們就知道了所有節(jié)點(diǎn)的樣式,然后計(jì)算他們?cè)陧撁嫔系拇?br> 小和位置,最后把節(jié)點(diǎn)繪制到頁面上。
      由于瀏覽器使用流式布局,對(duì) Render Tree 的計(jì)算通常只需要遍歷一次就可以完
      成,但 table 及其內(nèi)部元素除外,他們可能需要多次計(jì)算,通常要花 3 倍于同
      等元素的時(shí)間,這也是為什么要避免使用 table 布局的原因之一。
    1. 重繪
      由于節(jié)點(diǎn)的幾何屬性發(fā)生改變或者由于樣式發(fā)生改變而不會(huì)影響布局的,稱為
      重繪,例如 outline, visibility, color、background-color 等,重繪的代價(jià)是高昂的,
      因?yàn)闉g覽器必須驗(yàn)證 DOM 樹上其他節(jié)點(diǎn)元素的可見性。
    1. 回流
      回流是布局或者幾何屬性需要改變就稱為回流?;亓魇怯绊憺g覽器性能的關(guān)鍵
      因素,因?yàn)槠渥兓婕暗讲糠猪撁妫ɑ蚴钦麄€(gè)頁面)的布局更新。一個(gè)元素的
      回流可能會(huì)導(dǎo)致了其所有子元素以及 DOM 中緊隨其后的節(jié)點(diǎn)、祖先節(jié)點(diǎn)元素
      的隨后的回流。
<body>
<div class="error">
  <h4>我的組件</h4>
  <p><strong>錯(cuò)誤:</strong>錯(cuò)誤的描述…</p>
  <h5>錯(cuò)誤糾正</h5>
  <ol>
    <li>第一步</li>
    <li>第二步</li>
  </ol>
</div>
</body>

在上面的 HTML 片段中,對(duì)該段落(<p>標(biāo)簽)回流將會(huì)引發(fā)強(qiáng)烈的回流,因?yàn)樗?br> 是一個(gè)子節(jié)點(diǎn)。這也導(dǎo)致了祖先的回流(div.error 和 body – 視瀏覽器而定)。
此外,<h5>和<ol>也會(huì)有簡(jiǎn)單的回流,因?yàn)槠湓?DOM 中在回流元素之后。大部
分的回流將導(dǎo)致頁面的重新渲染。

回流必定會(huì)發(fā)生重繪,重繪不一定會(huì)引發(fā)回流。

    1. 瀏覽器優(yōu)化
      現(xiàn)代瀏覽器大多都是通過隊(duì)列機(jī)制來批量更新布局,瀏覽器會(huì)把修改操作放在
      隊(duì)列中,至少一個(gè)瀏覽器刷新(即 16.6ms)才會(huì)清空隊(duì)列,但當(dāng)你獲取布局信
      息的時(shí)候,隊(duì)列中可能有會(huì)影響這些屬性或方法返回值的操作,即使沒有,瀏
      覽器也會(huì)強(qiáng)制清空隊(duì)列,觸發(fā)回流與重繪來確保返回正確的值。
      主要包括以下屬性或方法:(實(shí)時(shí)計(jì)算屬性)
      1、offsetTop、offsetLeft、offsetWidth、offsetHeight
      2、scrollTop、scrollLeft、scrollWidth、scrollHeight
      3、clientTop、clientLeft、clientWidth、clientHeight
      4、width、height
      5、getComputedStyle()
      6、getBoundingClientRect()
      所以,我們應(yīng)該避免頻繁的使用上述的屬性,他們都會(huì)強(qiáng)制渲染刷新隊(duì)列
    1. 減少重繪與回流
CSS

1、使用 transform 替代 top
2、使用 visibility 替換 display: none ,因?yàn)榍罢咧粫?huì)引起重繪,后者會(huì)引發(fā)回
流(改變了布局)
3、避免使用 table 布局,可能很小的一個(gè)小改動(dòng)會(huì)造成整個(gè) table 的重新布局。
4、盡可能在 DOM 樹的最末端改變 class,回流是不可避免的,但可以減少其影
響。盡可能在 DOM 樹的最末端改變 class,可以限制了回流的范圍,使其影響
盡可能少的節(jié)點(diǎn)。
5、避免設(shè)置多層內(nèi)聯(lián)樣式,CSS 選擇符從右往左匹配查找,避免節(jié)點(diǎn)層級(jí)過多

<div>
  <a> 
    <span></span> 
  </a>
</div>
  <style>
    span {
      color: red;
    } 
    div > a > span {
      color: red;
    }
  </style>

對(duì)于第一種設(shè)置樣式的方式來說,瀏覽器只需要找到頁面中所有的 span 標(biāo)簽
然后設(shè)置顏色,但是對(duì)于第二種設(shè)置樣式的方式來說,瀏覽器首先需要找到所
有的 span 標(biāo)簽,然后找到 span 標(biāo)簽上的 a 標(biāo)簽,最后再去找到 div 標(biāo)簽,
然后給符合這種條件的 span 標(biāo)簽設(shè)置顏色,這樣的遞歸過程就很復(fù)雜。所以
我們應(yīng)該盡可能的避免寫過于具體的 CSS 選擇器,然后對(duì)于 HTML 來說也盡
量少的添加無意義標(biāo)簽,保證層級(jí)扁平。
將動(dòng)畫效果應(yīng)用到 position 屬性為 absolute 或 fixed 的元素上,避免影響其他元
素的布局,這樣只是一個(gè)重繪,而不是回流,同時(shí),控制動(dòng)畫速度可以選擇
requestAnimationFrame,詳見探討 requestAnimationFrame。
避免使用 CSS 表達(dá)式,可能會(huì)引發(fā)回流。

將頻繁重繪或者回流的節(jié)點(diǎn)設(shè)置為圖層,圖層能夠阻止該節(jié)點(diǎn)的渲染行為影響
別的節(jié)點(diǎn),例如 will-change、video、iframe 等標(biāo)簽,瀏覽器會(huì)自動(dòng)將該節(jié)點(diǎn)變
為圖層。
CSS3 硬件加速(GPU 加速),使用 css3 硬件加速,可以讓 transform、opacity、
filters 這些動(dòng)畫不會(huì)引起回流重繪 。但是對(duì)于動(dòng)畫的其它屬性,比如
background-color 這些,還是會(huì)引起回流重繪的,不過它還是可以提升這些動(dòng)畫
的性能。
DOM離線(display:none -> ,,,,,, -> display:inline-block)

JavaScript

1、避免頻繁操作樣式,最好一次性重寫 style 屬性,或者將樣式列表定義為 class
并一次性更改 class 屬性。
2、避免頻繁操作 DOM,創(chuàng)建一個(gè) documentFragment,在它上面應(yīng)用所有 DOM
操作,最后再把它添加到文檔中。
3、避免頻繁讀取會(huì)引發(fā)回流/重繪的屬性,如果確實(shí)需要多次使用,就用一個(gè)
變量緩存起來。
4、對(duì)具有復(fù)雜動(dòng)畫的元素使用絕對(duì)定位,使它脫離文檔流,否則會(huì)引起父元素
及后續(xù)元素頻繁回流。

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

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

  • 瀏覽器架構(gòu) 用戶界面 主進(jìn)程 內(nèi)核渲染引擎JS 引擎執(zhí)行棧事件觸發(fā)線程消息隊(duì)列微任務(wù)宏任務(wù)網(wǎng)絡(luò)異步線程定時(shí)器線程 ...
    菊花泡茶閱讀 937評(píng)論 0 1
  • 前端必讀:瀏覽器內(nèi)部工作原理[https://kb.cnblogs.com/page/129756/] 作者: T...
    我是強(qiáng)強(qiáng)閱讀 1,244評(píng)論 0 2
  • 一、了解瀏覽器的意義 如果不了解瀏覽器的運(yùn)行原理,瀏覽器對(duì)于我們來說就是一個(gè)黑盒,所以我們的代碼最終運(yùn)行效果怎樣、...
    丁樂ya閱讀 332評(píng)論 0 0
  • 進(jìn)程與線程 進(jìn)程是內(nèi)存分配的最小單位,線程是CPU調(diào)度的最小單位 瀏覽器內(nèi)核——瀏覽器渲染進(jìn)程 GUI渲染線程解析...
    如沐春風(fēng)ei閱讀 361評(píng)論 0 0
  • 瀏覽器如何渲染網(wǎng)頁 要了解瀏覽器渲染頁面的過程,首先得知道一個(gè)名詞——關(guān)鍵渲染路徑。關(guān)鍵渲染路徑是指瀏覽器從最初接...
    oWSQo閱讀 33,288評(píng)論 5 74

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