はじめに
私的な比較検討です。
「描画の滑らかさ」に着目して比較していきます。詳細な比較検討記事じゃなくてごめんなさい。
あまり大きな負荷をかけるような処理にはしませんし、だからといってケースを沢山用意するでもなく、あくまで簡易的なアニメーション動作を行ったときに、どれくらいのカクつき・処理速度差が生じるのかをチェックしようという目論見です。
下記3つのライブラリを選んだ理由も結構適当で、個人的に使ってみたいなぁと思ったものをピックアップしました。
比較対象ライブラリ
-
CSSアニメーション処理の animationプロパティ および @keyframes によるキーフレーム設定を、jQueryで動的に処理するプラグイン。CSSに事前に記述する必要がなくjQueryで全て完結させるため、簡単に要素にアニメーションを付与することが可能。
-
柔軟で軽いJavaScriptのアニメーションライブラリー。CSS、個々のTransform、SVG、DOMの属性、JavaScriptのオブジェクトに対応している。
-
単純な動作から回転、変形、バウンドなどといった複雑な動作も細かく設定することができる。そして複雑な処理をこなしながらも安定した動作と処理の速さが両立されている。
処理速度比較
●使用ツール
・Electron(ブラウザではなく、デスクトップアプリケーションとして実装する想定)
●動作環境
・OS:Windows7 64bit
・CPU:Intel(R) Core(TM)i7-4790 @ 3.60GHz
・RAM:16.0GB
比較方法
- 40個の正方形を並べる
- 500msかけて、右方向へ800px移動させる
- 移動完了後、1の画像位置に戻して再び同アニメーションを開始(ループは10回)
このアニメーション処理を、デベロッパーツールを用いて監視します。
jquery.keyframes.js
for(let i = 0; i < 40; i++){
$test = $(`<div id="test${i}"></div>`);
$(body).append($test);
$test.css({
left: `${100*parseInt(i/10)}px`,
top: `${54*(i%10)}px`,
width: "30px",
height: "30px",
position: "absolute",
background: "blue"
}).keyframes({
translateX: 800,
},{
count: 10,
duration: 500,
easing: "linear",
fill: "forwards"
});
}
アニメーション処理部のみ抽出↓
.keyframes({translateX: 800}, {count: 10, duration: 500, easing: "linear", fill: "forwards"});
結果
※「メモリ使用"率"」と記載していますが、「メモリ使用"量"」の誤りです。失礼致しました。
・定期的にFPSが低下している(図の赤丸):ループ終端・始端のCPU使用率上昇(図の青丸)が関係している?
・視覚的には滑らかに動く
・メモリ使用量は安定している:妙な増加も、GCが連続的に働くこともない
⇒ 視覚的には安定しているが、FPSが定期的に低下するため、他の動作などと並行で処理した場合などに影響が出そう
anime.js
for(let i = 0; i < 40; i++){
$test = $(`<div id="test${i}"></div>`);
$(body).append($test);
$test.css({
left: `${100*parseInt(i/10)}px`,
top: `${54*(i%10)}px`,
width: "30px",
height: "30px",
position: "absolute",
background: "blue"
});
}
for(let i = 0; i < 40; i++){
anime({
targets: `#test${i}`,
duration: 500,
translateX: 800,
easing: "linear",
loop: 10
});
}
アニメーション処理部のみ抽出↓
anime({
targets: `#test${i}`,
duration: 500,
translateX: 800,
easing: "linear",
loop: 10
});
結果
・FPSは概ね安定している(図では50以下になっていないが、何度か施行したところ、時折50以下になることもあった)
・視覚的には、時折カクつく感覚がある
・メモリ使用量が定期的にガクッと落ちている:定期的にGCが働いている(図の赤丸)
※ループを重ねるごとに、正方形一つずつのスピードに差が生じているのを感じた(最大だと、10回目ループ終了時点で100msほど遅れて到着)
→ 恐らくGCの処理が優先的に行われてしまうため、時折アニメーション動作がカクつく原因となっている
⇒ 概ね滑らかに動くが、GCが頻繁に動作するのでカクつきは感じざるを得ない
TweenMax.js
for(let i = 0; i < 40; i++){
$test = $(`<div id="test${i}"></div>`);
$(body).append($test);
$test.css({
left: `${100*parseInt(i/10)}px`,
top: `${54*(i%10)}px`,
width: "30px",
height: "30px",
position: "absolute",
background: "blue"
});
}
for(let i = 0; i < 40; i++){
TweenMax.to(`#test${i}`, 0.5, {x: "800", repeat: 9, ease: Power0.easeNone});
}
アニメーション処理部のみ抽出↓
TweenMax.to(`#test${i}`, 0.5, {x: "800", repeat: 9, ease: Power0.easeNone});
結果
・FPSは概ね安定(50以下になることは少ないが、グラフを見る限りガタガタになりがち)
・視覚的には、時折カクつく感覚がある
・メモリ使用量が時折ガクッと落ちる:GCが働いている(図の赤丸)
⇒ 気にはならない程度だが、ガタガタのFPSからもわかるように、他と比べれば滑らかさには欠ける印象
まとめ
jquery.keyframes.js | anime.js | TweenMax.js | |
---|---|---|---|
FPS | 定期的に下がる | 概ね安定 | 概ね安定(50以下になることは少ないが、上下しやすい) |
見た目 | 常に滑らか | 時折カクつく | 時折カクつく |
メモリ | 安定 | 上下が激しい | 時折上下する |
・jquery.keyframes.js
当比較結果からすると、最も滑らかなアニメーションを提供できているという感覚です。
しかしjquery.keyframes.jsは基本的にCSSアニメーションをベースに置いたライブラリなので、他のアニメーションライブラリと比べてタイムライン管理などの各種機能面で劣っている部分があります。
CSSアニメーションを、簡単なタイムライン管理程度で良いからjqueryを用いて実装したいという場合には適しているかと思います。たったの3KBという軽さですので、スマホ向けなどでは抜群かも!
・anime.js
基本的に安定していますし軽いですが、同じアニメーションを複数のオブジェクトに動作させると、「オブジェクトごとにスピード差が生じてしまう」のが最も気にかかりました。
にしても機能が充実していて、描画も安定していて、それでなんと11KBってめちゃくちゃ軽い!
・TweenMax.js
今回の比較ではまるで最下位のようになってしまいましたが、実際全く問題視するほどのものではありません。カクつきも気になる程度で生じることは少ないですし、anime.jsのようなオブジェクト毎のスピード差も生じません。滑らかさに関してはkeyframesに及びませんが、概ね安定したアニメーションが確認できましたし、何よりTweenMaxの魅力というのは機能の多さだと思うので、そのあたりは実装するシステム次第と言ったところでしょう。
ちなみに容量は112KBと少々重め。それだけ機能が充実しています!
最後に
自分用メモということで作ってみた記事ですが、なんだかあまり大したものを得られない比較だったなぁと反省。
どれも何十回と施行すれば必ず多少のカクつきは起きるもので、視覚的に「これが一番素晴らしい!」ってはっきり思うことはありませんでした。どうしたって、カクつくときはカクつくんですね。
けど、jquery.keyframes.jsを比較対象にしてみて、やっぱりCSSアニメーションと言うのは滑らかだなーと思いました。javascriptを使う必要が本当にあるのか、という部分をしっかり検討することも大切ですね。
追記
下記コメント欄、@albireo様のコメントがとても分かりやすかったので、そちらもご覧頂けると幸いです。
ありがとうございます。