CSS vs. JS Animation: 哪個更快

来源:https://www.cnblogs.com/wwhhq/archive/2017/12/31/8157430.html
-Advertisement-
Play Games

CSS vs. JS Animation: 哪個更快? CSS vs. JS Animation: 哪個更快? 基於JavaScript的動畫竟然已經默默地比CSS的transition動畫快了?而且,Adobe和 Google竟然一直在發佈可以媲美原生應用的富媒體移動站點? 這篇文章將會逐點講解基 ...


CSS vs. JS Animation: 哪個更快?

CSS vs. JS Animation: 哪個更快?

基於JavaScript的動畫竟然已經默默地比CSS的transition動畫快了?而且,Adobe和 Google竟然一直在發佈可以媲美原生應用的富媒體移動站點?

這篇文章將會逐點講解基於JavaScript的DOM動畫庫,比如Velocity.js和GSAP,是如何比jQuery和基於CSS的動畫庫高效的。

jQuery

讓我們先從這個事實開始:JavaScript和jQuery被錯誤的混淆了。JavaScript的動畫是快的,但是jQuery的動畫慢。為什麼?因為雖然jQuery很強大,但是它的目標從來不是為了成為一個高效的動畫引擎。

  • jQuery不能避免佈局震蕩因為它的代碼除了動畫還提供了很多功能。

  • jQuery的記憶體消耗經常觸發垃圾回收,導致動畫卡住

  • jQuery使用setInterval而不是requestAnimationFrame (RAF)為了避免一些bug

註意,佈局震蕩引起了動畫開始處的卡頓,垃圾回收導致了動畫進行中的卡頓,RAF的缺席導致了幀率低。

實現的例子

避免佈局震蕩,包括簡單地合併DOM查詢和DOM更新:

var currentTop,
  currentLeft;

/* 有佈局震蕩 */
currentTop = element.style.top; /* QUERY */
element.style.top = currentTop + 1; /* UPDATE */

currentLeft = element.style.left; /* QUERY */
element.style.left = currentLeft + 1; /* UPDATE */

/* 沒有佈局震蕩 */
currentTop = element.style.top; /* QUERY */
currentLeft = element.style.left; /* QUERY */

element.style.top = currentTop + 1; /* UPDATE */
element.style.left = currentLeft + 1; /* UPDATE */

發生在更新之後的查詢會強制瀏覽器立馬重新佈局,並計算給出頁面樣式的計算值(把更新的影響考慮在內)。這對於運行於16ms間隔的動畫來講,會產生巨大的開銷。

同樣,實現RAF並不需要對既有代碼改動很大。讓我們來對比一下RAF的實現和setInterval的實現:

var startingTop = 0;

/* setInterval: 每16ms運行一次來達到60fps (1000ms/60 ~= 16ms). */
setInterval(function() {
  /* 由於這裡的代碼會在1s內執行60次,所以我們把top屬性每秒1單位的增長分成60份 */
    element.style.top = (startingTop += 1/60);
}, 16);

/* requestAnimationFrame: 不管瀏覽器是否處於最優狀態,都試圖運行在60fps */
function tick () {
    element.style.top = (startingTop += 1/60);
}

window.requestAnimationFrame(tick);

RAF極大限度地提高了動畫的性能。而您只需要修改為數不多的代碼。

CSS Transitions

CSS transitions的動畫性能優於jQuery,它把動畫的邏輯交給了瀏覽器本身。這會有助於:1)優化DOM交互和記憶體消耗以避免卡頓,2)在底層藉助RAF的特性,3)強制硬體加速(藉助GPU的能力來提高動畫性能)。

然而,實際情況是,這些優化可以直接通過JavaScript來實現,GSAP已經致力於此多年。Velocity.js,一個新的動畫引擎,不止藉助於上述技術,還應用了其他方法--我們將很快探討。

明白JavaScript動畫可以媲美CSS動畫庫這一事實,只是我們計劃的第一步。第二步是我們要明白JavaScript動畫可以比CSS動畫還快。

