摘要:許多層還會(huì)因?yàn)檫^大與許多內(nèi)容重疊而導(dǎo)致過度繪制的情況發(fā)生,從而增加?xùn)鸥窕臅r(shí)間。關(guān)于這一點(diǎn),在中也有所體現(xiàn)。
前言
研究這個(gè)問題的起因,源于我在閱讀作曲家與聽眾這篇文章時(shí),看到的這樣一句話。
例如,我對(duì)很多開發(fā)者(不管新手還是老手)仍然使用 CSS 的 top 和 left 而不是 transform 創(chuàng)建平移動(dòng)畫感到震驚,盡管只要你在除了 8 核 MacBook Pro 之外的設(shè)備上進(jìn)行過測(cè)試,就會(huì)發(fā)現(xiàn)幀率的差別極其明顯。
看到這句話我也同樣震驚,震驚之處正如作者所言,我就是從未在意過兩者差別而使用 top 和 left 創(chuàng)建平移動(dòng)畫的人之一。那么為什么兩者會(huì)有區(qū)別,讓我們來一探究竟吧。
測(cè)試用例其實(shí)很慚愧,早在2012年就有許多人在博文中闡述這一事實(shí)了,也因此,我能很輕松的找到非常棒的demo(來源見參考文獻(xiàn)),如下:
top、left實(shí)現(xiàn)基于關(guān)鍵幀的平移動(dòng)畫
translate實(shí)現(xiàn)基于關(guān)鍵幀的平移動(dòng)畫
相信讀者在把Macbook Pro增加到一定數(shù)量的時(shí)候,都能發(fā)現(xiàn)兩者之間的差異了吧。
深入背后現(xiàn)在讓我們來探究其中的原因。打開Chrome dev tools,切到Performance選項(xiàng),記錄一段時(shí)間后,選擇某一幀查看各個(gè)過程所占時(shí)間。
首先是top、left的時(shí)間線:
在這一幀中,我們看到多個(gè)步驟占用了CPU時(shí)間。
換到translate則變成了截然不同的樣子:
根本沒有CPU時(shí)間。我看了很多幀,除了少部分幀有0.1ms左右的腳本執(zhí)行時(shí)間之外,大部分幀的CPU時(shí)間都是0。
答案已經(jīng)很顯然了,使用translate來做平移運(yùn)動(dòng),大部分時(shí)間都不需要CPU參與。這個(gè)結(jié)果和五年前的文章不太相同,但時(shí)間已經(jīng)過了五年,瀏覽器的優(yōu)化至此地步也不算出乎意料吧。
接下來我們打開Render,開啟Paint Flashing和Layer Borders。
對(duì)于top、left我們會(huì)看到如下情況:
其中綠框是瀏覽器重繪的區(qū)域,對(duì)于使用position的情況,瀏覽器要在動(dòng)畫的執(zhí)行中不停地繪制綠框中的區(qū)域。
而對(duì)于transform則是另一幅場(chǎng)景:
我們可以看到transform的版本我們的MacBook圖片周圍會(huì)多一個(gè)框框,這是因?yàn)閠ransform會(huì)生成一個(gè)新的層,而對(duì)這個(gè)圖層進(jìn)行變換,對(duì)于瀏覽器來說,是不需要重繪的。包括在我點(diǎn)擊“add 10 more macbook”之后,也只有插入元素的時(shí)候會(huì)引起重繪。同樣,新插入的“MacBook”也各自有獨(dú)立的圖層,不會(huì)引起重繪。
那么,Chrome創(chuàng)建層的標(biāo)準(zhǔn)是什么呢?在Accelerated Rendering in Chrome中有如下表述:
What else gets its own layer? Chrome’s heuristics here have evolved over time and continue to, but currently any of the following trigger layer creation:
3D or perspective transform CSS properties
Composited plugins (i.e. Flash)
Elements with CSS animation for their opacity or using an animated transform
Elements with accelerated CSS filters
Element has a descendant that has a compositing layer (in other words if the element has a child element that’s in its own layer)
Element has a sibling with a lower z-index which has a compositing layer (in other words the it’s rendered on top of a composited layer)
所以,對(duì)于我們的transform動(dòng)畫,其符合上述第五條規(guī)則中的“using an animated transform”,因此會(huì)創(chuàng)建自己獨(dú)立的層;同樣,我們也可以根據(jù)上述規(guī)則來給top、left方案創(chuàng)建獨(dú)立的層來減少重繪。
接下來,根據(jù)第一條規(guī)則,讓我們?cè)趖op、left示例中的.macbook類上面加上這樣一行css:
transform: translateZ(0);
我們就能看到和translate方案一樣的場(chǎng)景了。
通過查閱資料,我簡(jiǎn)單說一下我的理解。Chrome會(huì)預(yù)先將層的內(nèi)容繪制成位圖發(fā)送給GPU,如果層僅僅是位置與透明度等特定的一些屬性發(fā)生變化,而不是內(nèi)容發(fā)生變化,則無需重繪這一位圖。因此無論是translate動(dòng)畫方案,還是加上3D變換屬性的top、left方案,由于其都在獨(dú)立的層上,且只是發(fā)生位置變化,因此無需重繪。
然而,層并不是越多越好。參考Accelerated Rendering in Chrome中的表述。
But beware just blindly creating them, as they’re not free: they take up memory in system RAM and on the GPU (particularly limited on mobile devices) and having lots of them can introduce other overhead in the logic keeps track of which are visible. Many layers can also actually increase time spent rasterizing if they layers are large and overlap a lot where they didn’t previously, leading to what’s sometimes referred to as “overdraw”. So use your knowledge wisely!
簡(jiǎn)單翻譯一下就是:層會(huì)占用系統(tǒng) RAM 與 GPU(在移動(dòng)設(shè)備上尤其有限)的內(nèi)存,并且擁有大量的層會(huì)因?yàn)橛涗浤男┦强梢姷亩腩~外的開銷。許多層還會(huì)因?yàn)檫^大與許多內(nèi)容重疊而導(dǎo)致“過度繪制(overdraw)”的情況發(fā)生,從而增加?xùn)鸥窕臅r(shí)間。關(guān)于這一點(diǎn),在Jank Busting Apple"s Home Page中也有所體現(xiàn)。
In this case, too many elements have translateZ(0) applied when only one or two applications are really needed. This is forcing a longer composite time and ultimately giving the animations some jank.
“So use your knowledge wisely!”
參考文獻(xiàn)A Tale of Animation Performance
Why Moving Elements With Translate() Is Better Than Pos:abs Top/left
Accelerated Rendering in Chrome
Jank Busting Apple"s Home Page
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/112309.html
摘要:前端日?qǐng)?bào)精選使用重寫大型應(yīng)用后,我們想分享一下這八個(gè)經(jīng)驗(yàn)與交互之技術(shù)有贊前端團(tuán)隊(duì)專題之學(xué)在數(shù)組中查找指定元素基于角色的權(quán)限驗(yàn)證從源碼學(xué)習(xí)如何寫模板中文譯掘金譯回顧的成功掘金一些有趣的事情布局教程入門指南定位元素古寺比的寺更 2017-07-27 前端日?qǐng)?bào) 精選 使用 React Native 重寫大型 Ionic 應(yīng)用后,我們想分享一下這八個(gè)經(jīng)驗(yàn)H5與Native交互之JSBridge...
摘要:在繪制琦玉的頭像時(shí),最重要的一個(gè)屬性就是,我們用它可以畫出圓形橢圓及各種變體。以下的樣式能夠畫出琦玉的臉部形狀在調(diào)整后,可畫出眼鼻嘴的形狀介紹屬性也是一個(gè)很強(qiáng)大的屬性,能夠?qū)υ刈龈鞣N變形。 寫這篇博客的起因是我看了Medium上的這篇文章:How I started drawing CSS Images,然后哇哦?,同樣是前端開發(fā),這區(qū)別怎么這么大呢?這位作者和我完全點(diǎn)了不同的技能點(diǎn)...
摘要:前端最基礎(chǔ)的就是。類同于標(biāo)簽將對(duì)象作為彈性伸縮盒顯示。定義了一條立方貝塞爾曲線。是,表示終止時(shí)間和終止?fàn)顟B(tài)。動(dòng)畫過渡可以理解為兩個(gè)關(guān)鍵幀的補(bǔ)間操作。往期前端培訓(xùn)初級(jí)階段后記年月日更新。參考資料引用培訓(xùn)目錄出處已備份到筆記速查視差滾動(dòng) 前端最基礎(chǔ)的就是 HTML+CSS+Javascript。掌握了這三門技術(shù)就算入門,但也僅僅是入門,現(xiàn)在前端開發(fā)的定義已經(jīng)遠(yuǎn)遠(yuǎn)不止這些。前端小課堂(HTM...
摘要:前端最基礎(chǔ)的就是。類同于標(biāo)簽將對(duì)象作為彈性伸縮盒顯示。定義了一條立方貝塞爾曲線。是,表示終止時(shí)間和終止?fàn)顟B(tài)。動(dòng)畫過渡可以理解為兩個(gè)關(guān)鍵幀的補(bǔ)間操作。往期前端培訓(xùn)初級(jí)階段后記年月日更新。參考資料引用培訓(xùn)目錄出處已備份到筆記速查視差滾動(dòng) 前端最基礎(chǔ)的就是 HTML+CSS+Javascript。掌握了這三門技術(shù)就算入門,但也僅僅是入門,現(xiàn)在前端開發(fā)的定義已經(jīng)遠(yuǎn)遠(yuǎn)不止這些。前端小課堂(HTM...
閱讀 2694·2021-11-18 10:02
閱讀 2688·2021-11-15 11:38
閱讀 3793·2021-11-12 10:36
閱讀 766·2021-11-12 10:34
閱讀 2998·2021-10-21 09:38
閱讀 1591·2021-09-29 09:48
閱讀 1707·2021-09-29 09:34
閱讀 1187·2021-09-22 10:02