CSSのwill-change
プロパティとは?
特定のCSS処理(特にtransition
やanimation
)を実行している際に、ブラウザで「ちらつき」や「ガタつき」を経験したことがあるかもしれません。
CSSのwill-change
プロパティは、ブラウザに要素の予想される変更を知らせる役割を果たします。
このプロパティを使用すると、ブラウザは要素のスタイル変更が実際に必要になる前に必要なリソースを事前に最適化し、スタイルの変更やレンダリングをより高速かつ効率的に処理できます。これにより、「ちらつき」や「ガタつき」といった視覚的な現象を軽減または解消し、ウェブページの表示をより滑らかにします。結果として、ウェブサイトのスタイルパフォーマンス向上に貢献します。
CSSの処理における「ちらつき」と「ガタつき」現象およびCPU・GPU・ハードウェアアクセラレーションの関係を理解する
CSSの処理(特にCSSの変形やアニメーション)を行う際に、ブラウザで発生する「ちらつき」や「ガタつき」といった現象は、CPU、GPU、そしてハードウェアアクセラレーションに関連しています。以下に、それぞれの用語について説明します。.
「ちらつき」と「ガタつき」現象
CSSの処理中に要素が滑らかに変化せず、急激な変化によってブラウザ画面がちらついたりガタついたりする現象を指します。これはユーザー体験を損なう視覚的な問題です。
CPU(Central Processing Unit)
コンピュータの中央処理装置(CPU)であり、CSS処理においてはスタイルの計算、レイアウトの処理、アニメーションフレームの計算などを担当します。CPUが過剰に使用されたり最適化されていない場合、「ちらつき」や「ガタつき」といった視覚的な現象が発生することがあります。
GPU(Graphics Processing Unit)
グラフィック処理に特化した装置であり、CSSの変形やアニメーションのグラフィック部分を担当します。GPUは並列処理によって大量のグラフィック処理を行えるため、ブラウザで滑らかなアニメーションやグラフィック効果を実現する上で重要な役割を果たします。GPUの性能が不足したり制限された場合、「ちらつき」や「ガタつき」といった現象が発生することがあります。
ハードウェアアクセラレーション(Hardware Acceleration)
GPUアクセラレーションとも呼ばれ、GPUを活用してCSS処理を高速化する技術です。ハードウェアアクセラレーションを利用することで、GPUがグラフィック処理を担当し、CPUは他の処理に専念できるため、ウェブページの滑らかなレンダリングと高速な応答性を実現できます。ハードウェアアクセラレーションが使用されない、または適切に設定されていない場合、「ちらつき」や「ガタつき」といった視覚的な問題が発生することがあります。
CPU、GPU、そしてハードウェアアクセラレーションは、CSS処理中に発生する「ちらつき」や「ガタつき」といった現象に影響を与える要素です。
一部のブラウザでは、CSSのanimation
、transform
、およびtransition
に対して自動的にGPUアクセラレーションが提供されない場合があります。その場合、これらの処理はブラウザのソフトウェアレンダリングエンジンで行われます。しかし、一部のCSSプロパティはブラウザによってハードウェアアクセラレーションが適用され、より優れたレンダリング性能を実現できます。
例えば、opacity
プロパティはGPUで扱いやすいプロパティのひとつです。ブラウザは、不透明度を持つ要素に適用されるCSSのtransition
やopacity
を処理する際、該当要素のレイヤーを実際にGPUに渡してGPUで操作します。これにより、GPUの性能を最大限に活用して滑らかで高速な効果を提供できます。そのため、不透明度のプロパティは一般的に最も効率的なハードウェアアクセラレーションの対象となります。
もう一つ一般的なハードウェアアクセラレーションの対象は、CSSの3D変換(transform
)です。3D変換はGPUで効率的に処理され、特に3D空間における要素の位置、回転、スケーリングなどの変更に多く用いられます。3D変換はウェブページで視覚的な奥行きや立体感を表現するのに役立ち、GPUの性能を最大限に活用して滑らかなアニメーションを実現できます。
このように、一部のCSSプロパティはブラウザによるハードウェアアクセラレーションを通じてレンダリング性能を向上させることができます。しかし、すべてのCSSプロパティが自動的にGPUアクセラレーションを受けるわけではなく、ブラウザや環境によって異なります。開発者は適切なCSSプロパティを選択してハードウェアアクセラレーションを最大限に活用し、ブラウザのパフォーマンス最適化を図ることが求められます。
このような状況でCSSのwill-change
プロパティが有効です。will-change
を使用することで、開発者はブラウザに要素の予想される変更を通知でき、ブラウザはGPUアクセラレーションを活用して最適化された方法で処理できます。これにより、「ちらつき」や「ガタつき」といった現象を軽減または解消し、視覚的に滑らかでパフォーマンスの向上した体験を提供できます。
will-change
プロパティ
will-change
プロパティは、開発者が要素にどのような変更が予想されるかをレンダリングのヒントとしてユーザーエージェント(ブラウザ)に提供します。これにより、ユーザーエージェントは該当する変更をスムーズにレンダリングするために必要な最適化処理を事前に実行でき、開発者が機能を変更またはアニメーション化する際の「ジャンク(jank)」を回避できます。
各ブラウザはwill-change
プロパティの情報を異なる方法で活用し、同じブラウザであっても状況に応じて異なるタイミングや方法で使用することがあります。例えば、transform
プロパティにwill-change
を指定した場合、ブラウザは該当要素を自動的に「GPUレイヤー」に昇格させますが、これを多くの要素で宣言しすぎるとGPUメモリ不足による問題が発生しやすいため、この方法を避ける場合があります。つまり、will-change
プロパティはブラウザに要素の変更を通知する役割を持ち、各ブラウザはこの情報をさまざまな最適化手法に活用してレンダリング性能の向上を図ります。
形式構文
selector {
will-chnage: /* value */
}
形式定義
初期値 | auto |
---|---|
適用対象 | すべての要素 |
継承 | いいえ |
構文
/* キーワード値 */
will-change: auto;
will-change: scroll-position;
will-change: transform;
will-change: contents;
will-change: opacity;
will-change: left, bottom;
/* グローバル値 */
will-change: inherit;
will-change: initial;
will-change: unset;
CSSプロパティの値
auto |
変更が予定されているプロパティに対する最適化を自動的に行うかどうかは、ブラウザーが判断します |
---|---|
scroll-position |
スクロール位置に対する最適化を行うために、ブラウザーが自動的に処理します |
contents |
要素の内容の変更に対する最適化を行うために、ブラウザーが自動的に処理します |
opacity |
不透明度の変更に対する最適化を行うために、ブラウザーが自動的に処理します |
transform |
変換(transform)の変更に対する最適化は、ブラウザーによって自動的に処理されます |
perspective |
遠近(perspective)の変更に対する最適化は、ブラウザーによって自動的に処理されます |
left/top/right/bottom |
指定されたプロパティに対する最適化は、ブラウザーによって自動的に処理されます |
filter |
フィルター(Filter)プロパティに対する最適化は、ブラウザーによって自動的に処理されます |
color/background-color |
色または背景の変更に対する最適化は、ブラウザーによって自動的に処理されます |
all |
すべての変更に対する最適化は、ブラウザーによって自動的に処理されます |
上の表は will-change
プロパティの一部の例を示しており、それぞれの値がどの変更に対する最適化を行うかを説明しています。実際に使用される値はブラウザーや環境によって異なる場合があり、開発者は変更する要素に適した値を選択してハードウェアアクセラレーションを最大限に活用することができます。
ブラウザ互換性
プロパティ |
デスクトップ Chrome
|
デスクトップデスクトップ Edge
|
デスクトップ Firefox
|
Safari
|
---|---|---|---|---|
will-change
|
36 | 79 | 36 | 9.1 |
仕様書
仕様書 | |
---|---|
will-change
|
CSS Will Change Module Level 1 #will-change |
will-change
プロパティを使用する際に注意すべき点
will-change
プロパティの動作を理解すると、「ブラウザーにすべてを最適化させよう!」という誘惑を感じるかもしれません。その気持ちはわかります。すべての変更が最適化され、必要なときにいつでも実行されれば理想的です。しかし、will-change
は強力で優れたツールである一方、ほかの力と同様に責任を伴います。適切に使用しなければ、パフォーマンスが低下し、実際にページがクラッシュする可能性があります。
パフォーマンス向上のためのすべてのヒントと同様に、will-change
プロパティには直接的に検知できない副作用がある可能性があり、使用には注意が必要です。このプロパティを使用する際に留意すべき点がいくつかあります。これにより、最大限のパフォーマンスを得つつ、誤用による問題を回避できます。
乱用しないでください!
will-change
プロパティはパフォーマンス向上のための強力なツールですが、すべての要素に適用するのは望ましくありません。必要な要素にのみ適用し、適切な最適化を行うことが推奨されます。あまりにも多くの要素に will-change
を適用すると、メモリ使用量が増加し、ブラウザーのパフォーマンスに悪影響を及ぼす可能性があります。
不要な最適化を避けましょう!
will-change
プロパティを使用すると、ブラウザーは要素の変更を予測して最適化を行います。しかし、実際に変更が発生しない場合でもリソースを消費して最適化を行う可能性があります。したがって、will-change
は変更が予想される要素にのみ適用する必要があります。
ブラウザーに作業する十分な時間を与えましょう!
will-change
プロパティの名前には明確な理由があります。それは、変更が現在進行中であるのではなく、これから起こる変更についてブラウザーに通知するためです。will-change
を使って特定の最適化を要求し、宣言した変更に対してブラウザーがそれを実行するように促しています。しかし、その最適化を実際に行うためには、ブラウザーに多少の時間が必要です。
以下のサンプルコードは、will-change
プロパティを使用しても効果がない場合です。
.box {
width: 100px;
height: 100px;
background-color: red;
transition: transform 0.3s;
}
.box:hover {
will-change: transform;
transform: scale(1.2);
}
すでにスタイルが適用されている要素にホバー(:hover
)した場合、will-change
プロパティをすぐに使用しても、ブラウザーが実際に最適化を行うには多少の時間が必要なため、遅延なく適用されるべき状況ではほとんどまたは全く効果がありません。これは、will-change
プロパティを使用する目的を果たせなくなります。
以下のサンプルコードは、will-change
プロパティを使用して期待される効果が得られる例です。
.box {
width: 100px;
height: 100px;
background-color: red;
transition: transform 0.3s;
}
.box.optimized {
transform: scale(1.2);
}
<div class="box"></div>
// ページ読み込み後に最適化クラスを追加
window.addEventListener('load', () => {
const box = document.querySelector('.box');
box.classList.add('optimized');
});
上記のサンプルコードでは、ページ読み込み後に .box 要素に optimized クラスを追加して transform 効果を有効にしています。これにより、ページ読み込み時点で will-change
プロパティが適用された状態で変換効果が実行されます。
したがって、will-change
プロパティを適切に活用するには、変更が発生する前に要素に属性を設定し、必要な最適化をブラウザーに通知する形でコードを構成する必要があります。遅延させると will-change
プロパティが正しく機能しなくなるため、正しい方法で使用してください。
will-change
プロパティを使用した後は必ず削除してください!
will-change
プロパティはブラウザのリソースを多く消費します。一般的なブラウザの最適化動作としては、これらの最適化を解除し、できるだけ早く通常の状態に戻すことです。したがって、要素に will-change
プロパティを使って最適化を要求した後、その要素が変更されない場合や変更が不要になった場合は、プロパティを削除することで不要なリソース消費を減らし、ブラウザのパフォーマンス改善に役立ちます。
will-change
プロパティを使用した後に削除する、おおまかな一般的な例です。
// 例えば、クリック時にアニメーションを適用する要素を取得します。
var el = document.getElementById('element');
// 要素にマウスを乗せたときに <code>will-change</code> プロパティを設定します。
el.addEventListener('mouseenter', hintBrowser);
el.addEventListener('animationEnd', removeHint);
function hintBrowser() {
// アニメーションの keyframes ブロック内で変更される可能性があり、最適化が可能なプロパティ一覧
this.style.willChange = 'transform, opacity';
}
function removeHint() {
// will-changeプロパティの設定値を初期値に戻して解除します
this.style.willChange = 'auto';
}
結論
will-change
属性は、ウェブ開発者がブラウザに要素の予想される変更点を通知する役割を果たします。これにより、ブラウザは該当する変更に対して事前に最適化処理を行うことができます。will-change
属性を適切に活用することで、ウェブアプリケーションのパフォーマンスを向上させることが可能です。will-change
属性の主な利点は以下の通りです。
- レンダリング性能の改善:
will-change
属性を使用してブラウザに変更内容を事前に通知すると、ブラウザは最適化作業をあらかじめ準備し、変更をスムーズに処理できます。これによりレンダリング性能が向上します。 - アニメーション効果の最適化:
will-change
属性はアニメーション効果に特に有効です。変形(transform
)や不透明度(opacity
)など、アニメーションに関係するプロパティをwill-change
で指定すると、ブラウザはGPUを活用して効率的なアニメーションレンダリングを行います。
will-change
属性は性能最適化のための重要なツールとして活用できます。しかし、正しく使うことが必要です。必要な変更がある一部の要素だけに明示的に指定することが望ましく、すべての要素に一括で適用するのは効率的ではない場合があります。また、will-change
属性は変更が予想されるタイミングで適用し、変更が完了した後は適切に削除することが推奨されます。
性能最適化のための必須ツールとしてwill-change
属性を活用することで、ウェブアプリケーションのユーザー体験を向上させることができます。