CSS の will-change 属性について詳しく見る

青灯夜游
リリース: 2021-06-28 11:14:48
転載
4577 人が閲覧しました

CSS will-change 属性とは何ですか?それの使い方?この記事では、will-change 属性について学習し、いつ使用するか、どのように使用するか、CSS で will-change をより適切に設定する方法を確認します。

CSS の will-change 属性について詳しく見る

will-change

CSS 属性 will-change は、要素が変更されることをブラウザに伝える方法を Web 開発者に提供します。要素の属性が実際に変更される前に、ブラウザが対応する最適化の準備を事前に行えるようにするには、どのような変更方法を使用できるか。この種の最適化により、複雑な計算作業の一部を事前に準備できるため、ページの応答がより速く、より敏感になります。

重要な注意: will-change は、既存のパフォーマンスの問題に対処する際の最後の手段として使用することを目的としています。パフォーマンスの問題を予測するために使用しないでください。

translateZ() Hack を置き換えます

たとえば、CSS 3D 変換を使用して画面上の要素を移動する場合、要素そして、そのコンテンツは「レイヤー」に持ち上げられ、そこでページの残りの部分とは独立してレンダリングされ、後で合成することができます。これにより、コンテンツのレンダリングが分離され、要素の変換がフレーム間で変更される唯一のコンテンツである場合にページの残りの部分を再レンダリングする必要がなくなり、多くの場合、速度が大幅に向上します。

ただし、新しいレイヤーに要素を設定するのは比較的負荷の高い操作であり、変換アニメーションの開始が数分の 1 秒ほど遅れる可能性があります。

CSS 変換やその他の CSS 操作を使用する際のこの遅延を回避するために、私たちは長い間、translateZ (または、場合によっては translation3d) を使用して要素を独自のレイヤーにリフトしてきました。これにより、ハードウェア アクセラレーションによる操作がよりスムーズに、より高速に、不具合なく実行できるようになりました。 。ただし、「translateZ() (またはtranslate3d()) Hack」とも呼ばれるこのテクニックには代償が伴います。 Paul Lewis は、これについて 非常に役立つ投稿 を書いています。このテクニックを使用する場合は、ぜひチェックしてください。 will-change は、このハックや他のハックに頼ることなくアニメーションを最適化できるようにするためのものです。

(学習ビデオ共有: css ビデオ チュートリアル)

カンマ区切り

合格できます変更するプロパティ名を (カンマで区切って) 指定して、要素のスクロール位置、その内容、または 1 つ以上の CSS プロパティの値を変更することをブラウザに宣言します。ユーザー エージェントはほとんどのプロパティへの変更に対して特別な最適化を実行しないため、ほとんどのプロパティは指定しても効果がありません。ただし、まったく影響はありませんが、指定しても安全です。

要素の複数の値/側面を変更することが予想または計画されている場合は、値のカンマ区切りリストを指定できます。カンマで区切られた値のリストには、事前定義されたキーワードやプロパティ名を含めることができます。 (以下の「例」セクションを参照してください。)

スタッキング コンテキストとブロックを含むブロックの追加作成

property 要素にスタッキング コンテキストが作成されます。will-change でこの属性を指定すると、要素にスタッキング コンテキストが確実に作成されます。たとえば、不透明度を 1 以外の値に設定すると、要素にスタッキング コンテキストが作成されます。したがって、will-change: opacity を設定すると、opacity が 1 のままであっても、スタッキング コンテキストも作成されます。

同様に、will-change で属性を指定すると、属性の非初期値によって固定位置要素の包含ブロックが生成される場合、要素は固定位置要素の包含ブロックを生成する必要があります。位置要素。

will-change 属性は、前述のスタッキング コンテキストと包含ブロックの作成以外に、指定する要素に直接的な影響はありません。これは、ユーザー エージェントへのレンダリング ヒントにすぎず、ユーザー エージェントでの使用を可能にします。特定の種類のセットアップでは、変更が実際に開始される前に、コストがかかる可能性のある最適化をセットアップします。

注意して使用してください

とはいえ、このプロパティは注意して使用する必要があることを理解しておくことが重要です。ブラウザーが異なれば、will-change からの情報をさまざまな方法で使用できます。また、単一のブラウザーでも、さまざまな時点でさまざまな方法で情報を使用する可能性があります。過度に使用すると、ステートメントが完全に無視される可能性があります。たとえば、要素に will-change がある場合、要素を独自の「GPU レイヤー」にプロモートするブラウザーです。ただし、要素の宣言が多すぎる場合、ブラウザーは GPU メモリの不足を避けるために宣言を無視します。

