will-changeを使ってなめらかなアニメーションを作成しよう

animationtransitionを使ってCSSアニメーションを行った際に、アニメーションがカクついて困った経験はありませんか?そんな時はwill-changeを使うことによって、カクついていたアニメーションをスムーズにすることができます。

この記事ではwill-changeの使う際の実装方法についてご説明します。

will-changeのブラウザサポート状況(2019/3/10時点)

Edge、IE以外の主要なブラウザで利用可能です。
will-changeのブラウザサポート状況

will-changeって何してくれるの?

will-changeを指定することによって、アニメーションのパフォーマンスを上げる事ができます。
アニメーションするプロパティーをwill-changeで指定することによって、ブラウザは事前にアニメーションの準備を行い、その要素がアニメーションを行うのに最適な状態にします。ただし、will-changeを多用すると逆にパフォーマンスの低下を招きます。
will-changeの内部処理については次の記事で詳しく説明しています。

これって効いてる?will-changeが効いているか確認する方法

will-changeの基本文法

.targetというクラスを持った要素をアニメーションする場合、will-changeは次のように書きます。

will-changeの使用上の注意点
will-changeを多用するとレイヤーを過剰に作成することになるため、逆にパフォーマンスの低下を招きます。アニメーションを行う場合、まずはtransform, opacityのアニメーションで代替できないかを検討してください。transform, opacityを使用したアニメーションはブラウザで最適化しており、最も処理が軽くなめらかに処理できる方法です。transform, opacityで代用できないアニメーション(例えばbox-shadow)などをアニメーションさせる場合にはwill-changeを付与することで処理が早くなることがあります。また、will-changeを使用する場合、なるべくアニメーションの直前に付与するようにしてください。will-changeを恒久的に定義した場合、不要なGPUメモリを専有することになります。

will-changeプロパティーの使い方

繰り返しになりますが、will-changeを使う場合以下の2点に気をつけてください。

使用上の注意点
  1. will-changeはなるべくアニメーションの直前につける。
  2. 何でもかんでもwill-changeを付けない。

では、アニメーションの直前にwill-changeプロパティーをつける方法を考えてみましょう。大切なことはアニメーションの直前につけて、アニメーション終了後に削除することです。ここで紹介するのはあくまで例ですので、状況に応じて使用してください。

CSSでwill-changeをつける場合

例として.wrapper_area内の.targetをホバーした際に発火するアニメーションを考えます。

この場合、.targetエレメントにマウスが行く前にまず親要素の.wrapper_area上をマウスが通過するため、次の様に書くと.targetエレメントのホバー前にwill-changeが適用されている状態になります。

これだけはやっちゃダメ
すべての要素にwill-change要素をつけるなんてことはくれぐれもしないように注意しましょう。

Javascriptでwill-changeをつける

マウスが親要素に入ったタイミングでwill-changeを付与し、アニメーションが終了した時点でwill-changeを削除しています。

will-changeが使えないブラウザでのハック

Edgeブラウザなどのwill-changeをサポートしていないブラウザでは代わりにtranslateZを使用することで同様の効果が得られます。
この3Dのtranslateプロパティーを指定するとレイヤーが新しく生成されます。しかし値自体は0なので画面の表示に影響はありません。
しかしこのプロパティーもwill-changeと同様に多用しないように気をつけてください。

先程のwill-changeを付与するところに追加しておくとwill-changeをサポートしていないブラウザでも対策することができますね。

まとめ

will-changeはうまく使うとカクついたアニメーションをなめらかにすることができます。しかし、『アニメーションの直前に付与する』『多用しない』という2点を守って正しく使わなければ逆にページ全体のパフォーマンスを下げる事があるので注意しましょう。また、EdgeブラウザではtranslateZ(0)を代わりに使用しましょう。

will-changeを使用していると、ほんとに効いているのか疑問に思うことがあります。
次の記事ではwill-changeの効果の確認方法をご紹介します。

次の記事

これって効いてる?will-changeが効いているか確認する方法

関連記事

レンダリングのパフォーマンス対策入門〜アニメーション、JSで困った時に

最新記事