讓我們從檢查CSS動畫庫的缺陷開始:

  • Transitions的強制硬體加速是使GPU加速,然而這反而會導致GPU強壓狀況下動畫的卡頓。這些影響在移動設備上更為嚴重。(特別地,這個卡頓是由於數據在瀏覽器的主線程和排序線程間傳遞的開銷導致的。一些CSS屬性,比如transforms和opacity,是不受這個開銷影響的。)Adobe在這裡闡述了這個問題。

  • Transitions在IE10以下有相容問題, 這在PC端站點會很容易導致問題發生,因為IE8和IE9依然很流行

  • 因為transitions並不是被JavaScript控制(它們只是被JavaScript觸發),瀏覽器並不知道如何同步地使用JavaScript代碼來操控優化transitions。

相反地:基於JavaScript的動畫庫,可以自己決定什麼時候使用硬體加速,可以相容所有版本的IE,並且它們非常適合批量動畫優化。

我的建議是,當您只是開發移動站點,並且您的動畫只包含簡單的狀態變化時,可以使用原生CSS transitions。在這種情況下,transitions算是一種高效並且原生的解決方案,並且可以把所有的動畫邏輯只放在css中,避免了因為引入JavaScript庫而導致頁面臃腫。但是,如果您正在設計複雜的UI,或者正在開發具有狀態UI的應用程式,請使用JavaScript動畫庫,它可以使您的動畫保持高性能,使您的工作流程保持可控。特別是在管理CSStransitions方面做得很棒的一個庫是 Transit

JavaScript Animation

Okay,所以JavaScript在性能上可以占上風。但是JavaScript究竟可以快多少呢?其實,它已經快到可以創建複雜的,通常只能用WebGL構建的3D animation demo。已經快到可以創建通常只能用Flash或者影效處理做到的multimedia teaser。已經快到可以創建通常只能用canvas構建的virtual world

為了直觀比較動畫庫的領先性能,包括Transit(內部使用CSS transitions),請查閱Velocity的文檔,在VelocityJS.org

依然存在問題:JavaScript究竟如何達到高性能?下麵是基於JavaScript的動畫庫能實現的優化列表:

  • 為了減小佈局震蕩,將整個動畫中涉及到DOM同步化到堆棧中。

  • 緩存鏈式調用中的屬性值,以儘量減少DOM查詢(它是影響DOM動畫性能的致命弱點)的發生。

  • 在同一個跨同級元素調用中緩存單位轉換比率(例如PX到%、em等)。

  • 當樣式更新在視覺上不明顯時,跳過更新。

回顧之前講的佈局震蕩,Velocity.js利用這些最佳實踐來緩存動畫的結束值,這些值會被重用為之後動畫的開始值,從而避免再次查詢DOM元素的初始值:

$element
  /* 將元素向下滑動到視圖中。 */
  .velocity({ opacity: 1, top: "50%" })
  /* 延遲1000ms,元素滑動出視圖 */
  .velocity({ opacity: 0, top: "-50%" }, { delay: 1000 });

在上面的例子中,第二個Velocity自動知道它應該從opacity為1,top為50%開始。

瀏覽器最終可以自己執行很多相同的優化,但這樣做將需要極大地限制開發人員編寫動畫代碼的方式。因此,同樣的原因,jQuery不使用RAF(見上文),瀏覽器也永遠不會強加優化,即使這些優化只有非常小的可能會打破規範或偏離預期的行為。

最後,讓我們來比較一下這兩個JavaScript動畫庫(Velocity.js和GSAP)。

  • GSAP是一種快速、功能豐富的動畫平臺。Velocit是一個輕量級工具,可以極大地提高UI動畫性能和工作流程。

  • GSAP需要許可費。Velocity是通過許MIT開源的。

  • 性能都很優異,GSAP和Velocity在真實項目中沒有區別。

我的建議是:當您需要精確的控制(例如重映,暫停/恢復/搜索)、運動(例如Bezier曲線路徑),或複雜的分組/排序時,使用GSAP。這些特性對於游戲開發和某些niche應用非常重要,但在Web應用程式的UI中並不常見。

Velocity.js

定位GSAP功能豐富,並不意味著Velocity功能單一。相反地,在壓縮後只有7Kb的文件中,Velocity不僅提供了jQuery$.animate()的所有功能,而且提供了color animation,transforms,loops,easings,class animation和scrolling。

簡而言之,Velocity是jQuery、jQuery UI和CSStransitions的最佳組合。