さらに、要素が既知であるか、近い将来 (たとえば、数分の 1 秒以内に) 変更されることが予想される場合を除き、will-change は使用しないでください。必要がなくなったら設定を解除する必要があります。

実際に変更される要素で実際に変更するプロパティに will-change を設定します。停止したら取り外します。 - タブ・アトキンス・ジュニア (仕様編集者)

今後の変更に対するブラウザによる最適化は多くの場合費用がかかり、前述したように多くのマシン リソースを消費します。ブラウザの通常の最適化動作では、これらの最適化を削除し、できるだけ早く通常の動作に戻ります。ただし、will-change はこの動作をオーバーライドし、ブラウザーがそれ以外の場合よりも最適化を長く維持します。

したがって、ブラウザーが宣言されたリソースの最適化を再開できるように、要素の変更が完了した後は必ず will-change を削除することを忘れないでください。

JavaScript を使用して設定を変更する

JavaScript を使用して設定を変更すると、よりきめ細かい制御が可能になり、より多くのブラウザで変更に対応できるようになりますまた、アニメーション イベントが終了した直後に設定を解除することもできます。 JavaScript を使用して、ブラウザーへの変更を宣言し、変更が完了するタイミングをリッスンして、変更が完了したら will-change を削除します。

たとえば、要素 (またはその祖先) がホバーされたときをリッスンし、mouseenter で will-change を設定できます。要素がアニメーション化されている場合は、DOM イベント animeEnd を使用してアニメーションが終了するタイミングをリッスンし、animationEnd が起動された後に will-change を削除できます。

// Rough generic example
// Get the element that is going to be animated on click, for example
var el = document.getElementById('element');

// Set will-change when the element is hovered
el.addEventListener('mouseenter', hintBrowser);
el.addEventListener('animationEnd', removeHint);

function hintBrowser() {
	// The optimizable properties that are going to change
	// in the animation's keyframes block
	this.style.willChange = 'transform, opacity';
}

function removeHint() {
	this.style.willChange = 'auto';
}
ログイン後にコピー

css で will-change を設定する方が良いです。

本当にスタイルシートで will-change を設定したい場合は、要素を最適化する必要があります。ホバー時に変更を加えたい場合は、ホバー時に発生させたい変更を最適化するようにブラウザに指示するために、次の操作を行うことができます:

.el:hover {
    will-change: transform;
    transform: rotate()...;
}
ログイン後にコピー

これは特に間違っているわけではありませんが、特に便利というわけでもありません。変更の準備をして必要な最適化を行うための時間を与えるために、変更が発生したときではなく、変更が実際に発生する少し前にブラウザに意図を宣言する必要があります。したがって、次のようなシナリオでは、これを行うことができます:

.el {
    will-change: transform;
}

.el:hover {
    transform: rotate()...;
}
ログイン後にコピー

または、ホバー イベントが要素自体に到達するまでに時間がかかるため、要素のコンテナのホバー時に will-change を設定することもできます。 、次にブラウザ この時間を要素自体への変更の準備に利用できます:

.container:hover .el {
    will-change: transform;
}

.el:hover {
    transform: rotate()...;
}
ログイン後にコピー

要約すると、will-change は注意して使用することを忘れないでください。使いすぎず、設定のみを行ってください。要素が変更されようとしていることがわかっている場合は、変更が完了したら必ず設定をキャンセルしてください。

公式文法

  • ステートメント:
will-change: auto | <animateable-feature>#
ログイン後にコピー

where

<animateable-feature> = scroll-position | contents | <custom-ident>
ログイン後にコピー

