日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > CSS >内容正文

CSS

盒子端 CSS 动画性能提升研究

發布時間:2025/4/5 CSS 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 盒子端 CSS 动画性能提升研究 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

不同于傳統的 PC Web 或者是移動 WEB,在騰訊視頻客廳盒子端,接大屏顯示器(電視)下,許多能流暢運行于 PC 端、移動端的 Web 動畫,受限于硬件水平,在盒子端的表現的往往不盡如人意。

基于此,對于 Web 動畫的性能問題,僅僅停留在感覺已經優化的OK之上,是不夠的,想要在盒子端跑出高性能接近 60 FPS 的流暢動畫,就必須要刨根問底,深挖每一處可以提升的方法。

?

流暢動畫的標準

理論上說,FPS 越高,動畫會越流暢,目前大多數設備的屏幕刷新率為 60 次/秒,所以通常來講 FPS 為 60frame/s 時動畫效果最好,也就是每幀的消耗時間為 16.67ms。

直觀感受,不同幀率的體驗

  • 幀率能夠達到 50 ~ 60 FPS 的動畫將會相當流暢,讓人倍感舒適;
  • 幀率在 30 ~ 50 FPS 之間的動畫,因各人敏感程度不同,舒適度因人而異;
  • 幀率在 30 FPS 以下的動畫,讓人感覺到明顯的卡頓和不適感;
  • 幀率波動很大的動畫,亦會使人感覺到卡頓。

?

盒子端動畫優化

在騰訊視頻客廳盒子端,Web 動畫未進行優化之前,一些復雜動畫的幀率僅有 10 ~ 30 FPS,卡頓感非常明顯,帶來很不好的用戶體驗。

而進行優化之后,能將 10 ~ 30 FPS的動畫優化至 30 ~ 60 FPS,雖然不算優化到最完美,但是當前盒子硬件的條件下,已經算是非常大的進步。

盒子端 Web 動畫性能比較

首先先給出在盒子端不同類型的Web 動畫的性能比較。經過對比,在盒子端 CSS 動畫的性能要優于 Javascript 動畫,而在 CSS 動畫里,使用 GPU 硬件加速的動畫性能要優于不使用硬件加速的性能。

所以在盒子端,實現一個 Web 動畫,優先級是:

GPU 硬件加速 CSS 動畫 > 非硬件加速 CSS 動畫 > Javascript 動畫

?

動畫性能上報分析

要有優化,就必須得有數據做為支撐。對比優化前后是否有提升。而對于動畫而言,衡量一個動畫的標準也就是 FPS 值。

所以現在的關鍵是如何計算出每個動畫運行時的幀率,這里我使用的是?requestAnimationFrame這個函數近似的得到動畫運行時的幀率。

考慮到盒子都是安卓系統,且大多版本較低且硬件性能堪憂,導致一是許多高級 API 無法使用,二是這里只是近似得到動畫幀率

原理是,正常而言?requestAnimationFrame?這個方法在一秒內會執行 60 次,也就是不掉幀的情況下。假設動畫在時間 A 開始執行,在時間 B 結束,耗時 x ms。而中間?requestAnimationFrame?一共執行了 n 次,則此段動畫的幀率大致為:n / (B - A)。

