こんにちは、id:j-horikawaです。
昨今のUIはリッチ化が進みインタラクティブなデザインを実現するためアニメーションが多く使われています。
アニメーションを多用すると、コンポーネントのアニメーションがカクつく、もたつくなど処理が重くなりがちです。
今回はアニメーションのパフォーマンスに関する1つの改善方法としてDOMのレンダリングに絞った対応策を探ってみましょう。
今回改善したいアニメーション
要素が左から右へ400px移動するだけのシンプルな実装なので実際に処理が重くなることはないのですが、処理が重くなりアニメーションがカクついているという前提でお話を進めます。
HTML
<div class="animation-cpu">CPU</div>
CSS
.animation-cpu { animation-name: position-element; animation-duration: 2s; animation-iteration-count: infinite; animation-timing-function: ease; background-color: gray; color: white; width: 100px; height: 100px; position: relative; left: 0; top: 0; } @keyframes position-element { 100% { left: 400px; } }
問題箇所の調査
Chromeをお使いの場合、DevToolsのRenderingタブにあるPaint flashingを有効にしてみましょう。
Renderingタブがない場合は下ペインの左にある「︙」からRenderingを選択すると表示されます。
Paint flashingを有効にするとページ上で再描画が発生したエリアが緑色でハイライトされ、DOMのリペイントが行われていることがわかります。
このリペイントは要素の位置が変更されるたびにCPUが使用されペイント処理が走るため、使用箇所が多くなるとCPUの負荷が高くなっていきます。
リペイントによる処理の負荷を軽減させる
今回の左から右へ要素が移動する処理、つまりright, left, top, bottomによる位置の移動にはCPUが使用されるので、GPUを使用する transform
プロパティに変更します。
HTML
<div class="animation-gpu">GPU</div>
CSS
.animation-gpu { animation-name: transform-css; animation-duration: 2s; animation-iteration-count: infinite; animation-timing-function: ease; background-color: gray; color: white; width: 100px; height: 100px; } @keyframes transform-css { 0% { transform: translate(0px); } 100% { transform: translate(400px); } }
要素が左から右へ400px移動する処理を transform
に置き換えました。
Paint flashingを有効にした状態で比較してみると transform
を使用した要素がリペイントされていないことが分かります。
対象ブラウザの使用率によるバランスの良い設計が必要
GPUを使った処理が早いとは言え今回ご紹介した改善方法はアニメーションの描画に関する速度改善です。
GPUを使ったハードウェア・アクセラレーションを行うとメモリの使用率が高くなり端末への負荷が高くなります、改善によって新しいボトルネックが生まれないか慎重に確認を行いながらパフォーマンス改善を行うと良いでしょう。
最後に
ContractSはエンジニア・デザイナーを募集しています。 共にプロダクト作りを通して、社会・組織を良くしていきましょう! 興味がある方はぜひこちらからご連絡ください!