摘要:原文地址在頁(yè)面的生命周期中,一些效果的交互都有可能發(fā)生重排和重繪,這些都會(huì)使我們付出高額的性能代價(jià)。更比而言,重排會(huì)產(chǎn)生比重繪更大的開銷。觸發(fā)重繪的操作主要有背景色等屬性的改變我們應(yīng)當(dāng)注意的是重繪不一定導(dǎo)致重排,但重排一定會(huì)導(dǎo)致重繪。
原文地址:http://www.cun-xu.cn/index.ph...
在頁(yè)面的生命周期中,一些效果的交互都有可能發(fā)生重排(Layout)和重繪(Painting),這些都會(huì)使我們付出高額的性能代價(jià)。
瀏覽器從下載文件至本地到顯示頁(yè)面是個(gè)復(fù)雜的過程,這里包含了重繪和重排。通常來說,渲染引擎會(huì)解析HTML文檔來構(gòu)建DOM樹,與此同時(shí),渲染引擎也會(huì)用CSS解析器解析CSS文檔構(gòu)建CSSOM樹。接下來,DOM樹和CSSOM樹關(guān)聯(lián)起來構(gòu)成渲染樹(RenderTree),這一過程稱為Attachment。然后瀏覽器按照渲染樹進(jìn)行布局(Layout),最后一步通過繪制顯示出整個(gè)頁(yè)面。
其中重排和重繪是最耗時(shí)的部分,一旦觸發(fā)重排,我們對(duì)DOM的修改引發(fā)了DOM幾何元素的變化,渲染樹需要重新計(jì)算,
而重繪只會(huì)改變vidibility、outline、背景色等屬性導(dǎo)致樣式的變化,使瀏覽器需要根據(jù)新的屬性進(jìn)行繪制。更比而言,重排會(huì)產(chǎn)生比重繪更大的開銷。所以,我們?cè)趯?shí)際生產(chǎn)中要嚴(yán)格注意減少重排的觸發(fā)。
1.頁(yè)面第一次渲染
在頁(yè)面發(fā)生首次渲染的時(shí)候,所有組件都要進(jìn)行首次布局,這是開銷最大的一次重排。
2.瀏覽器窗口尺寸改變
3.元素位置和尺寸發(fā)生改變的時(shí)候
4.新增和刪除可見元素
5.內(nèi)容發(fā)生改變(文字?jǐn)?shù)量或圖片大小等等)
6.元素字體大小變化。
7.激活CSS偽類(例如::hover)。
8.設(shè)置style屬性
9.查詢某些屬性或調(diào)用某些方法。比如說:
offsetTop、offsetLeft、 offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、clientTop、clientLeft、clientWidth、clientHeight
除此之外,當(dāng)我們調(diào)用getComputedStyle方法,或者IE里的currentStyle時(shí),也會(huì)觸發(fā)重排,原理是一樣的,都為求一個(gè)“即時(shí)性”和“準(zhǔn)確性”。
vidibility、outline、背景色等屬性的改變
我們應(yīng)當(dāng)注意的是:重繪不一定導(dǎo)致重排,但重排一定會(huì)導(dǎo)致重繪。
div.style.top = "10px"; div.style.bottom = "10px"; div.style.right = "10px"; div.style.left = "10px"; console.log(div.offsetWidth); console.log(div.offseHeight); console.log(div.offsetRight); console.log(div.offsetLeft);
原來的操作會(huì)導(dǎo)致四次重排和四次重繪,變換順序之后只會(huì)觸發(fā)一次重排
在第一個(gè)console的時(shí)候,瀏覽器把之前上面四個(gè)寫操作的渲染隊(duì)列都給清空了。因?yàn)殇秩娟?duì)列本來就是空的,所以剩下的console并沒有觸發(fā)重排,僅僅拿值而已。
通過class和cssText進(jìn)行集中改變樣式
未進(jìn)行優(yōu)化的代碼是這樣的:
//bad var left = 10; var top = 10; el.style.left = left + "px"; el.style.top = top + "px";
雖然現(xiàn)在大部分現(xiàn)代瀏覽器都會(huì)有Flush隊(duì)列進(jìn)行渲染隊(duì)列優(yōu)化,但是有些老版本的瀏覽器比如IE6這樣的坑貨效率依然低下:
這時(shí)我們就可以通過上面所說的利用class和cssText屬性集中改變樣式
//good el.className += " className"; //or el.style.cssText += "; left: " + left + "px; top: " + top + "px;";
// bad 強(qiáng)制刷新 觸發(fā)兩次重排 div.style.left = div.offsetLeft + 1 + "px"; div.style.top = div.offsetTop + 1 + "px"; // good 緩存布局信息 相當(dāng)于讀寫分離 var curLeft = div.offsetLeft; var curTop = div.offsetTop; div.style.left = curLeft + 1 + "px"; div.style.top = curTop + 1 + "px"; 復(fù)制代碼
DOM離線化
一旦我們給元素設(shè)置display:none時(shí),元素不會(huì)存在于渲染樹中,相當(dāng)于將其從頁(yè)面“拿掉”,我們之后的操作將不會(huì)觸發(fā)重排和重繪,這叫做DOM的離線化。
dom.display = "none" // 修改dom樣式 dom.display = "block" 復(fù)制代碼
通過使用DocumentFragment創(chuàng)建一個(gè)dom碎片,在它上面批量操作dom,操作完成之后,再添加到文檔中,這樣只會(huì)觸發(fā)一次重排。
復(fù)制節(jié)點(diǎn),在副本上工作,然后替換它!
position屬性為absolute或fixed的元素,重排開銷比較小,不用考慮它對(duì)其他元素的影響
可以把動(dòng)畫效果應(yīng)用到position屬性為absolute或fixed的元素上,這樣對(duì)其他元素影響較小
動(dòng)畫效果還應(yīng)犧牲一些平滑,來?yè)Q取速度,這中間的度自己衡量:
比如實(shí)現(xiàn)一個(gè)動(dòng)畫,以1個(gè)像素為單位移動(dòng)這樣最平滑,但是Layout就會(huì)過于頻繁,大量消耗CPU資源,如果以3個(gè)像素為單位移動(dòng)則會(huì)好很多。
啟用GPU加速
GPU 硬件加速是指應(yīng)用 GPU 的圖形性能對(duì)瀏覽器中的一些圖形操作交給 GPU 來完成,因?yàn)?GPU 是專門為處理圖形而設(shè)計(jì),所以它在速度和能耗上更有效率。
GPU 加速通常包括以下幾個(gè)部分:Canvas2D,布局合成, CSS3轉(zhuǎn)換(transitions),CSS3 3D變換(transforms),WebGL和視頻(video)。
/* * 根據(jù)上面的結(jié)論 * 將 2d transform 換成 3d * 就可以強(qiáng)制開啟 GPU 加速 * 提高動(dòng)畫性能 */ div { transform: translate3d(10px, 10px, 0); }
娘滴,終于寫完了,肩膀子疼的我,得要得肩周炎了。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/62059.html
摘要:完成重排后,瀏覽器會(huì)重新繪制受到影響的部分到屏幕中,該過程稱為重繪重繪和重排操作都是代價(jià)昂貴的操作,它們會(huì)導(dǎo)致應(yīng)用程序的反應(yīng)遲鈍,所以應(yīng)該盡可能減少這類過程的發(fā)生。 瀏覽器下載完頁(yè)面中的所有內(nèi)容:HTML、JavaScript、CSS、圖片——之后會(huì)解析并生成兩個(gè)內(nèi)部數(shù)據(jù)結(jié)構(gòu): DOM樹:表示頁(yè)面結(jié)構(gòu) 渲染樹:表示DOM節(jié)點(diǎn)如何顯示 DOM樹中的每一個(gè)需要顯示的節(jié)點(diǎn)在渲染樹中至少存...
摘要:完成重排后,瀏覽器會(huì)重新繪制受到影響的部分到屏幕中,該過程稱為重繪重繪和重排操作都是代價(jià)昂貴的操作,它們會(huì)導(dǎo)致應(yīng)用程序的反應(yīng)遲鈍,所以應(yīng)該盡可能減少這類過程的發(fā)生。 瀏覽器下載完頁(yè)面中的所有內(nèi)容:HTML、JavaScript、CSS、圖片——之后會(huì)解析并生成兩個(gè)內(nèi)部數(shù)據(jù)結(jié)構(gòu): DOM樹:表示頁(yè)面結(jié)構(gòu) 渲染樹:表示DOM節(jié)點(diǎn)如何顯示 DOM樹中的每一個(gè)需要顯示的節(jié)點(diǎn)在渲染樹中至少存...
摘要:完成重排后,瀏覽器會(huì)重新繪制受到影響的部分到屏幕中,該過程稱為重繪重繪和重排操作都是代價(jià)昂貴的操作,它們會(huì)導(dǎo)致應(yīng)用程序的反應(yīng)遲鈍,所以應(yīng)該盡可能減少這類過程的發(fā)生。 瀏覽器下載完頁(yè)面中的所有內(nèi)容:HTML、JavaScript、CSS、圖片——之后會(huì)解析并生成兩個(gè)內(nèi)部數(shù)據(jù)結(jié)構(gòu): DOM樹:表示頁(yè)面結(jié)構(gòu) 渲染樹:表示DOM節(jié)點(diǎn)如何顯示 DOM樹中的每一個(gè)需要顯示的節(jié)點(diǎn)在渲染樹中至少存...
摘要:回流也被稱為重排,其實(shí)從字面上來看,重排更容易讓人形象易懂即重新排版整個(gè)頁(yè)面。重繪當(dāng)頁(yè)面元素樣式改變不影響元素在文檔流中的位置時(shí)如,,,瀏覽器只會(huì)將新樣式賦予元素并進(jìn)行重新繪制操作。你真的了解回流和重繪嗎 簡(jiǎn)單先了解一下瀏覽器的渲染過程(圖片來自于網(wǎng)絡(luò)) showImg(https://segmentfault.com/img/bVbaC2e?w=624&h=289); 瀏覽器生成渲染...
摘要:,當(dāng)元素插入后仍然保留對(duì)元素的指針。能夠獲得事件處理函數(shù),而生成的新無(wú)法獲得原先設(shè)置的事件處理函數(shù)。某些情況下,更加快速。無(wú)疑,在大多數(shù)情況下,更為快速且更加易用,但是使用的時(shí)候小心上述的那個(gè)問題就好。 WilsonLius blog 首發(fā)地址兩者生成dom的方式有什么優(yōu)劣呢?首先讓我們看一個(gè)小問題再引入正題~ 如何重復(fù)插入一個(gè)相同的html結(jié)構(gòu)呢? //錯(cuò)誤的 window.onlo...
閱讀 2975·2021-11-16 11:51
閱讀 2608·2021-09-22 15:02
閱讀 3723·2021-08-04 10:21
閱讀 3605·2019-08-30 15:43
閱讀 1947·2019-08-30 11:04
閱讀 3599·2019-08-29 17:14
閱讀 490·2019-08-29 12:16
閱讀 2933·2019-08-28 18:31