CSS VS JSアニメ、どっちが早いか

10299 ワード

英文原文:https://davidwalsh.name/css-js-animation
原作者Julian ShapiroはVelocity.jsの作者、Velocity.jsは効率的で使いやすいjsアニメーションライブラリです.「Javascript Webアニメーションデザイン」という本では、このライブラリについてより具体的な分析が多く、VelocityやJSアニメーションに興味がある人は見ることができます.
Javascriptベースのアニメーションは、CSS transitionと同じように速く、さらに速くなるはずがありません.いったい何の秘密なのか.AdobeとGoogleは、リッチメディアモバイルサイトの速度をnative appに匹敵させるにはどうすればいいのでしょうか.
この記事では、JavascriptベースのDOMアニメーションライブラリ(Velocity.jsやGSAPなど)がjQueryやCSSベースのアニメーションライブラリよりも効率的である理由を少しずつ説明します.
JQuery
JavascriptとjQueryの両者を誤って混同してはいけないという基本的なことから始めましょう.Javascriptアニメーションは速いが、jQueryアニメーションは遅い.どうしてですか.jQueryは非常に強力ですが、その設計目標は効率的なアニメーションエンジンではありません.
1.JQueryはlayout thrashingを避けることができません.アニメーションだけでなく、他のシーンにも使用する必要があります.
2.JQueryのメモリ消費は頻繁にゴミ回収メカニズムをトリガし、ゴミ回収はアニメーションを一時的に停止させる.
3.JQueryはrequestAnimationFrame(RAF)ではなくsetIntervalを使用しており、RAFがフォーカスを失ったときにアニメーションを停止しないようにしている(訳者注:JQuery 3.0はRAFを統合しており、IE 8および以下のバージョンはサポートされていない).
注意layout thrashingはアニメーションの開始時にカートンする原因であり、ゴミ回収はアニメーションの実行中にカートンする原因であり、RAFを使用しないとアニメーションのフレームレートが低くなることが多い.
実装例
layout thrashingを回避するには、一括同期操作DOM要求とDOM更新から構成されます.
var currentTop,
    currentLeft;

/* With layout thrashing. */
currentTop = element.style.top; /* QUERY */
element.style.top = currentTop + 1; /* UPDATE */

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

/* Without layout thrashing. */
currentTop = element.style.top; /* QUERY */
currentLeft = element.style.left; /* QUERY */

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

更新操作後のアクセス操作では、ブラウザがページ要素のスタイルを再計算するように強制されます(更新されたスタイルを適用すると正しい値が得られます).これは一般的な操作ではあまり性能損失はありませんが、わずか16 ms間隔のアニメーションでは顕著な性能オーバーヘッドが発生します.操作の順序を少し変えるだけで、アニメーションのパフォーマンスが大幅に向上します.
同様に、RAFを使用しても、現在のコードを大量に再構築することはできません.RAFとsetIntervalの違いを比較してみましょう.
var startingTop = 0;

/* setInterval: Runs every 16ms to achieve 60fps (1000ms/60 ~= 16ms). */
setInterval(function() {
    /* Since this ticks 60 times a second, we divide the top property's increment of 1 unit per 1 second by 60. */
    element.style.top = (startingTop += 1/60);
}, 16);

/* requestAnimationFrame: Attempts to run at 60fps based on whether the browser is in an optimal state. */
function tick () {
    element.style.top = (startingTop += 1/60);
}

window.requestAnimationFrame(tick);

