|
想要達(dá)到平滑的動畫效果,瀏覽器需要避免復(fù)雜繁瑣的工作,比如解析代碼,構(gòu)建渲染樹,繪制,布局等等工作。慶幸的是,我們有GPU。 從一個簡單例子說起。 假設(shè)現(xiàn)在有這樣的需求,鼠標(biāo)移上圖標(biāo)時,圖片向右移動300個像素單位,效果大概是下面這樣。 http://image98.360doc.com/DownloadImg/2016/07/2110/76297989_1.gif
很自然,人類的理所當(dāng)然思維會指引我們進(jìn)坑。
沒問題,這能完成我們的任務(wù)。 https://dn-w3ctrain./smoother-animation-chrome-timeline1.jpg
(注意這是我故意放大很多倍圖片的效果。) 綠色部分表示瀏覽器在執(zhí)行Paint操作,我們都知道動畫的刷新頻率需要保持在60fps以上肉眼才會覺得很順暢。低于30fps則會讓用戶感覺到明顯卡頓。而這個實驗中,瀏覽器略感吃力。為了能夠按時完成任務(wù),瀏覽器選擇跳過部分幀,于是我們就看到走走停停的卡頓效果,這也通常被稱為丟幀。 于是我又換成padding-left,jQuery animate方法,然而并沒有改善。
https://dn-w3ctrain./smoother-animation-chrome-timeline2.jpg
我的天!質(zhì)的飛躍有沒有,相同動畫下還能保持這個高的刷新頻率。 查查資料。 reflow,repaint當(dāng)我們在某個元素上執(zhí)行動畫時,瀏覽器需要每一幀都檢測是否有元素受到影響,并調(diào)整他們的大小,位置,通常這種調(diào)整都是聯(lián)動的,我們稱為reflow。同樣的,瀏覽器還需要監(jiān)聽元素的外觀變化,通常是背景色,陰影,邊框等可視元素,并進(jìn)行重繪,我們稱為repaint。每次reflow,repaint后瀏覽器還需要合并渲染層并輸出到屏幕上。所有的這些都會是動畫卡頓的原因。
你可以在csstrigger上查找某個css屬性會觸發(fā)什么事件。 CPU,GPU分工在沒有GUP的年代,所有任務(wù)都是CPU來完成。慶幸的是,這篇文章一開始就說到,我們生活在有GPU的年代。GPU擅長圖形計算,這是它的強(qiáng)項。 一個頁面上來,瀏覽器會經(jīng)過一番處理,生成相應(yīng)的位圖。然后把它們?nèi)咏oGPU。GPU再拼接位圖,合并渲染層,并把最終結(jié)果輸出到屏幕。 問題根源在《你不知道的Z-Index》中有提到,如果某個元素處于以下狀態(tài):
那么就會產(chǎn)生一個新的渲染層(堆疊上下文),這時候執(zhí)行動畫,只需要GPU按照現(xiàn)有的位圖,按照相應(yīng)的變換在獨立的渲染層中輸出,然后再合并輸出。這個過程并不需要主線程CPU的參與。 而當(dāng)我們使用left,padding,margin,JavaScript,jQuery等方式來執(zhí)行動畫,那么流程就不一樣了。 還是舉上面的例子,CPU需要重新計算每一幀,元素的位置,外觀,重新定位元素,repaint,然后才生成位圖,傳給GPU渲染。 所以當(dāng)我們開啟GPU渲染的時候,瀏覽器主線程就能空出來去響應(yīng)用戶輸入了。 注意然而并不是所有瀏覽器默認(rèn)都會開啟GPU渲染,所以通常會用translate3d,translateZ,或者是opacity < 1等來強(qiáng)制開啟。 請注意,GUP渲染并不是越多越好,首先它很占內(nèi)存,在移動端比較耗電, 還可能會有坑。 聯(lián)系前幾天看了前端農(nóng)民工的一篇文章《CSS3硬件加速也有坑!??!》,里面的Demo也是讓我久久不能忘懷。 http://image98.360doc.com/DownloadImg/2016/07/2110/76297989_4.jpg 文中說到如果有一個元素,它的兄弟元素在復(fù)合層中渲染,而這個兄弟元素的z-index比較小,那么這個元素(不管是不是應(yīng)用了硬件加速樣式)也會被放到復(fù)合層中。
暫時還不是很懂,兄弟元素如何定義。特別是看了源碼后稍稍有些困惑, 所以我
動畫優(yōu)化要點總結(jié)
關(guān)于排錯 (12月15)TimeLine面板非常有用,如果你遇到很棘手的性能問題,肉眼看不錯哪里有問題,你可以試試把有嫌疑的元素加個 TQ的H5動感影集性能分析非常棒! 推薦閱讀
|
|
|