タグ (#) は、カンマで区切って複数の値を指定できることを示します。

  • 初期値: auto
  • 適用対象: すべての要素
  • アニメーション: no

Value (値)

auto

これはデフォルト値です。特別な意図を示すものではありません。ブラウザーには変更が通知されないため、将来の変更に対応するための最適化は実行されません。

scroll-position

作成者が近い将来、要素のスクロール位置をアニメーション化または変更することを希望していることを示します。ブラウザは、この変更に合わせて事前に適切に最適化されます。

たとえば、ブラウザは通常、スクロール可能な要素の「スクロール ウィンドウ」内のコンテンツと、すでにウィンドウを通過したコンテンツのみをレンダリングするため、レンダリングをスキップすることで節約される時間とメモリと、レンダリングの必要性のバランスをとります。スクロールすると見栄えが良くなります。ブラウザーは、この値を信号として使用して、レンダリングされたスクロール ウィンドウの周囲のコンテンツ範囲を拡大し、より長い/より高速なスクロールをスムーズに実行できるようにすることがあります。

contents

作成者が近い将来アニメーション化または要素のコンテンツを変更したいものを示します。ブラウザは、この変更に合わせて事前に適切に最適化されます。

たとえば、ほとんどのものはそれほど頻繁に変更されないか、位置が変更されるだけであるため、ブラウザーは時間の経過とともに要素のレンダリングを「キャッシュ」することがよくあります。ただし、要素のコンテンツが定期的に変更される場合、このキャッシュの生成と維持は時間の無駄です。ブラウザーは、この値を信号として受け取り、要素のキャッシュをあまり積極的に行わないか、まったくキャッシュを回避して要素を最初から継続的に再レン​​ダリングすることもあります。

<カスタム ID> (<ユーザー ID>)

<カスタム-ident> 値 (詳細については、<custom-ident> エントリを参照してください)。作成者が近い将来、要素上の指定された名前のプロパティをアニメーション化または変更することを希望していることを示します。

たとえば、ブラウザは多くの場合、非初期値 transform 属性セットを持つ要素を他の要素から区別し、それらを独自の「GPU レイヤー」にレンダリングするか、他のメカニズムを使用して、より簡単にアクセスできるようにします。すぐに変更を加えます。ブラウザは、古いレイヤーと新しいレイヤーの再レンダリングに伴う遅延を避けるために、変換を開始する直前に要素を独自のレイヤーに昇格させる必要があるという信号として transform の値を受け取る場合があります。

除了通常从 <custom-ident> 中排除的关键字之外,<custom-ident> 值不能是以下关键字之一:will-changenoneallautoscroll-positioncontents

请注意,大多数属性在指定时将不起作用,因为用户代理不会对大多数属性的更改执行任何特殊优化。不过,指定它们仍然是安全的,虽然它根本没有效果。

注:感觉虽然命名为『自定义标志』, 其实主要碰到的还是 css 预定义好的标志,譬如 transform、opacity

例子

下面告诉浏览器期望元素的变换属性发生变化,以便提前进行适当的优化。

.el {
    will-change: transform;
}
ログイン後にコピー

上面的 will-change 声明应该通过 JavaScript 添加,然后在更改结束后删除或取消设置 (will-change: auto)。

以下所有的都是可能且有效的 will-change 值:

will-change: contents;
will-change: scroll-position;
will-change: opacity;/* multiple comma-separated values */will-change: contents, transform;
will-change: scroll-position, opacity;
ログイン後にコピー

使用小结

想使用好 will-change 并不是太容易,以下使用忠告摘录于官方文档,可见真是太难了。

  • 不要将 will-change 应用到太多元素上: 浏览器已经尽力尝试去优化一切可以优化的东西了。有一些更强力的优化,如果与 will-change 结合在一起的话,有可能会消耗很多机器资源,如果过度使用的话,可能导致页面响应缓慢或者消耗非常多的资源。

  • 有节制地使用: 通常,当元素恢复到初始状态时,浏览器会丢弃掉之前做的优化工作。但是如果直接在样式表中显式声明了 will-change 属性,则表示目标元素可能会经常变化,浏览器会将优化工作保存得比之前更久。所以最佳实践是当元素变化之前和之后通过脚本来切换 will-change 的值。

  • 不要过早应用 will-change 优化: 如果你的页面在性能方面没什么问题,则不要添加 will-change 属性来榨取一丁点的速度。 will-change 的设计初衷是作为最后的优化手段,用来尝试解决现有的性能问题。它不应该被用来预防性能问题。过度使用 will-change 会导致大量的内存占用,并会导致更复杂的渲染过程,因为浏览器会试图准备可能存在的变化过程。这会导致更严重的性能问题。

  • 给它足够的工作时间准备,不要过迟应用: 这个属性是用来让页面开发者告知浏览器哪些属性可能会变化的。然后浏览器可以选择在变化发生前提前去做一些优化工作。所以给浏览器一点时间去真正做这些优化工作是非常重要的。使用时需要尝试去找到一些方法提前一定时间获知元素可能发生的变化,然后为它加上 will-change 属性。

更多编程相关知识,请访问:编程视频!!

以上がCSS の will-change 属性について詳しく見るの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
css
ソース:juejin.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート