淺析CSS的性能優(yōu)化

transform和position

position + top/left的效果

下面我們來看一個(gè)動(dòng)畫效果(類似平時(shí)頁面滾動(dòng)功能)殿如,在該動(dòng)畫是讓一個(gè)球沿著某種路徑移動(dòng)猴娩。最簡(jiǎn)單的方式就是實(shí)時(shí)調(diào)整它們的left和top屬性,使用css動(dòng)畫實(shí)現(xiàn)些椒。

<style>
    html,
    body {
        width: 100%;
        height: 100%;
    }
    .ball-running {
        animation: run-around 4s infinite;
        width: 100px;
        height: 100px;
        background-color: red;
        position: absolute;
    }
    @keyframes run-around {
        0%: {
            top: 0;
            left: 0;
        }
        25% {
            top: 0;
            left: 200px;
        }
        50% {
            top: 200px;
            left: 200px;
        }
        75% {
            top: 200px;
            left: 0;
        }
    }
</style>
<body>
    <div class="ball-running"></div>
</body>

在運(yùn)行的時(shí)候即使是在電腦瀏覽器上也會(huì)隱約覺得動(dòng)畫的運(yùn)行并不流暢妻往,更不要提在移動(dòng)端達(dá)到60fps的流暢效果了拗窃。這是因?yàn)閠op和left的改變會(huì)觸發(fā)瀏覽器的reflow和repaint棺蛛,整個(gè)動(dòng)畫過程都在不斷觸發(fā)瀏覽器的重新渲染枷畏,這個(gè)過程是很影響性能的瓮增。

transform效果

為了解決這個(gè)問題,我們使用transform中的translate()來替換top和left

<style>
    html,
    body {
        width: 100%;
        height: 100%;
    }
    .ball-running {
        animation: run-around2 4s infinite;
        width: 100px;
        height: 100px;
        background-color: red;
        position: absolute;
    }
    @keyframes run-around2 {
        0% {
            transform: translate(0, 0);
        }
        25% {
            transform: translate(200px, 0);
        }
        50% {
            transform: translate(200px, 200px);
        }
        75% {
            transform: translate(0, 200px);
        }
    }
</style>
<body>
    <div class="ball-running"></div>
</body>

這個(gè)時(shí)候我們就會(huì)發(fā)現(xiàn)整個(gè)動(dòng)畫效果流暢了很多哩俭,在動(dòng)畫移動(dòng)的過程中也沒有發(fā)生repaint和reflow钉赁。那么為什么transform沒有出發(fā)repaint呢?原因就是transform動(dòng)畫由GPU控制携茂,支持硬件加速,并不需要軟件方面的渲染诅岩。

硬件加速工作原理

瀏覽器收到頁面文檔后讳苦,會(huì)將文檔中的標(biāo)記語言解析為DOM樹,DOM和CSS結(jié)合后形成瀏覽器構(gòu)建頁面的渲染樹吩谦,渲染樹中包含了大量的渲染元素鸳谜,每一個(gè)渲染元素會(huì)被分到一個(gè)圖層中,每個(gè)又會(huì)被加載到GPU形成渲染紋理式廷,而圖層在GPU中transform是不會(huì)觸發(fā)repaint的咐扭,這一點(diǎn)非常類似3D繪圖功能,最終這些使用transform的圖層都會(huì)使用獨(dú)立的合成器進(jìn)程進(jìn)行處理滑废,移動(dòng)時(shí)的變化也是獨(dú)立的蝗肪,不會(huì)影響到頁面的其他元素,造成重排重繪是因?yàn)橛绊懙巾撁娴钠渌麍D層元素導(dǎo)致的蠕趁,可以理解為其他元素都是在一個(gè)圖層空間薛闪,所以一個(gè)圖層移動(dòng)其他的也會(huì)收到影響,而transform創(chuàng)建了一個(gè)新的復(fù)合圖層俺陋,它會(huì)被GPU獨(dú)立執(zhí)行transform操作豁延,跟其他圖層互不影響,所以不會(huì)引起重排重繪腊状。
此時(shí)诱咏,你也許會(huì)問瀏覽器什么時(shí)候會(huì)創(chuàng)建一個(gè)獨(dú)立的復(fù)合圖層呢?事實(shí)上一般是在以下幾種情況下:

  • 3D或者CSS transform
  • video或canvas標(biāo)簽
  • CSS filters
  • 元素覆蓋時(shí)缴挖,比如使用了z-index屬性
    等一下袋狞,上面的示例使用的是2Dtransform而不是3D的transform,因?yàn)樵趧?dòng)畫開始和結(jié)束的時(shí)候觸發(fā)了兩次repaint操作映屋。3D和2D transform的區(qū)別就在于硕并,瀏覽器在頁面渲染前為3D動(dòng)畫創(chuàng)建獨(dú)立的復(fù)合圖層,而在運(yùn)行期間為2D動(dòng)畫創(chuàng)建秧荆。
    動(dòng)畫開始時(shí)倔毙,生成新的復(fù)合圖層并加載為GPU的紋理用于初始化repaint,然后由GPU的復(fù)合器操作整個(gè)動(dòng)畫的執(zhí)行乙濒,最后當(dāng)動(dòng)畫結(jié)束時(shí)陕赃,再次執(zhí)行repaint操作刪除復(fù)合圖層卵蛉。

