摘要:回流重繪及其優(yōu)化渲染過(guò)程渲染引擎通過(guò)通過(guò)網(wǎng)絡(luò)請(qǐng)求接收渲染內(nèi)容解析抽象抽象出布局繪畫抽象渲染引擎的第一步是解析文檔并將解析的元素轉(zhuǎn)換為樹(shù)中的實(shí)際節(jié)點(diǎn)。
回流、重繪及其優(yōu)化 渲染過(guò)程
渲染引擎通過(guò)通過(guò)網(wǎng)絡(luò)請(qǐng)求接收渲染內(nèi)容
解析HTML抽象DOM tree
抽象出Render tree
布局(layout)render tree
繪畫render tree
抽象DOM tree渲染引擎的第一步是解析html文檔并將解析的元素轉(zhuǎn)換為dom樹(shù)中的實(shí)際dom節(jié)點(diǎn)。抽象CSSOM tree
當(dāng)瀏覽器解析dom的時(shí)候,遇到link標(biāo)簽,引用外部的css樣式表,引擎會(huì)將css抽象成cssom構(gòu)建渲染樹(shù)
HTML中的可視指令與來(lái)自cssom樹(shù)的樣式數(shù)據(jù)結(jié)合使用來(lái)創(chuàng)建渲染樹(shù)。
為了構(gòu)建渲染樹(shù),瀏覽器大致如下:
從dom樹(shù)的根開(kāi)始,遍歷每個(gè)可見(jiàn)節(jié)點(diǎn)。某些節(jié)點(diǎn)不可見(jiàn)(例如,腳本標(biāo)記,元標(biāo)記等),并且由于它們未反映在呈現(xiàn)的輸出中而被省略。display:none 也會(huì)使節(jié)點(diǎn)省略
對(duì)于每個(gè)可見(jiàn)節(jié)點(diǎn),瀏覽器找到適當(dāng)?shù)钠ヅ鋍ssom規(guī)則并應(yīng)用它們
它會(huì)發(fā)布帶有內(nèi)容和計(jì)算樣式的可見(jiàn)節(jié)點(diǎn)
每個(gè)渲染器代表一個(gè)矩形區(qū)域,通常對(duì)應(yīng)于一個(gè)節(jié)點(diǎn)的CSS框。
它包括幾何信息,如寬度,高度和位置
渲染樹(shù)的布局當(dāng)渲染器被創(chuàng)建并添加到樹(shù)中時(shí),它沒(méi)有位置和大小。計(jì)算這些值稱為布局。繪制渲染樹(shù)html使用基于流的布局模型,這意味著大多數(shù)時(shí)候它可以一次性計(jì)算幾何。坐標(biāo)系相對(duì)于根渲染器。使用頂部和左側(cè)坐標(biāo)。
布局是一個(gè)遞歸過(guò)程,從根元素開(kāi)始,也就是html,每個(gè)渲染器都會(huì)去計(jì)算他自己的位置和大小
在這個(gè)階段,遍歷渲染器樹(shù),調(diào)用渲染器的paint()方法在屏幕上顯示內(nèi)容。
渲染分為全局渲染和增量渲染
處理腳本和樣式表的順序當(dāng)解析器到達(dá)script標(biāo)記時(shí),腳本將被立即解析并執(zhí)行。
文檔的解析將暫停,直到腳本執(zhí)行完畢。
這意味著該過(guò)程是同步的
這也是為什么把script標(biāo)簽放在body結(jié)束之前
html5添加了一個(gè)選項(xiàng),將腳本標(biāo)記為異步,以便它可以被其他線程解析和執(zhí)行。
回流和重繪(reflow和repaint)回流: 意味著元素的內(nèi)容、結(jié)構(gòu)、位置或尺寸發(fā)生了變化,需要重新計(jì)算樣式和渲染樹(shù);
重繪:意味著元素發(fā)生的改變只影響了節(jié)點(diǎn)的一些樣式(背景色,邊框顏色,文字顏色等),只需要應(yīng)用新樣式繪制這個(gè)元素就可以了;
何時(shí)觸發(fā)回流和重繪
repaint重繪:
reflow回流必定引起repaint重繪,重繪可以多帶帶觸發(fā)
背景色、顏色、字體改變(注意:字體大小發(fā)生變化時(shí),會(huì)觸發(fā)回流)
reflow回流:
頁(yè)面第一次渲染(初始化)
DOM樹(shù)變化(如:增刪節(jié)點(diǎn))
Render樹(shù)變化(如:padding改變)
瀏覽器窗口resize
當(dāng)你查詢布局信息,包括offsetLeft、offsetTop、offsetWidth、offsetHeight、 scrollTop/Left/Width/Height、clientTop/Left/Width/Height、調(diào)用了getComputedStyle()或者IE的currentStyle時(shí),瀏覽器為了返回最新值,會(huì)觸發(fā)回流。
優(yōu)化渲染性能,減少回流和重繪減少reflow和repaint
盡量避免改變布局屬性。如width, height, left, top。
除了transforms 或者 opacity屬性都會(huì)引起重繪,做動(dòng)畫的時(shí)候要注意,盡量使用這兩個(gè)屬性;
使用Flexbox。
避免多次讀取部分布局屬性(同上)
將復(fù)雜的節(jié)點(diǎn)元素脫離文檔流,降低回流成本
javascript
避免使用setTimeout setInterval 來(lái)更新視圖,這會(huì)在render之后提交修改需求
在micro-tasks中修改dom。這會(huì)在render之前提交修改需求
把script標(biāo)簽放在body結(jié)束之前,或者使用異步script(defer, async)
把計(jì)算量大的js放在workers執(zhí)行,例如解析一個(gè)大的json文件
CSS
減少選擇器的復(fù)雜性。
避免逐個(gè)修改節(jié)點(diǎn)樣式,盡量一次性修改,減少style修改所影響元素的數(shù)量,使用cssText來(lái)替代要多次修改的style屬性
// 設(shè)置單個(gè)屬性 elt.style.color = "blue"; // 在單個(gè)語(yǔ)句中設(shè)置多個(gè)樣式 elt.style.cssText = "color: blue; border: 1px solid black"; // 在單個(gè)語(yǔ)句中設(shè)置多個(gè)樣式 elt.setAttribute("style", "color:red; border: 1px solid blue;");
通過(guò)改變類名來(lái)修改樣式
DOM
使元素脫離文檔流
對(duì)其應(yīng)用多重修改
把元素帶回文檔中
這個(gè)過(guò)程會(huì)觸發(fā)兩次回流,第一步和第三步。把會(huì)觸發(fā)多次回流的步驟放在第二步
三種基本方法:
display:none,然后修改樣式,然后在恢復(fù)
使用文檔片段(document fragment)在當(dāng)前dom樹(shù)之外構(gòu)建一個(gè)子樹(shù),再把他拷貝回文檔。
var fragment = document.createDocumentFragment() ... 在這里進(jìn)行dom操作,可以減少回流和重繪的次數(shù) document.getElementById("#app").appendChild(fragment)
將原始元素拷貝到一個(gè)脫離文檔的節(jié)點(diǎn)中,修改副本,完成后替換原始元素
var old = document.getElementById("#app") var clone = old.cloneNode(true) ... 在這里進(jìn)行dom操作,可以減少回流和重繪的次數(shù) old.parentNode.replaceChild(clone, old)
緩存布局信息
前面提到在查詢布局信息(offsetLeft...)的時(shí)候也會(huì)引起回流,我們?cè)谑褂玫臅r(shí)候可以把布局信息緩存起來(lái),減少回流次數(shù)
這里貼上<<高性能javascript>>中的例子:把myElement元素沿對(duì)角線移動(dòng),每次移動(dòng)一個(gè)像素,從100100的位置開(kāi)始,到500500的位置結(jié)束。在timeout循環(huán)體中你可以使用下面的方法
// 低效的 myElement.style.left = 1 + myElement.offsetLeft + "px" myElement.style.top = 1 + myElement.offsetTop + "px" if (myElement.offsetTop >= 500) { stopAnimation(); }
// 優(yōu)化 // 在循環(huán)外層獲取初始值 var current = myElement.offsetLeft . . . // 直接使用current變量,不再查詢偏移量 current++ myElement.style.left = current + "px" myElement.style.top = current + "px" if (current >= 500) { stopAnimation(); }
使元素進(jìn)行動(dòng)畫效果的時(shí)候脫離文檔流
在元素發(fā)生動(dòng)畫效果的時(shí)候,會(huì)引起底部元素的回流,這個(gè)影響可能很大,也可能很小,取決于元素在文檔流的位置
動(dòng)畫元素使用絕對(duì)定位,使其脫離文檔流
這里再進(jìn)行旋轉(zhuǎn),跳躍,都不會(huì)影響到整個(gè)頁(yè)面的回流
在動(dòng)畫結(jié)束時(shí)恢復(fù)定位,從而只會(huì)下移一次文檔的其他元素。
參考DOM操作成本到底高在哪兒
參考高性能javascript
參考How JavaScript works: the rendering engine and tips to optimize its performance
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/113095.html
摘要:何時(shí)發(fā)生有大量的用戶行為以及潛在的改變會(huì)觸發(fā)回流。這樣就會(huì)讓多次的回流重繪變成一次回流重繪。因?yàn)樯系牟僮鞑粫?huì)引發(fā)回流和重繪。參考文章回流與重繪性能讓變慢參考文章瀏覽器的重繪與重排 推薦了解的知識(shí):基本的HTML,基本的JavaScript,以及一些css工作原理方面的知識(shí) 瀏覽器的渲染原理 css的加載和解析不會(huì)阻塞html文檔的解析 css的解析會(huì)阻塞js的執(zhí)行,必須等到CSSOM...
摘要:回流重繪及其優(yōu)化渲染過(guò)程渲染引擎通過(guò)通過(guò)網(wǎng)絡(luò)請(qǐng)求接收渲染內(nèi)容解析抽象抽象出布局繪畫抽象渲染引擎的第一步是解析文檔并將解析的元素轉(zhuǎn)換為樹(shù)中的實(shí)際節(jié)點(diǎn)。 回流、重繪及其優(yōu)化 渲染過(guò)程 渲染引擎通過(guò)通過(guò)網(wǎng)絡(luò)請(qǐng)求接收渲染內(nèi)容 解析HTML抽象DOM tree 抽象出Render tree 布局(layout)render tree 繪畫render tree 抽象DOM tree 渲染引擎...
摘要:回流重繪及其優(yōu)化渲染過(guò)程渲染引擎通過(guò)通過(guò)網(wǎng)絡(luò)請(qǐng)求接收渲染內(nèi)容解析抽象抽象出布局繪畫抽象渲染引擎的第一步是解析文檔并將解析的元素轉(zhuǎn)換為樹(shù)中的實(shí)際節(jié)點(diǎn)。 回流、重繪及其優(yōu)化 渲染過(guò)程 渲染引擎通過(guò)通過(guò)網(wǎng)絡(luò)請(qǐng)求接收渲染內(nèi)容 解析HTML抽象DOM tree 抽象出Render tree 布局(layout)render tree 繪畫render tree 抽象DOM tree 渲染引擎...
摘要:例如對(duì)于復(fù)雜動(dòng)畫效果,由于會(huì)經(jīng)常的引起回流重繪,因此,我們可以使用絕對(duì)定位,讓它脫離文檔流,成為一個(gè)單獨(dú)的圖層。 瀏覽器的渲染過(guò)程 showImg(https://segmentfault.com/img/bVblB7y?w=624&h=289); 從上面這個(gè)圖上,我們可以看到,瀏覽器渲染過(guò)程如下 解析HTML生成DOM樹(shù),解析CSS生成CSSOM樹(shù) 將DOM樹(shù)和CSSOM樹(shù)結(jié)合生成...
摘要:例如對(duì)于復(fù)雜動(dòng)畫效果,由于會(huì)經(jīng)常的引起回流重繪,因此,我們可以使用絕對(duì)定位,讓它脫離文檔流,成為一個(gè)單獨(dú)的圖層。 瀏覽器的渲染過(guò)程 showImg(https://segmentfault.com/img/bVblB7y?w=624&h=289); 從上面這個(gè)圖上,我們可以看到,瀏覽器渲染過(guò)程如下 解析HTML生成DOM樹(shù),解析CSS生成CSSOM樹(shù) 將DOM樹(shù)和CSSOM樹(shù)結(jié)合生成...
閱讀 1713·2021-09-22 10:02
閱讀 1940·2021-09-02 15:40
閱讀 2842·2019-08-30 15:55
閱讀 2252·2019-08-30 15:44
閱讀 3598·2019-08-30 13:18
閱讀 3231·2019-08-30 11:00
閱讀 1951·2019-08-29 16:57
閱讀 570·2019-08-29 16:41