RAFはアニメーションのパフォーマンスを最大限に向上させることができますが、そのためにはコードを簡単に変更する必要があります.
CSS Transitions
CSS transitionの性能はjQueryアニメーションより良く、transitionはアニメーションロジックをブラウザ自身に投げて実行する.そのメリットは次のとおりです.
1.DOM操作とメモリ消費量を最適化することでカートンを回避
2.RAF下地の原理を利用する
3.ハードウェアアクセラレーションを強制する(GPUアクセラレーションを使用してアニメーション効果を向上させる).
しかし、実際にはJavascriptはこれらの最適化を直接使用することができます.GSAPはすでにこれらの最適化を何年もしています.Velocity.jsは、新しいアニメーションエンジンで、同じ技術を実現しただけでなく、もっと遠くまで歩いています.後でお話しします.
現実に直面して、JavascriptアニメーションがCSSアニメーションの性能と競争できるようにするのは、私たちの復興計画の第一歩にすぎません.2つ目のステップは、実際にJavascriptアニメーションがCSSアニメーションよりも速いことを意識することです!
CSSアニメーションの欠陥をテストしてみましょう.
1.Transitionの強制使用GPU加速により、アニメーションカートンがスムーズではなく、高負荷で束縛される.このような状況はモバイルデバイスで激化します.(特に、カートンは、ブラウザのプライマリ・スレッドとそのソート・スレッドとの間でデータが転送されるときに発生するオーバーロードに起因する.transformsやopacityなどのCSS属性は、このような制限を受けない.)Adobe兄弟のブログでこの話題を話したことがあります.
2.TransitionはIE 10では機能しないため、多くのデスクトップシーンに残っているIE 8、IE 9で互換性の問題が発生する.
3.Transitionはオリジナルでjavascriptによって制御されないため(javascriptによってトリガーされるだけ)、ブラウザはTransitionを操作するjavascriptコードをどのように最適化するか分からない.
逆に、javascriptベースのアニメーションライブラリは、ハードウェアアクセラレータをいつ有効にするかを自分で決めることができ、IEの各バージョンで正常に動作し、一括アニメーションの最適化にも非常に適しています.
私の提案は、モバイル端末向けに開発されたページでオリジナルのcss Transitionsを使用することができ、あなたのアニメーションは簡単な状態変化だけで構成されています.このような場合、transitionsは、javascriptライブラリを多く使用することでページが膨張する高性能な埋め込みを招くことなく、アニメーションの論理をすべてcssスタイルシートに保持できる方法です.しかし、複雑なUIアニメーションを設計しているか、マルチステータスUIのアプリを開発している場合は、アニメーションライブラリを使用して、アニメーションが高性能な状態にあるようにし、ワークフローが処理しやすい状態にあることを覚えておいてください.
JavaScriptアニメーション
はい、javascriptは使用時に性能が優れています.しかしjavascriptはいったいどれだけ速くできますか?スタート--比較的強い3 Dプレゼンテーションアニメーションを構築するのに十分です.あなたが考えているように、通常はwebGlでしかできません.複雑なマルチメディアアニメーションを作成するのに十分なスピードで、通常はFlashまたはAfter Effectsを使用して完成します.
仮想世界を構築できるほど速く、通常はcanvasを使用して完成します.
主流のアニメーションライブラリの表現を直接比較するために、Transit(CSSのTransitionを使用している)を含めて、ここではまずVelocityの公式ドキュメント:VelocityJSを見ることができます.org
以前の問題はjavascriptがどのように高性能に達したのかということです.
以下に、javascriptのアニメーションライブラリが適切に機能する最適化の表現を示します.
1.DOM-を同期してスタック間のアニメーションチェーンを調整し、レイアウトのジッタを最小化します.
2.チェーンコールで属性値をキャッシュしてDOMクエリの発生を最小限に抑える(これが高性能アニメーションのアカレスの踵である).
3.更新がほとんど見えない場合は、スタイル更新をスキップします.
前に議論したレイアウトのジッタを再確認できますjsは、これらのベストプラクティスを用いて、アニメーションの終了値をキャッシュし、その後のアニメーションの開始値として再利用する.これにより、DOM要素の開始値の再クエリが回避されます.
    $element
    /* Slide the element down into view. */
    .velocity({ opacity: 1, top: "50%" })
    /* After a delay of 1000ms, slide the element out of view. */
    .velocity({ opacity: 0, top: "-50%" }, { delay: 1000 });

上記の例では、2回目のvelocity呼び出しで、opacityが1、topが50%のときに自動的に開始すべきであることが分かった.
ブラウザは、このような最適化を独自に実行できますが、開発者が手動でアニメーションコードを書く方法を大きく制限します.
したがって、同じ理由に基づいて、JqueryはRAFを用いず(前述を参照)、ブラウザは仕様を破ったり、予想された動作から逸脱したりする可能性のある最適化を実行しない.
最後に、2つのjavascriptアニメーションライブラリ(velocityとGSAP)を比較してみましょう.
1.GSAPは高速で、機能が豊富なアニメーションライブラリプラットフォームです.velocityはUIのアニメーション性能と仕事の劉を大幅に向上させる軽量級のツールです.
2.GSAPは多くの種類のビジネスアプリケーションに有料で、velocityは完全にオープンソースで無料で、非常に自由なMITlicenceを使用しています.
3.実際の応用において、両者の性能表現は相当する.
時間を正確に制御する必要がある場合は、GSAP(remapping、一時停止/継続/スキップ)、移動(ベッセル曲線など)、複雑なアニメーションの組み合わせ/キューを使用することをお勧めします.これらの特性はゲーム開発やいくつかの特殊な応用にとって非常に重要であるが,web応用ではあまり見られない.
Velocity.js
GSAPは豊富な機能を持っているが、Velocity自身の機能が豊富ではないという意味ではない.逆に、圧縮後7 KBのパッケージでは、VelocityはJqueryanimateのすべての機能を実現しただけでなく、カラーアニメーション、変換、ループ、移動、クラスアニメーション、スクロールもパッケージ化されています.
簡単に言えば、VelocityはjQuery、jQuery UI、CSS transitionsとの最高の結合です.
さらに、便利な観点から、Vは最下位でJqueryの$を用いる.Quene()メソッド.だからJqueryの$.animate(), $.fade(), and $.delay()はシームレスに相互に動作します.また、Vの文法と$.animate()は完全に一致しており、ページのコードを変更する必要はありません.
Vを素早く見てみましょう.Vとanimateの文法はまったく同じです.
$element
    .delay(1000)
    /* Use Velocity to animate the element's top property over a duration of 2000ms. */
    .velocity({ top: "50%" }, 2000)
    /* Use a standard jQuery method to fade the element out once Velocity is done animating top. */
    .fadeOut(1000);

高度な使い方では、複雑なスクロールシーンと3 Dアニメーションを作成できます.簡単なコードは2行しかありません.
$element
    /* Scroll the browser to the top of this element over a duration of 1000ms. */
    .velocity("scroll", 1000)
    /* Then rotate the element around its Y axis by 360 degrees. */
    .velocity({ rotateY: "360deg" }, 1000);

まとめ
Vの目標は、DOMでのアニメーション性能と便利さのリーダーになることです.この文章の重点は前者である.前に述べたようにorgは後者を知ることができる.
終了する前に、高性能UIは適切なアニメーションライブラリを選択するだけではないことを覚えておいてください.ページの残りの部分も最適化する必要があります.