ホームページ >ウェブフロントエンド >htmlチュートリアル >[Webアニメーション] CSS3 3D惑星運動とブラウザレンダリング原理_html/css_WEB-ITnose
前回の記事:【CSS3 Advanced】かっこいい3D回転パース の続きです。
最近Webアニメーションにハマったので、学習過程を記録して皆さんと共有したいと思います。
CSS3 3D 惑星運動のデモ ページをクリックしてください: デモ。 (Chrome を使用して開くことをお勧めします)
この記事の完全なコードとその他の CSS3 効果は、私の Github で見ることができます。星を付けていただければ幸いです。
まあ、デモを開けなかったり、ページがめちゃくちゃになっている人もいるかもしれないので、ここにいくつかのレンダリングを示します: (写真は少し大きいので、しばらく辛抱してお待ちください)
CSS3 3D 惑星運動レンダリング
ランダムなスクリーンショット 1 枚の写真:
CSS3 3D の魅力を体験するには、デモ ページをクリックすることを強くお勧めします。
それでは、この CSS3 3D 惑星運動アニメーションの制作プロセスについては詳しく説明しません。この記事の焦点は Web アニメーションの導入とパフォーマンスの最適化です。 CSS3 3D の詳細については、以前のブログ「[CSS3 Advanced] クールな 3D 回転パース」を参照してください。シンプルなアイデア:
1. 前の記事で作成した 3D 写真の壁をプロトタイプとして使用し、それを修正します。 CSS3 の 3D 形状。次に、制作プロセス中に Sass を使用して CSS を作成すると、CSS アニメーションを作成する面倒なプロセスの多くを削減できます。
3. デモでは、このイベントが削除されると、JavaScript が使用されます。惑星の動きのアニメーション自体は純粋な CSS で実現されています。
この記事では、パフォーマンスの最適化の観点から、ブラウザのレンダリングと表示、ブラウザの再描画とリフロー、アニメーションのパフォーマンス検出の最適化などの原理について説明します。
ブラウザのレンダリングと表示の原理 そして、Web アニメーションへの影響
サブタイトルは少し大きいですが、ブラウザごとにコア (レンダリング エンジン) が異なることはわかっています。たとえば、最も主流の Chrome ブラウザのコアは次のとおりです。 Blink カーネル (Chrome (バージョン 28 以降)、Opera (バージョン 15 以降)、および Yandex ブラウザーで使用されます)、Firefox は Gecko、IE は Trident です。ブラウザー カーネルは、Web ページの構文の解釈とレンダリング (表示) を担当します。 Web ページの動作原理は、さまざまなブラウザー カーネルで完全に一致しているわけではありません。
実際、以下で主に説明するのは、Chrome ブラウザーでのレンダリング原理です。 Chrome カーネルのレンダリングについては検証可能な情報がたくさんあるため、他のカーネルを使用したブラウザについては結論を導き出すことは敢えてしません。そのため、以下の説明はデフォルトで Chrome ブラウザに関するものです。
まず最初に結論をいくつか挙げておきます:
transform API の代わりにtransform3d API を使用し、GPU アクセラレーションの開始を強制します
ここでは GPU アクセラレーションについて説明しますが、なぜ GPU で 3D 変換をアクセラレートできるのでしょうか?これらはすべて、ブラウザーの基本的なレンダリングから開始する必要があります。ブラウザーでの Web ページのレンダリングと表示のプロセスは決まり文句であり、面接では次のように分けられます。
1. HTML の解析 (HTML パーサー)。
2. DOM ツリーを構築する (DOM ツリー) 3. レンダー ツリーを構築する (レンダー ツリー)
非常に古典的な画像を見つけました:
このレンダリング プロセスは、基本的な知識については、以下に進みます。
ページがロードされて解析されると、ブラウザーで非常によく知られた構造である DOM (Document Object Model) が表されます。ブラウザがページをレンダリングするとき、開発者には公開されない多くの中間表現が使用されます。その最も重要な構造はレイヤーです。
この記事の焦点はこのレイヤーです:
Chrome には、RenderLayer (DOM サブツリーを担当)、GraphicsLayer (RenderLayer のサブツリーを担当) というさまざまな種類のレイヤーがあります。次に、GraphicsLayer レイヤーについて説明します。
GraphicsLayer レイヤーはテクスチャとして GPU にアップロードされます。
ここでのテクスチャは非常に重要です。それで、
テクスチャとは何ですか?ここでのテクスチャとは GPU 用語を指します。メイン メモリ (RAM など) から画像メモリ (GPU の VRAM など) に移動されるビットマップ イメージと考えてください。 GPU に移動したら、それをメッシュ ジオメトリに合わせ、Chrome でテクスチャを使用して、ページ コンテンツの大部分を GPU から取得できます。非常に単純な長方形のグリッドにテクスチャを適用することで、さまざまな位置や変換を簡単に一致させることができます。これが 3D CSS の仕組みです。
理解するのは難しいですが、Chrome では、GraphicsLayer (前述のレイヤーの概念) を見ることができます。開発者ツールで次の選択を行って、レイヤー境界線の表示オプションを表示します:
非常に単純なページでは、以下に示すように、このページにはレイヤーが 1 つだけあることがわかります。青いグリッドはタイルを表しており、(レイヤーではなく) レイヤーの単位として考えることができます。Chrome では、要素自体のレイヤーの
を作成します。上のページは非常に単純で、レイヤーは生成されませんが、非常に複雑なページでは、たとえば、要素に 3D CSS プロパティを設定して要素を変換すると、要素に独自のレイヤーがあるときにどのように見えるかがわかります。のように。
このビューでレイヤーの輪郭を示すオレンジ色の境界線に注目してください:
レイヤーの作成はいつトリガーされますか?
上の図の黄色の枠で囲まれたレイヤーは、Web アニメーションにとって非常に重要です。通常、Chrome はレイヤーのコンテンツをテクスチャとして GPU にアップロードします。 。コンテンツが変更されない場合は、レイヤーを再ペイントする必要はありません。
これの重要な点は、再描画に費やした時間を JavaScript の実行など、他のことに使用できることです。描画に時間がかかると、アニメーションの失敗や遅延も発生します。では、要素はいつレイヤーの作成をトリガーするのでしょうか?現時点では、次の条件のいずれかが満たされる場合にレイヤーが作成されます:
3D またはパースペクティブ変換 (perspective、transform) CSS プロパティ
高速ビデオ デコードを使用する 39000f942b2545a5315c57fa3276f220 要素
静的 Web ページの場合、レイヤーは最初に描画された後は変更されませんが、Web アニメーションの場合、ページの DOM 要素は常に変更されます。レイヤーのコンテンツが変更された場合、はい、変換プロセス中に変更があった場合、レイヤーは再描画されます。 強力な Chrome 開発者ツールは、アニメーション ページの実行中にどのコンテンツが再描画されたかを確認できるツールを提供します:
Chrome の古いバージョンでは、ペイント四角形を表示するオプションがあり、これを表示できます。ページのどのレイヤーが再描画されたかは、赤い枠線でマークされます。
しかし、Chrome の新しいバージョンではこのオプションが削除されたようです。現在のオプションはペイント フラッシュを有効にすることであり、これは Web サイトの動的変換を識別し、緑色の境界線でマークされています。
上の図を見ると、ページ上にいくつかの緑色のボックスがあり、再描画が発生したことを示していることがわかります。 Chrome は常にレイヤー全体を再描画するわけではなく、DOM の無効な部分をインテリジェントに再描画しようとすることに注意してください。
論理的には、ページ上で非常に多くのアニメーションが発生しているため、再描画は非常に頻繁に行われるはずですが、私の個人的な理解では、アニメーション全体の 1 つは GPU の最適化であると考えられます。ページにレイヤーが 1 つしかない場合、変形にはtransformが使用され、必然的にページの再描画が必要になります。ただし、レイヤー化(GraphicsLayer)技術を使用すると、上記の状況に応じた要素がそれぞれレイヤーを作成され、要素によって作成されたレイヤーは回転などの変換を使用します。このとき、このレイヤーの回転変換は他のレイヤーに影響を与えないため、このレイヤーを必ずしも再描画する必要はありません。 (個人的な意見ですので、ご了承ください。)
Web アニメーションのパフォーマンスを最適化するには、レイヤーの再描画を理解することが重要です。
無効化と強制再描画の原因は何ですか?境界失敗につながる状況は数多くあるため、この質問に網羅的に答えるのは困難です。最も一般的な状況は、CSS スタイルを操作して DOM を変更するか、リフローを引き起こすことです。
再ペイントとリフローの根本原因を見つける最善の方法は、開発者ツールのタイムラインとペイント フラッシュ ツールの有効化を使用して、再ペイント/リフローの直前に DOM が変更された場所を見つけてみることです。
概要では、ブラウザは DOM 要素から最終的なアニメーションまでどのように表示するのでしょうか? Web アニメーションのコストの大部分はレイヤーの再描画にあり、レイヤーベースの複合モデルはレンダリング パフォーマンスに大きな影響を与えます。描画が必要ない場合、複合操作のオーバーヘッドは無視できるほどであるため、レンダリングのパフォーマンスの問題をデバッグしようとするときの最初の目標は、レイヤーの再描画を回避することです。これにより、アニメーションのパフォーマンスを最適化する方向が決まり、要素の再描画とリフローが削減されます。 リフローと再ペイント ここでは、まず、再描画とリフローという 2 つの概念を区別する必要があります。 リフロー 要素のサイズ、レイアウト、非表示などの変更により、レンダー ツリーの一部 (またはすべて) を再構築する必要がある場合。これをリフロー、つまり再レイアウトといいます。 すべてのページを少なくとも 1 回リフローする必要があります。これは、ページが初めてロードされるときです。リフロー中、ブラウザはレンダリング ツリーの影響を受けた部分を無効にし、リフローが完了した後、影響を受けた部分を画面に再描画します。このプロセスは再描画と呼ばれます。 Repaint レンダー ツリー内の一部の要素で属性を更新する必要がある場合、これらの属性は要素の外観とスタイルにのみ影響し、背景色などのレイアウトには影響しません。それを再描画といいます。 リフローは間違いなく再描画を引き起こしますが、再描画は必ずしもリフローを引き起こすわけではないことに注意してください。 明らかに、リフローのコストは大きくなります。簡単に言うと、要素の操作により要素のサイズや位置が変更されると、リフローが発生します。 リフローがトリガーされる場合: リフローと再描画を減らすことは、実際には意味します。レンダリング ツリーでの操作 (複数の DOM とスタイル変更のマージ) を減らし、一部のスタイル情報の要求を減らし、ブラウザーの最適化戦略を最大限に活用します。 キューをフラッシュ 実際、ブラウザ自体に最適化戦略があり、すべての Javascript 文が DOM をリフローして再描画するように操作すると、ブラウザはそれに耐えられなくなる可能性があります。したがって、多くのブラウザはこれらの操作を最適化するため、キューを維持し、キュー内の操作が特定の数または一定の時間間隔に達すると、リフローと再描画を引き起こすすべての操作をこのキューに入れます。フラッシュされ、バッチが処理されます。これにより、複数のリフローと再描画が 1 つのリフローと再描画に変わります。 offsetTop、offsetLeft、offsetWidth、offsetHeight // 下面这种方式将会导致回流reflow两次var newWidth = aDiv.offsetWidth + 10; // ReadaDiv.style.width = newWidth + 'px'; // Writevar newHeight = aDiv.offsetHeight + 10; // ReadaDiv.style.height = newHeight + 'px'; // Write// 下面这种方式更好,只会回流reflow一次var newWidth = aDiv.offsetWidth + 10; // Readvar newHeight = aDiv.offsetHeight + 10; // ReadaDiv.style.width = newWidth + 'px'; // WriteaDiv.style.height = newHeight + 'px'; // Write
display:none と Visibility:hidden
どちらもページ上のノードを非表示にすることができます。違いは
从性能的角度而言,即是回流与重绘的方面,
他们两者在优化中 visibility:hidden 会显得更好,因为我们不会因为它而去改变了文档中已经定义好的显示层次结构了。
对子元素的影响:
动画的性能检测及优化
耗性能样式
不同样式在消耗性能方面是不同的,譬如 box-shadow 从渲染角度来讲十分耗性能,原因就是与其他样式相比,它们的绘制代码执行时间过长。这就是说,如果一个耗性能严重的样式经常需要重绘,那么你就会遇到性能问题。其次你要知道,没有不变的事情,在今天性能很差的样式,可能明天就被优化,并且浏览器之间也存在差异。
因此关键在于,你要借助开发工具来分辨出性能瓶颈所在,然后设法减少浏览器的工作量。
好在 chrome 浏览器提供了许多强大的功能,让我们可以检测我们的动画性能,除了上面提到的,我们还可以通过勾选下面这个 show FPS meter 显示页面的 FPS 信息,以及 GPU 的使用率:
使用 will-change 提高页面滚动、动画等渲染性能
官方文档说,这是一个仍处于实验阶段的功能,所以在未来版本的浏览器中该功能的语法和行为可能随之改变。
使用方法示例:(具体每个取值的意义,去翻翻文档)
will-change: autowill-change: scroll-positionwill-change: contentswill-change: transform // Example of <custom-ident> will-change: opacity // Example of <custom-ident>will-change: left, top // Example of two <animateable-feature>will-change: unsetwill-change: initialwill-change: inherit// 示例.example{ will-change: transform;}
will-change 为 web 开发者提供了一种告知浏览器该元素会有哪些变化的方法,这样浏览器可以在元素属性真正发生变化之前提前做好对应的优化准备工作。 这种优化可以将一部分复杂的计算工作提前准备好,使页面的反应更为快速灵敏。
值得注意的是,用好这个属性并不是很容易:
使用 transform3d api 代替 transform api,强制开始 GPU 加速
GPU 能够加速 Web 动画,这个上文已经反复提到了。
3D 変換は、translate3D、scaleZ などの GPU アクセラレーションを有効にします。もちろん、私たちのページには 3D 変換がない可能性がありますが、GPU アクセラレーションを有効にできないという意味ではなく、3D 変換以外の変換でも使用できます。ページ、これは操作の一種と考えられます。実際には Z 軸の変更は必要ありませんが、ブラウザを騙すために宣言したふりをします。
参考:
レンダリング: 再描画、リフロー/再レイアウト、再スタイル
スクロールパフォーマンス
MDN--will-change
WebKitでレイアウトをトリガーする方法(しない)
ハイパフォーマンスアニメーション
Chrome での高速レンダリング
3D 回転球体を作成する CSS3
この記事はこれで終わりです。まだ質問や提案がある場合は、オリジナルの記事です。才能が浅いです 記事に何か間違いがあればお知らせください。
CSS3 3D 惑星運動のデモ ページをクリックしてください: デモ。 (Chrome を使用して開くことをお勧めします)
この記事の完全なコードとその他の CSS3 効果は、私の Github で見ることができます。星を付けていただければ幸いです。
この記事が役に立った場合は、「おすすめ」をクリックしてください。記事を書くのは簡単ではありません。