瀏覽器的渲染、重繪以及回流

瀏覽器渲染

瀏覽器拿到html后會(huì)按自上而下的順序依次執(zhí)行,遇到link標(biāo)簽和img標(biāo)簽時(shí)會(huì)發(fā)送新的請(qǐng)求。渲染過(guò)程如下:

  • 瀏覽器遍歷html標(biāo)簽后生成dom樹(shù)
  • css加載完成后生成cssom樹(shù)
  • dom樹(shù)和cssom樹(shù)全部生成后一起生成render樹(shù)
  • 瀏覽器開(kāi)始計(jì)算元素位置
  • 將節(jié)點(diǎn)內(nèi)容呈現(xiàn)出來(lái)

大多數(shù)瀏覽器請(qǐng)求js文件時(shí)會(huì)暫停渲染過(guò)程以防止js文件修改dom導(dǎo)致之前的渲染做無(wú)用功,所以一般將js文件寫(xiě)在body標(biāo)簽底部。但是有些瀏覽器會(huì)幾乎同時(shí)加載css和不影響dom結(jié)構(gòu)的js,等這些文件加載后再加載剩余js文件。

重繪以及回流

定義

重繪:對(duì)某個(gè)區(qū)域、對(duì)象的重新渲染表現(xiàn)

回流:對(duì)某個(gè)區(qū)域、對(duì)象進(jìn)行重繪,根據(jù)條件影響到它的祖先對(duì)象進(jìn)入重繪(并可能無(wú)限遞歸直到頂級(jí)祖先對(duì)象)

觸發(fā)

重繪如何出現(xiàn):改變對(duì)象的形狀、坐標(biāo)、表現(xiàn)以及內(nèi)容都會(huì)引發(fā)該對(duì)象被重新渲染,這種現(xiàn)象即為重繪。

回流如何出現(xiàn):當(dāng)該對(duì)象即將重繪時(shí),瀏覽器會(huì)根據(jù)條件判斷該對(duì)象的重繪結(jié)果是否會(huì)依賴該對(duì)象的祖先元素。如果有則將該對(duì)象祖先元素也加入本次重繪。并一直向上尋找,直到條件不匹配。此現(xiàn)象即為回流。

最后總結(jié):
1、重繪可能引發(fā)回流
2、回流必定引發(fā)重繪

引發(fā)重繪和回流的操作

  • 調(diào)整窗口大小
  • 改變字體
  • 增加或者移除樣式表
  • 內(nèi)容變化,比如用戶在input框中輸入文字
  • 激活 CSS 偽類,比如 :hover (IE 中為兄弟結(jié)點(diǎn)偽類的激活)
  • 操作 class 屬性
  • 腳本操作 DOM
  • 計(jì)算 offsetWidth 和 offsetHeight 屬性
  • 設(shè)置 style 屬性的值

優(yōu)化回流

瀏覽器本身的優(yōu)化策略:瀏覽器會(huì)維護(hù)1個(gè)隊(duì)列,把所有會(huì)引起回流、重繪的操作放入這個(gè)隊(duì)列,等隊(duì)列中的操作到了一定的數(shù)量或者到了一定的時(shí)間間隔,瀏覽器就會(huì)flush隊(duì)列,進(jìn)行一個(gè)批處理。這樣就會(huì)讓多次的回流、重繪變成一次回流重繪。但有時(shí)候我們寫(xiě)的一些代碼可能會(huì)強(qiáng)制瀏覽器提前flush隊(duì)列,這樣瀏覽器的優(yōu)化可能就起不到作用了。當(dāng)你請(qǐng)求向?yàn)g覽器請(qǐng)求一些 style信息的時(shí)候,就會(huì)讓瀏覽器flush隊(duì)列。

所以我們要減少對(duì)render tree的操作(合并多次多DOM和樣式的修改),并減少對(duì)一些style信息的請(qǐng)求,盡量利用好瀏覽器的優(yōu)化策略

  • 將多次改變樣式屬性的操作合并成一次操作。
  • 將需要多次重排的元素,position屬性設(shè)為absolute或fixed,這樣此元素就脫離了文檔流,它的變化不會(huì)影響到其他元素。例如有動(dòng)畫(huà)效果的元素就最好設(shè)置為絕對(duì)定位。
  • 在內(nèi)存中多次操作節(jié)點(diǎn),完成后再添加到文檔中去。例如要異步獲取表格數(shù)據(jù),渲染到頁(yè)面??梢韵热〉脭?shù)據(jù)后在內(nèi)存中構(gòu)建整個(gè)表格的html片段,再一次性添加到文檔中去,而不是循環(huán)添加每一行。
  • 由于display屬性為none的元素不在渲染樹(shù)中,對(duì)隱藏的元素操作不會(huì)引發(fā)其他元素的重排。如果要對(duì)一個(gè)元素進(jìn)行復(fù)雜的操作時(shí),可以先隱藏它,操作完成后再顯示。這樣只在隱藏和顯示時(shí)觸發(fā)2次重排。
  • 在需要經(jīng)常取那些引起瀏覽器重排的屬性值時(shí),要緩存到變量。
  • 如果想設(shè)定元素的樣式,通過(guò)改變?cè)氐?class 名 (盡可能在 DOM 樹(shù)的最末端)
  • 避免設(shè)置多項(xiàng)內(nèi)聯(lián)樣式
  • 權(quán)衡動(dòng)畫(huà)的平滑和速度
  • 避免使用table布局
最后編輯于
?著作權(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)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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