transform為什么不會(huì)引發(fā)重排

因?yàn)镚PU進(jìn)程會(huì)為其開啟一個(gè)新的復(fù)合圖層,不會(huì)影響默認(rèn)復(fù)合圖層(就是普通文檔流)么库,所以并不會(huì)影響周邊的 DOM 結(jié)構(gòu)傻丝,而屬性的改變也會(huì)交給 GPU 處理,不會(huì)進(jìn)行重排诉儒。使 GPU 進(jìn)程開啟一個(gè)新的復(fù)合圖層的方式還有 3D 動(dòng)畫葡缰,過渡動(dòng)畫,以及 opacity 屬性忱反,還有一些標(biāo)簽泛释,這些都可以創(chuàng)建新的復(fù)合圖層。這些方式叫做硬件加速方式温算。你可以想象成新的復(fù)合圖層和默認(rèn)復(fù)合圖層是兩幅畫怜校,相互獨(dú)立,不會(huì)彼此影響注竿。降低重排的方式:要么減少次數(shù)茄茁,要么降低影響范圍,創(chuàng)建新的復(fù)合圖層就是第二種優(yōu)化方式巩割。絕對(duì)布局雖然脫離了文檔流裙顽,但不會(huì)創(chuàng)建新的復(fù)合圖層,因此當(dāng)絕對(duì)布局改變時(shí)宣谈,不會(huì)影響普通文檔流的 render tree锦庸,但是依然會(huì)繪制整個(gè)默認(rèn)復(fù)合圖層,對(duì)普通文檔流是有影響的蒲祈。普通文檔流就是默認(rèn)復(fù)合圖層甘萧,不要介意我交換使用它們?nèi)绻阋褂糜布铀俜绞浇档椭嘏诺挠绊懀?qǐng)不要過度使用梆掸,創(chuàng)建新的復(fù)合圖層是有額外消耗的扬卷,比如更多的內(nèi)存消耗,并且在使用硬件加速方式時(shí)酸钦,配合 z-index 一起使用怪得,盡可能使新的復(fù)合圖層的元素層級(jí)等級(jí)最高。

使用GPU渲染元素

能觸發(fā)GPU硬件加速的CSS屬性

(1)transform
(2)opacity
(3)filter

使用硬件加速需要注意的事項(xiàng)

(1)內(nèi)存卑硫。如果GPU加載了大量的紋理徒恋,那么很容易就會(huì)發(fā)生內(nèi)存問題,這一點(diǎn)在移動(dòng)端尤為明顯欢伏。
(2)使用GPU渲染會(huì)影響字體的抗鋸齒效果入挣。這是因?yàn)镚PU和CPU具有不同的渲染機(jī)制,即使最終硬件加速停止了硝拧,文本還是會(huì)在動(dòng)畫期間顯示的很模糊径筏。

總結(jié)

1葛假、transform會(huì)使用GPU硬件加速,性能更好滋恬,position + top/left會(huì)觸發(fā)大量的重排重繪聊训,性能影響較大。
2恢氯、硬件加速的工作原理是創(chuàng)建一個(gè)新的復(fù)合圖層带斑,然后使用合成線程進(jìn)行渲染
3、3D和2D動(dòng)畫的區(qū)別勋拟,2D動(dòng)畫會(huì)在動(dòng)畫開始和動(dòng)畫結(jié)束時(shí)觸發(fā)2次重新渲染
4勋磕、使用了GPU可以優(yōu)化動(dòng)畫小故宮但是不要濫用,會(huì)有內(nèi)存問題
5指黎、理解強(qiáng)制觸發(fā)硬件加速的transform技巧,使用對(duì)GPU友好的CSS屬性

