コンポジタ専用プロパティを使用し、レイヤ数を管理する

コンポジットは、画面に表示するために、ページのペイントされた部分がまとめて置かれている場所です。

コンポジットは、画面に表示するために、ページのペイントされた部分がまとめて置かれている場所です。

ページのパフォーマンスに影響を与える 2 つの重要な要因があります。管理対象となるコンポジタ レイヤーの数と、アニメーションのために使用するプロパティです。

  • アニメーションの形状と不透明度の変更のみを行うようにします。
  • 移動要素を will-change または translateZ でプロモートします。
  • プロモーション ルールの過剰な使用は避けてください。レイヤにはメモリと管理が必要です。

最もパフォーマンスの高いピクセル パイプラインでは、レイアウトとペイントの両方を避け、コンポジットの変更のみを必要とします。

レイアウトもペイントもないピクセル パイプライン。

これを実現するには、コンポジタのみで処理できるプロパティの変更のみを行う必要があります。現在、これに該当するプロパティは transformopacity の 2 つだけです。

レイアウトやペイントをトリガーせずにアニメーション化できるプロパティ。

transformopacity を使用する際の注意点は、これらのプロパティを変更する要素がそれ自身のコンポジタのレイヤーになければならないということです。レイヤを作成するには、要素をプロモートする必要があります。これについて次に説明します。

アニメーション化する要素をプロモートする

ペイントの複雑さの簡略化とペイントエリアの縮小」セクションで説明したように、アニメーション化する要素をそれら自身のレイヤーにプロモートする必要があります(合理的な範囲にとどめてください)。

.moving-element {
  will-change: transform;
}

古いブラウザ、または will-change をサポートしていないブラウザの場合は、次のようにします。

.moving-element {
  transform: translateZ(0);
}

レイヤーを管理して、レイヤーが増えすぎないようにする

レイヤーによってパフォーマンスが向上することが多いことを知ると、次のように、ページ上のすべての要素をプロモートしたくなることでしょう。

* {
  will-change: transform;
  transform: translateZ(0);
}

これは、ページ上のあらゆる要素をプロモートしたいという遠回しな言い方です。ここでの問題は、作成したすべてのレイヤーにメモリと管理が必要であり、それはコストなしでは行えないということです。実際、メモリが限られている端末では、レイヤーの作成によって得られる利益を、パフォーマンスへの影響がはるかに上回ることがあります。すべてのレイヤーのテクスチャは GPU にアップロードする必要があるため、CPU と GPU 間の帯域幅や、GPU のテクスチャで使用可能なメモリの面でさらなる制約が生じます。

Chrome DevTools を使用してアプリのレイヤを理解する

Chrome DevTools のペイント プロファイラの切り替え。

アプリ内の各レイヤーを理解し、その要素がなぜレイヤーを有しているかを知るために、Chrome DevTools の Timeline でペイント プロファイラを有効にする必要があります。

これがオンになっている場合、記録を実行する必要があります。記録が終了したら、frames-per-second バーと詳細の間にある個々のフレームをクリックできるようになります。

デベロッパーがプロファイリングを行うフレーム。

これをクリックすると、詳細に新しいオプションとして [レイヤ] タブが表示されます。

Chrome DevTools の [layer] タブボタン。

このオプションでは新しいビューが表示されます。これを使用して、対象のフレームの間にすべてのレイヤーをパン、スキャン、およびズームインすることができ、各レイヤーが作成された理由も示されます。

Chrome DevTools の [レイヤ] ビュー。

このビューを使用すると、現在あるレイヤーの数を追跡することができます。スクロールや遷移などのパフォーマンスが重要なアクションで合成に多くの時間を費やす場合(4 ~ 5 ミリ秒を目安に)、この情報を使用すると、レイヤ数や作成された理由を確認したり、そこからアプリのレイヤ数を管理したりできます。