進一步,從方便的角度,Velocity在底層使用jQuery的$.queue()方法,因此可以無縫地與jQuery的$.animate(), $.fade()$.delay()函數交互。並且,由於Velocity的語法和$.animate()一致,您頁面的代碼不需要修改

讓我們快速看一下Velocity.js。在基礎動畫上,Velocity和$.animate()一樣:

$element
  .delay(1000)
  /* 使用Velocity的2000ms內改變元素top屬性的動畫*/
  .velocity({ top: "50%" }, 2000)
  /* 當上面Velocity動畫執行完時,使用標準的jQuery方法來使元素淡出*/
  .fadeOut(1000);

在高級動畫上,複雜的滾動場景和三維動畫都可以創建——只需要兩行簡單的代碼:

$element
  /* 在1000ms內,瀏覽器滾動到這個元素的頂部 */
  .velocity("scroll", 1000)
  /* 之後使元素繞著它的Y軸旋轉360度。 */
  .velocity({ rotateY: "360deg" }, 1000);

結束語

Velocity的目標是保持領先的DOM動畫性能和便捷。本文的重點是前者。請去VelocityJS.org學習更多關於後者的知識。

在我們結束之前,記得_*一個高性能的UI不僅僅是選擇合適的動畫庫_。頁面的其餘部分也應該優化。從下麵這些奇妙的Google話題中學習更多:


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 手機拍照身份證識別使用成熟的OCR文字識別技術,通過手機或者帶有攝像頭的終端設備對身份證拍照,並對證件照片做OCR文字識別,提取身份證信息。此技術越來越被廣大消費用戶認知並使用。優點是:方案成本低,用於智能手機,使用環境方便,功能容易擴展。 近幾年,各種各樣的APP正在取代PC端軟體成為用戶應用方式 ...
  • 13.Label的作用是什麼?是怎麼用的? label標簽來定義表單控制間的關係,當用戶選擇該標簽時,瀏覽器會自動將焦點轉到和標簽相關的表單事件上。 <label for="Name">Number:</label> <input type="text" name="Name" id="Name"/ ...
  • 1. css的全稱 2. CSS的層疊次序:優先順序由低到高 ·瀏覽器設置 ·外部樣式表 或者 內部樣式表 —— 就近原則 ·內聯樣式 3. CSS的3種形式,以及每種形式的語法格式 ——註意樣式表的為什麼常用link 4. CSS基本語法: selector(property:value; colo ...
  • opacity用來設置元素的透明度。 值被約束在[0.-1.0]範圍內,如果超過了這個範圍,其計算結果將截取到與之最相近的值。 0表示完全透明,1表示完全不透明。 瀏覽器支持: (1).IE瀏覽器支持此屬性。 (2).火狐李藍旗支持此屬性。 (3).谷歌瀏覽器支持此屬性。 (4).opera瀏覽器支 ...
  • 一.什麼是CSS: CSS是Cascading Style Sheets的縮寫,通常為級聯樣式表。 CSS已經是網路不可或缺的元素,為瀏覽者呈現五彩繽紛的頁面效果起到了重要作用。 CSS是一種標記語言,不需要進行編譯,直接就可以在瀏覽器中執行。 二.使用CSS的優勢: (1).能夠極大提高代碼的簡潔 ...
  • 事件可以是瀏覽器行為也可以是用戶行為。 比如頁面文檔內容載入完成或者用戶滑鼠點擊等。 當一個事件發生的時候,需要特定的行為來響應這個事件,所以要為事件註冊事件處理函數。 代碼實例: 為按鈕註冊click事件處理函數,當點擊按鈕的時候,此函數就會執行。 本章節只是簡單介紹一下JavaScript事件的 ...
  • 一.HTML簡單介紹: HTML是Hypertext Markup Language的英文縮寫,即超文本標記語言。 它是一種標記語言而非編程語言,由瀏覽器解釋支持。 html文件是一種文本文件,可以用記事本打開,當然也可以用其他開發工具,比如dreamweaver和VS等等。通過在文本中添加各種標簽 ...
  • 現在我們的Redux和React Redux已經基本實現了,在Redux中,觸發一個action,reducer立即就能算出相應的state,如果我要過一會才讓reducer計算state呢怎麼辦?也就是我們如何實現非同步的action呢?這裡就要用到中間件(middleware) 1. 中間件(mi ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...