參考文章:https://zhuanlan.zhihu.com/p/78230297

el-scrollbar是elementui自帶的頁面滾動(dòng)條州丹,如果用頁面滾動(dòng)條醋安,我們發(fā)現(xiàn)在ie瀏覽器下卡頓很明顯,但是用el-scrollbar滾動(dòng)頁面就會(huì)感覺會(huì)流暢很多墓毒,因?yàn)轫撁鏉L動(dòng)會(huì)引發(fā)重排重繪吓揪,但是el-scrollbar是用transform不會(huì)引起,所以用el-scrollbar會(huì)感覺流暢很多所计,轉(zhuǎn)訂單去掉overflow:hidden就會(huì)流暢是因?yàn)檫@個(gè)樣式會(huì)覆蓋el-scrollbar的樣式柠辞,

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市主胧,隨后出現(xiàn)的幾起案子叭首,更是在濱河造成了極大的恐慌,老刑警劉巖踪栋,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件焙格,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡夷都,警方通過查閱死者的電腦和手機(jī)眷唉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來囤官,“玉大人冬阳,你說我怎么就攤上這事〉骋” “怎么了肝陪?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)刑顺。 經(jīng)常有香客問我见坑,道長(zhǎng)嚷掠,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任荞驴,我火速辦了婚禮不皆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘熊楼。我一直安慰自己霹娄,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布鲫骗。 她就那樣靜靜地躺著犬耻,像睡著了一般。 火紅的嫁衣襯著肌膚如雪执泰。 梳的紋絲不亂的頭發(fā)上枕磁,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音术吝,去河邊找鬼计济。 笑死,一個(gè)胖子當(dāng)著我的面吹牛排苍,可吹牛的內(nèi)容都是我干的沦寂。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼淘衙,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼传藏!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起彤守,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤毯侦,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后具垫,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體叫惊,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年做修,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了霍狰。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡饰及,死狀恐怖蔗坯,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情燎含,我是刑警寧澤宾濒,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站屏箍,受9級(jí)特大地震影響绘梦,放射性物質(zhì)發(fā)生泄漏橘忱。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一卸奉、第九天 我趴在偏房一處隱蔽的房頂上張望钝诚。 院中可真熱鬧,春花似錦榄棵、人聲如沸凝颇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽拧略。三九已至,卻和暖如春瘪弓,著一層夾襖步出監(jiān)牢的瞬間垫蛆,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工腺怯, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留袱饭,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓瓢喉,卻偏偏與公主長(zhǎng)得像宁赤,于是被迫代替她去往敵國(guó)和親舀透。 傳聞我的和親對(duì)象是個(gè)殘疾皇子栓票,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • CSS3動(dòng)畫應(yīng)用很廣,尤其是在H5項(xiàng)目中愕够,炫酷的交互效果可以給產(chǎn)品帶來更好的體驗(yàn)走贪,更能吸引用戶。然而在應(yīng)用的時(shí)候惑芭,...
    UIleader閱讀 2,212評(píng)論 0 7
  • 頁面渲染的過程 構(gòu)建DOM樹解析HTML坠狡,創(chuàng)建DOM樹,解析過程:如果遇到link & style遂跟,就會(huì)去下載這些...
    熬得薩菲閱讀 965評(píng)論 0 5
  • 前端性能優(yōu)化資料整理 頁面性能差的直接后果是用戶需要等待逃沿,而等待,尤其是不確定要多長(zhǎng)時(shí)間的等待會(huì)給用戶帶來焦慮幻锁,為...
    飄零之雪閱讀 811評(píng)論 2 3
  • AJax 優(yōu)化 緩存 Ajax 請(qǐng)求盡量使用GET, 僅取決于cookie數(shù)量 Cookie 優(yōu)化 減少Cooki...
    KeKeMars閱讀 9,351評(píng)論 5 89
  • 資源的合并與壓縮 減少 http 請(qǐng)求數(shù)量 減少請(qǐng)求資源的大小 html 壓縮 壓縮在文本文件中有意義但是在HTM...
    阿昕_閱讀 3,619評(píng)論 0 28