コンポーザ オンリー プロパティに固執し、レイヤ数を管理する

合成では、ページのペイントされた部分がまとめられて画面に表示されます。合成されていないアニメーションは、より多くの作業が必要であり、低価格のスマートフォンや、パフォーマンスに負荷の高いタスクがメインスレッドで実行されている場合、ぎくしゃくしてスムーズに動作しないことがあります。

この領域には、ページのパフォーマンスに影響する 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 のタイムラインでペイント プロファイラを有効にする必要があります。

スイッチをオンにして、録音します。録画が完了すると、フレームレートのバーと詳細の間に表示される個々のフレームをクリックできるようになります。

デベロッパーがプロファイリングに興味を持っているフレーム。

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

Chrome DevTools のレイヤタブボタン。

このオプションを選択すると、そのフレーム内のすべてのレイヤをパン、スキャン、ズームインできる新しいビューが表示されます。各レイヤが作成された理由も表示されます。

Chrome DevTools のレイヤビュー。

このビューを使用すると、レイヤの数を確認できます。スクロールや遷移などのパフォーマンスに影響するアクションでコンポーズに多くの時間が費やされている場合(4 ~ 5 ms 程度を目標にしてください)、この情報を使用してレイヤの数や作成された理由を確認できます。そこから、アプリのレイヤ数を管理できます。