核心代碼如下,能近似計算每秒頁面幀率,以及我們額外記錄一個?allFrameCount,用于記錄 rAF 的執行次數,用于計算每次動畫的幀率 :

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 var?rAF =?function?() { ????return?( ????????window.requestAnimationFrame || ????????window.webkitRequestAnimationFrame || ????????function?(callback) { ????????????window.setTimeout(callback, 1000 / 60); ????????} ????); }(); var?frame = 0; var?allFrameCount = 0; var?lastTime = Date.now(); var?lastFameTime = Date.now(); var?loop =?function?() { ????var?now = Date.now(); ????var?fs = (now - lastFameTime); ????var?fps = Math.round(1000 / fs); ????lastFameTime = now; ????// 不置 0,在動畫的開頭及結尾記錄此值的差值算出 FPS ????allFrameCount++; ????frame++; ????if?(now > 1000 + lastTime) { ????????var?fps = Math.round((frame * 1000) / (now - lastTime)); ????????// console.log('fps', fps); 每秒 FPS ????????frame = 0; ????????lastTime = now; ????}; ????rAF(loop); }

  

研究結論

所以,我們的目標就是在使用 GPU 硬件加速的基礎之上,更深入的去優化 CSS 動畫,先給出最后的一個優化步驟方案:

  • 精簡 DOM ,合理布局
  • 使用 transform 代替 left、top,減少使用耗性能樣式
  • 控制頻繁動畫的層級關系
  • 考慮使用 will-change
  • 使用 dev-tool 時間線 timeline 觀察,找出導致高耗時、掉幀的關鍵操作
  • 下文會有每一步驟的具體分析解釋。

    ?

    Web 每一幀的渲染

    要想達到 60 FPS,每幀的預算時間僅比 16 毫秒多一點 (1 秒/ 60 = 16.67 毫秒)。但實際上,瀏覽器有整理工作要做,因此您的所有工作需要盡量在 10 毫秒內完成。

    而每一幀,如果有必要,我們能控制的部分,也是像素至屏幕管道中的關鍵步驟如下:

    完整的像素管道?JS / CSS > 樣式 > 布局 > 繪制 > 合成:

  • JavaScript。一般來說,我們會使用 JavaScript 來實現一些視覺變化的效果。比如用 jQuery 的 animate 函數做一個動畫、對一個數據集進行排序或者往頁面里添加一些 DOM 元素等。當然,除了 JavaScript,還有其他一些常用方法也可以實現視覺變化效果,比如:CSS Animations、Transitions 和 Web Animation API。

  • 樣式計算。此過程是根據匹配選擇器(例如 .headline 或 .nav > .nav__item)計算出哪些元素應用哪些 CSS 3. 規則的過程。從中知道規則之后,將應用規則并計算每個元素的最終樣式。

  • 布局。在知道對一個元素應用哪些規則之后,瀏覽器即可開始計算它要占據的空間大小及其在屏幕的位置。網頁的布局模式意味著一個元素可能影響其他元素,例如 <body> 元素的寬度一般會影響其子元素的寬度以及樹中各處的節點,因此對于瀏覽器來說,布局過程是經常發生的。

  • 繪制。繪制是填充像素的過程。它涉及繪出文本、顏色、圖像、邊框和陰影,基本上包括元素的每個可視部分。繪制一般是在多個表面(通常稱為層)上完成的。

  • 合成。由于頁面的各部分可能被繪制到多層,由此它們需要按正確順序繪制到屏幕上,以便正確渲染頁面。對于與另一元素重疊的元素來說,這點特別重要,因為一個錯誤可能使一個元素錯誤地出現在另一個元素的上層。

  • 當然,不一定每幀都總是會經過管道每個部分的處理。我們的目標就是,每一幀的動畫,對于上述的管道流程,能避免則避免,不能避免則最大限度優化。

    ?

    優化動畫步驟

    先給出一個步驟,調優一個動畫,有一定的指導原則可以遵循,一步一步深入動畫:

    1.精簡 DOM ,合理布局

    這個沒什么好說的,如果可以,精簡 DOM 結構在任何時候都是對頁面有幫助的。

    2.使用 transform 代替 left、top,減少使用耗性能樣式

    現代瀏覽器在完成以下四種屬性的動畫時,消耗成本較低:

    • position(位置):?transform: translate(npx, npx)
    • scale(比例縮放):transform: scale(n)
    • rotation(旋轉) :transform: rotate(ndeg)
    • opacity(透明度):opacity: 0...1

    如果可以,盡量只使用上述四種屬性去控制動畫。

    不同樣式在消耗性能方面是不同的,改變一些屬性的開銷比改變其他屬性要多,因此更可能使動畫卡頓。

    例如,與改變元素的文本顏色相比,改變元素的?box-shadow?將需要開銷大很多的繪圖操作。 改變元素的?width?可能比改變其?transform?要多一些開銷。如?box-shadow?屬性,從渲染角度來講十分耗性能,原因就是與其他樣式相比,它們的繪制代碼執行時間過長。

    這就是說,如果一個耗性能嚴重的樣式經常需要重繪,那么你就會遇到性能問題。其次你要知道,沒有不變的事情,在今天性能很差的樣式,可能明天就被優化,并且瀏覽器之間也存在差異。

    開啟 GPU 硬件加速

    歸根結底,上述四種屬性的動畫消耗較低的原因是會開啟了 GPU 硬件加速。動畫元素生成了自己的圖形層(GraphicsLayer)。

    通常而言,開啟 GPU 加速的方法我們可以使用

    • will-change: transform

    這會使聲明了該樣式屬性的元素生成一個圖形層,告訴瀏覽器接下來該元素將會進行 transform 變換,讓瀏覽器提前做好準備。

    使用?will-change?并不一定會有性能的提升,因為即使瀏覽器預料到會有這些更改,依然會為這些屬性運行布局和繪制流程,所以提前告訴瀏覽器,也并不會有太多性能上的提升。這樣做的好處是,創建新的圖層代價很高,而等到需要時匆忙地創建,不如一開始直接創建好。

    對于 Safari 及一些舊版本瀏覽器,它們不能識別?will-change,則需要使用某種 translate 3D 進行 hack,通常會使用

    • transform: translateZ(0)

    所以,正常而言,在生產環境下,我們可能需要使用如下代碼,開啟硬件加速:

    1 2 3 4 { ????will-change: transform; ????transform: translateZ(0); }

    3.控制頻繁動畫的層級關系

    動畫層級的控制的意思是盡量讓需要進行 CSS 動畫的元素的?z-index?保持在頁面最上方,避免瀏覽器創建不必要的圖形層(GraphicsLayer),能夠很好的提升渲染性能。

    OK,這里又提到了圖形層(GraphicsLayer),這是一個瀏覽器渲染原理相關的知識(WebKit/blink內核下)。它能對動畫進行加速,但同時也存在相應的加速坑!

    ?

    簡單來說,瀏覽器為了提升動畫的性能,為了在動畫的每一幀的過程中不必每次都重新繪制整個頁面。在特定方式下可以觸發生成一個合成層,合成層擁有單獨的 GraphicsLayer。

    需要進行動畫的元素包含在這個合成層之下,這樣動畫的每一幀只需要去重新繪制這個 Graphics Layer 即可,從而達到提升動畫性能的目的。

    那么一個元素什么時候會觸發創建一個 Graphics Layer 層?從目前來說,滿足以下任意情況便會創建層:

    • 硬件加速的 iframe 元素(比如 iframe 嵌入的頁面中有合成層)
    • 硬件加速的插件,比如 flash 等等
    • 使用加速視頻解碼的?<video>?元素
    • 3D 或者 硬件加速的 2D Canvas 元素
    • 3D 或透視變換 (perspective、transform) 的 CSS 屬性
    • 對自己的 opacity 做 CSS 動畫或使用一個動畫變換的元素
    • 擁有加速 CSS 過濾器的元素
    • 元素有一個包含復合層的后代節點(換句話說,就是一個元素擁有一個子元素,該子元素在自己的層里)
    • 元素有一個 z-index 較低且包含一個復合層的兄弟元素

    本小點中說到的動畫層級的控制,原因就在于上面生成層的最后一條:

    元素有一個 z-index 較低且包含一個復合層的兄弟元素。

    這里是存在坑的地方,首先我們要明確兩點:

  • 我們希望我們的動畫得到 GPU 硬件加速,所以我們會利用類似?transform: translateZ()這樣的方式生成一個 Graphics Layer 層。
  • Graphics Layer 雖好,但不是越多越好,每一幀的渲染內核都會去遍歷計算當前所有的 Graphics Layer ,并計算他們下一幀的重繪區域,所以過量的 Graphics Layer 計算也會給渲染造成性能影響。
  • 記住這兩點之后,回到上面我們說的坑。

    假設我們有一個輪播圖,有一個 ul 列表,結構如下:

    1 2 3 4 5 6 7 8 9 <div?class="container"> <div?class="swiper">輪播圖</div> <ul?class="list"> <li>列表li</li> <li>列表li</li> <li>列表li</li> <li>列表li</li> </ul> </div>

    假設給他們定義如下 CSS:

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 .swiper { ????position:?static; ????animation:?10s?move?infinite; } .list { ????position:?relative; } @keyframes?move?{ ????100%?{ ????????transform: translate3d(10px,?0,?0); ????} }

    由于給?.swiper?添加了?translate3d(10px, 0, 0)?動畫,所以它會生成一個 Graphics Layer,如下圖所示,用開發者工具可以打開層的展示,圖形外的黃色邊框即代表生成了一個獨立的復合層,擁有獨立的 Graphics Layer 。

    但是!在上面的圖中,我們并沒有給下面的?list?也添加任何能觸發生成 Graphics Layer 的屬性,但是它也同樣也有黃色的邊框,生成了一個獨立的復合層。

    原因在于上面那條元素有一個 z-index 較低且包含一個復合層的兄弟元素。我們并不希望?list?元素也生成 Graphics Layer ,但是由于 CSS 層級定義原因,下面的 list 的層級高于上面的 swiper,所以它被動的也生成了一個 Graphics Layer 。

    使用 Chrome,我們也可以觀察到這種層級關系,可以看到?.list?的層級高于?.swiper:

    ?

    所以,下面我們修改一下 CSS ,改成:

    1 2 3 4 5 6 7 8 .swiper { ????position:?relative; ????z-index:?100; } .list { ????position:?relative; }

    這里,我們明確使得?.swiper?的層級高于?.list?,再打開開發者工具觀察一下:

    ?

    可以看到,這一次,.list?元素已經沒有了黃色外邊框,說明此時沒有生成 Graphics Layer 。再看看層級圖:

    此時,層級關系才是我們希望看到的,.list?元素沒有觸發生成 Graphics Layer 。而我們希望需要硬件加速的?.swiper?保持在最上方,每次動畫過程中只會獨立重繪這部分的區域。

    總結

    這個坑最早見于張云龍發布的這篇文章CSS3硬件加速也有坑,這里還要總結補充的是:

    • GPU 硬件加速也會有坑,當我們希望使用利用類似?transform: translate3d()?這樣的方式開啟 GPU 硬件加速,一定要注意元素層級的關系,盡量保持讓需要進行 CSS 動畫的元素的?z-index?保持在頁面最上方。

    • Graphics Layer 不是越多越好,每一幀的渲染內核都會去遍歷計算當前所有的 Graphics Layer ,并計算他們下一幀的重繪區域,所以過量的 Graphics Layer 計算也會給渲染造成性能影響。

    • 可以使用 Chrome ,用上面介紹的兩個工具對自己的頁面生成的 Graphics Layer 和元素層級進行觀察然后進行相應修改。

    • 上面觀察頁面層級的 chrome 工具非常吃內存?好像還是一個處于實驗室的功能,分析稍微大一點的頁面容易直接卡死,所以要多學會使用第一種觀察黃色邊框的方式查看頁面生成的 Graphics Layer 這種方式。

    4. 使用 will-change 可以在元素屬性真正發生變化之前提前做好對應準備

    1 2 3 4 // 示例 .example { ????will-change: transform; }

    上面已經提到過 will-change 了。

    will-change 為 web 開發者提供了一種告知瀏覽器該元素會有哪些變化的方法,這樣瀏覽器可以在元素屬性真正發生變化之前提前做好對應的優化準備工作。 這種優化可以將一部分復雜的計算工作提前準備好,使頁面的反應更為快速靈敏。

    值得注意的是,用好這個屬性并不是很容易:

    • 在一些低端盒子上,will-change?會導致很多小問題,譬如會使圖片模糊,有的時候很容易適得其反,所以使用的時候還需要多加測試。

    • 不要將 will-change 應用到太多元素上:瀏覽器已經盡力嘗試去優化一切可以優化的東西了。有一些更強力的優化,如果與 will-change 結合在一起的話,有可能會消耗很多機器資源,如果過度使用的話,可能導致頁面響應緩慢或者消耗非常多的資源。

    • 有節制地使用:通常,當元素恢復到初始狀態時,瀏覽器會丟棄掉之前做的優化工作。但是如果直接在樣式表中顯式聲明了 will-change 屬性,則表示目標元素可能會經常變化,瀏覽器會將優化工作保存得比之前更久。所以最佳實踐是當元素變化之前和之后通過腳本來切換 will-change 的值。

    • 不要過早應用 will-change 優化:如果你的頁面在性能方面沒什么問題,則不要添加 will-change 屬性來榨取一丁點的速度。 will-change 的設計初衷是作為最后的優化手段,用來嘗試解決現有的性能問題。它不應該被用來預防性能問題。過度使用 will-change 會導致生成大量圖層,進而導致大量的內存占用,并會導致更復雜的渲染過程,因為瀏覽器會試圖準備可能存在的變化過程,這會導致更嚴重的性能問題。

    • 給它足夠的工作時間:這個屬性是用來讓頁面開發者告知瀏覽器哪些屬性可能會變化的。然后瀏覽器可以選擇在變化發生前提前去做一些優化工作。所以給瀏覽器一點時間去真正做這些優化工作是非常重要的。使用時需要嘗試去找到一些方法提前一定時間獲知元素可能發生的變化,然后為它加上 will-change 屬性。

    5. 使用 dev-tool 時間線 timeline 觀察,找出導致高耗時、掉幀的關鍵操作

    1)對比屏幕快照,觀察每一幀包含的內容及具體的操作

    2)找到掉幀的那一幀,分析該幀內不同步驟的耗時占比,進行有針對性的優化

    3)觀察是否存在內存泄漏

    ?對于 timeline 的使用用法,這里有個非常好的教程,通俗易懂,可以看看:

    瀏覽器渲染優化 Udacity 課程

    ?

    總結一下

    對于盒子端 CSS 動畫的性能,很多方面仍處于探索中,本文大量內容在之前文章已經出現過,這里更多的是歸納總結提煉成可參照執行的流程。

    本文的優化方案研究同樣適用于 PC Web 及移動 Web,文章難免有錯誤及疏漏,歡迎不吝賜教。

    如果覺得文章對您有用,請隨意打賞。您的支持將鼓勵我繼續創作! 打賞支持 分類:?CSS進階,編碼技巧,性能優化

    本文轉自ChokCoco博客園博客,原文鏈接:http://www.cnblogs.com/coco1s/p/7851658.html

    總結

    以上是生活随笔為你收集整理的盒子端 CSS 动画性能提升研究的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: www性欧美| 国产黄色免费在线观看 | 免费在线激情视频 | 国产呻吟av| 青青草日本 | 欧美另类专区 | 明日叶三叶 | 极品销魂美女一区二区三区 | 欧美嫩草影院 | 亚洲大片免费观看 | 欧美第一页浮力影院 | 不卡一区二区三区四区 | 麻豆一区二区三区在线观看 | 久久精品综合网 | 成熟人妻av无码专区 | 色妞综合| 人人澡人人爽 | 亚洲欧美偷拍视频 | 国产亚洲成人精品 | 天堂国产一区二区三区 | 日韩精品一区二区三区四区 | 中文字幕av播放 | 亚洲天堂av线 | 欧美日韩一区二区三 | 极品色综合 | 在线免费观看污视频 | 欧美视频福利 | 女人性做爰24姿势视频 | 99热亚洲精品| 日韩欧美亚洲国产精品字幕久久久 | 91久色 | 色婷婷综合久久久久中文一区二区 | 日本不卡一区二区在线观看 | jizz少妇 | 国产又粗又黄又爽的视频 | 素人av在线| 在线中文av| 国产视频一区在线观看 | 欧美色亚洲色 | 怡红院成永久免费人全部视频 | 国产成人一区二区三区小说 | 乱短篇艳辣500篇h文最新章节 | 日韩伊人久久 | 欧美午夜网站 | 琪琪午夜伦理影院7777 | japanese24hdxxxx中文字幕 | 99黄色 | 超碰99在线 | 日韩欧美在线一区 | 免费激情av | 97夜夜| 秋霞国产午夜精品免费视频 | 亚洲免费视频观看 | 欧美亚色 | 日韩欧美综合视频 | 成人av网站在线 | 天天看片天天操 | 天天干天天操av | 欧美在线精品一区 | 欧美手机在线观看 | 国产精品人妻一区二区三区 | 日韩一区二区精品视频 | 欧美黑丝少妇 | 青青在线免费观看 | 欧美69久成人做爰视频 | 日韩大片av| 三级av毛片 | 亚洲毛片一区二区 | 手机av在线免费观看 | 人妻 日韩 欧美 综合 制服 | 天堂网在线看 | 亚洲天堂男人av | 亚洲素人在线 | 国产成人8x视频一区二区 | 亚洲黄色中文字幕 | 国产婷婷色一区二区在线观看 | 日韩少妇 | 干干干日日日 | 欧美性受黑人性爽 | 中文字幕永久 | 奶妈的诱惑 | 91在线视频观看 | 最近免费中文字幕大全免费版视频 | 免费在线成人av | 老司机在线看片 | 日韩性生活大片 | h片在线观看视频 | 成都电影免费大全 | 日本边添边摸边做边爱 | 国产区123 | 在线观看免费国产 | 国产精品热久久 | 国产视频一区二区视频 | 在线视频日韩欧美 | 久久久免费av| 麻豆av影视 | 国产精品久久久一区二区 | 五月婷婷伊人网 | 992tv在线成人免费观看 |