アニメーションで要素を動かす際に、left、right、top、bottomを使用しているコードを見かけることがあります。
しかし、leftなどの位置調整を行うプロパティーはレンダリングのパフォーマンスの低下を起こすため、アニメーションには使ってはいけません。
理由を詳しく知りたい方はこちらの記事を見てください。
この記事では使用例を交えながら、transform
、opacity
の使い方を見ていきましょう。
TransformとLeftを使ったアニメーションのパフォーマンス比較
まず、transformとleftをそれぞれ使用した際のパフォーマンスの比較を行います。ここでは、パフォーマンスを比較しやすくするために、以下の条件を用意しました。
- 400個のブロックを作成して、それぞれ200個ずつに分け、Transformで動かすものを青色、Leftで動かすものを赤色としました。
- ブラウザの設定からCPUのパフォーマンスを1/6に設定し、意図的に処理を遅くして測定しました。
ソースコード
Codepen
青色がスムーズに動いているのに対して、赤色は動きがカクカクしているのが見て取れます。これがブラウザの処理フローによるパフォーマンスの違いです。サイトの規模が大きくなるに連れて、パフォーマンスを意識した実装をしているかどうかは、見た目に大きな違いを生みます。この記事でtransform
、opacity
の使い方を学んで、積極的に導入しましょう。
では実際のケーススタディーを見てみましょう。
ケーススタディー
位置を移動する
まずは位置を移動するアニメーションを考えてみます。位置を変更する場合はtransform: translate
を使います。
ダメな例:top, left, bottom, right, margin, paddingで移動
良い例:transform: translateで移動
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 35 36 | <style> .demo1{ position: relative; height: 200px; color: white; } .swing{ position: absolute; left: 0; width: 100px; height: 100px; } .swing.bad{ top: 100px; background: red; animation: swing_bad 2s ease 0s infinite alternate; } .swing.good{ background: blue; animation: swing_good 2s ease 0s infinite alternate; } @keyframes swing_good { 100%{ transform: translateX(200px); } } @keyframes swing_bad { 100%{ left: 200px; } } </style> <div class="demo1"> <div class="swing good"></div> <div class="swing bad"></div> </div> |
Transform(青色)を使うとスムーズに動いていますね。Left(赤色)は動きがカクついているのが確認できます。
大きさを変更する
次に大きさを変更します。大きさを変更する際はtransform: scale
を使います。
ダメな例:height、width、paddingで拡大縮小
良い例:transform: scaleで拡大縮小
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 35 36 37 38 | <style> .demo2{ position: relative; height: 300px; color: white; } .scale{ position: absolute; left: 0; width: 100px; height: 100px; } .scale.bad{ top: 150px; background: red; animation: size_bad 2s ease 0s infinite alternate; } .scale.good{ background: blue; transform-origin: top left; animation: size_good 2s ease 0s infinite alternate; } @keyframes size_good { 100%{ transform: scale(1.5); } } @keyframes size_bad { 100%{ width: 150px; height: 150px; } } </style> <div class="demo2"> <div class="scale good">Transform: scaleで拡大</div> <div class="scale bad">Width, Heightで拡大</div> </div> |
この比較では見た目にはそれほど大きな違いは見られないかもしれません。拡大すると赤色の方が動きがカクついているのが確認できます。また、拡大する要素に隣接する要素や子要素がある場合、それら要素の位置や大きさも再計算する必要があるため、よりパフォーマンスの低下が引き起こされます。
scaleX
、scaleY
、rotate
、skew
など色々な変形を行える関数が用意されているので、width
、height
よりも柔軟な変形が行なえます。透明度を変更する
背景の透明度を変更する場合はopacity
を使いましょう。
ダメな例:背景色(rgba)の透明度を変える
良い例:opacityを使う
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 35 36 37 38 39 40 41 | <style> .demo3{ position: relative; height: 200px; color: black; } .opc, .opc * { width: 100px; height: 100px; } .opc.bad{ top: 100px; background: red; animation: opc_bad 2s ease 0s infinite alternate; } .opc .good{ position: absolute; top: 0; background: blue; animation: opc_good 2s ease 0s infinite alternate; } .text{ position: relative; z-index: 2; } @keyframes opc_good { 100%{ opacity: 0; } } @keyframes opc_bad { 100%{ background: rgba(255, 0, 0, 0); } } </style> <div class="demo3"> <div class="opc"><div class="text">Opacityで変更</div><div class="good"></div></div> <div class="opc bad">RGBAの透明度を変更</div> </div> |
悪い例では背景色の透明度を変更しています。背景色の透明度を行うのと、その要素自体の透明度を変えるのでは一見同じに見えますが、ブラウザからすると背景色の透明度を変更する方が処理が重くなります。ホバー時の色の変更などは、なるべくopacity
で色の濃淡を調節し、視差効果を付けたほうがブラウザには優しい設計となります。
まとめ
transform
, opacity
を意識して使用することで、ブラウザの負荷を小さくする事ができます。
上で挙げた例を見てもわかりますが、アニメーションさせる要素が少なかったり、画面に表示されている要素の数がそれほど多くない場合、transformを使用しなくても大きな違いは出ません。しかし、ウェブサイトが成長し、規模が大きくなるとその違いは歴然です。そうなってから修正するのは大変です。日頃から意識してtransform
、opacity
を使用するようにしましょう。
次の記事ではすでにパフォーマンスの低下が見られるサイトの場合、どの様にして改善していけばよいのかをChromeのDevtoolを使ってご説明します。