記事のディレクトリ
この記事では、いくつかのCSSパフォーマンス最適化スキームを紹介します。
最初の画面の1つのインラインキーCSS
レンダリングのおおよそのプロセス:
- HTMLリソースをロードする
- HTMLを解析する
- CSSリソースの読み込みとDOMツリーの構築を同時に行う
- CSSの解析とDOMツリーのレンダリングを同時に行う
CSSファイルが大きすぎると、手順3のままになります。インターネットの速度が遅い場合、Webサイトを開くときにスタイルがないことがよくあります。
したがって、最初にCSSの一部(最初の画面で使用されるCSS)をロードする必要があり、優先度の低い他のCSSは非同期でロードされます。
スクロールせずに見える範囲のコンテンツをHTMLにレンダリングするために必要な主要なCSSをインライン化すると、CSSをより迅速にダウンロードできます。HTMLのダウンロードが完了した後にレンダリングでき、ページのレンダリング時間が短縮されるため、最初の画面のレンダリング時間が短縮されます。
残りのCSSは外部CSSファイルを使用し、HTMLドキュメントのダウンロード後にダウンロードします。これにより、キャッシュが有効になりますが、非同期でロードされることに加えて。
短所:インライン化後のCSSはキャッシュされず、毎回再ダウンロードされます。
次に、CSSを非同期でロードします
CSSはレンダリングをブロックします。ブラウザは、CSSファイルの要求、ダウンロード、および解析が完了するまで、処理されたコンテンツをレンダリングしません。必要なCSSがロードされる前にブラウザがページのレンダリングを開始したくないため、このブロックが必要になる場合があります。次に、最初の画面の主要なCSSがインライン化された後、残りのCSSコンテンツのブロックレンダリングは不要であり、外部CSSを使用して非同期でロードできます。
非同期でロードするいくつかの方法
1.jsは、スタイルシートのリンク要素を動的に作成し、それをDOMに挿入します。
// 创建link标签
const myCSS = document.createElement( "link" );
myCSS.rel = "stylesheet";
myCSS.href = "mystyles.css";
// 插入到header的最后位置
document.head.insertBefore( myCSS, document.head.childNodes[ document.head.childNodes.length - 1 ].nextSibling );
2.メディア属性を設定します
link要素のmedia属性を、media = "print"などのユーザーのブラウザと一致しないメディアタイプ(またはメディアクエリ)に設定するか、完全に存在しないタイプmedia = "noexist"に設定します。ブラウザの場合、スタイルシートが現在のメディアタイプに適していない場合、その優先度は低くなり、ページのレンダリングをブロックせずにダウンロードされます。
<link rel="stylesheet" href="mystyles.css" media="noexist" onload="this.media='all'">
もちろん、これはCSSの非同期ロードを実装するためだけのものです。ブラウザがCSSの解析を開始できるように、ファイルのロード後にメディアの値をscreenまたはallに設定することを忘れないでください。
3.rel属性を設定します
rel属性を使用してリンク要素を代替スタイルシートとしてマークすることで、ブラウザーによる非同期ロードを実現することもできます。また、ロードが完了した後、relを元に戻すことを忘れないでください。
<link rel="alternate stylesheet" href="mystyles.css" onload="this.rel='stylesheet'">
4. rel =“ preload”
<link rel="preload" href="mystyles.css" as="style" onload="this.rel='stylesheet'">
必要に応じて注意してください。as属性または間違ったas属性を無視すると、プリロードはXHRリクエストと等しくなります。ブラウザはロードされているコンテンツを認識しないため、そのようなリソースをロードする優先度は非常に低くなります。
3、ファイル圧縮
ファイルのサイズは、ブラウザの読み込み速度に直接影響します。現在のビルドのwebpack、gulp / grunt、rollupなどもCSS圧縮をサポートしています。圧縮ファイルを大幅に削減できるため、ブラウザの読み込み時間を大幅に短縮できます。
第四に、役に立たないCSSを削除します
ファイル圧縮はファイルサイズを減らすことができますが、cssファイル圧縮は通常、無駄なスペースを削除するだけであり、cssファイルの圧縮率を制限します。それでも圧縮ファイルが予想サイズを超える場合は、コード内の役に立たないcssを見つけて削除してみてください。
通常の状況では、2種類の役に立たないCSSコードがあります。
- さまざまな要素やその他の状況でコードが重複している、
- ページ全体に効果的なCSSコードはありません
css継承メカニズムの巧妙な使用。親ノードが定義されている場合、子ノードを定義する必要はありません。
5、セレクターを選択的に使用する
CSSセレクターのマッチングは、右から左に実行されます。この戦略により、異なるタイプのセレクター間でパフォーマンスに違いが生じます。
CSS内のより多くのセレクターは一致しないため、パフォーマンスの問題を検討する際に考慮する必要があるのは、セレクターが一致しない場合に効率を向上させる方法です。右から左へのマッチングはこの目的のためです。
#abcと比較すると、明らかに#a .bcを使用する場合、ブラウザーはレンダーツリーの生成に時間がかかります。後者はDOM内のすべてのc要素を検索し、次に.bではない祖先要素を除外し、最後に#aではない.bの祖先を除外する必要があるためです。ネストのレベルが高いほど、時間がかかります。
- ネストされすぎたり、複雑すぎたりするセレクターは使用しないでください。
- ワイルドカードと属性セレクターは効率が最も低く、ほとんどの要素に一致する必要があるため、できるだけ使用しないでください。
- h3#markdown-contentなどの要素タグを装飾するためにクラスセレクターとIDセレクターを使用しないでください
(IDは元々一意であり、大きなアクセス許可値を持っています。ネストはパフォーマンスの無駄です。)
第六に、高価な属性の使用を減らす
ブラウザが画面を描画するとき、ブラウザによって操作または計算される必要があるすべてのプロパティは比較的高価です。ページが再描画されると、ブラウザのレンダリングパフォーマンスが低下します。box-shadow / border-radius / filter / transparency /:nth-childなどの高価な属性の使用を最小限に抑えます。
7.再配置と再描画を最適化します
1.再配置を減らします
再配置すると、ブラウザはドキュメント全体を再計算し、レンダリングツリーを再構築します。これにより、ブラウザのレンダリング速度が低下します。
再配置を引き起こす操作:
- 表示されているDOM要素を追加または削除します
- 要素の位置の変更
- 要素サイズの変更
- 要素の内容が変更されます(例:テキストが異なるサイズの別の画像に置き換えられます)
- ページレンダリングの初期化(これは避けられません)
- ブラウザのウィンドウサイズが変更されました
- CSS疑似クラスのアクティブ化
一般的な再配置要素:
- サイズに関連する幅、高さ、パディング、マージン、境界線の幅、境界線、最小の高さ
- レイアウト関連の表示、上、位置、フロート、左、右、下
- フォント関連のfont-size、text-align、font-weight、font-family、line-height、white-space、vertical-align
- 関連するオーバーフロー、overflow-x、overflow-yを非表示にする
ページ上のほとんどのリフローを回避するには、次の手順を使用します。
- 絶対位置を使用してアニメーション要素をページに配置し、ドキュメントフローからそれらを取り出します
- 要素を動かしてみましょう。展開すると、一時的にページの一部をカバーします。しかし、これはページの小さな領域の再描画プロセスにすぎず、ページのコンテンツのほとんどを再配置して再描画することはありません。
- アニメーションが終了すると、位置が復元されるため、ドキュメントの他の要素は1回だけ下に移動します。
- Flexを使用する場合、インラインブロックおよびフロートを使用する場合よりも再配置が高速であるため、レイアウトでFlexを優先できます。
2.不必要な再描画を避けます
当ウェブサイトのご利用中は、再描画は避けられません。ただし、ブラウザはこれを最適化しており、複数のリフロー操作と再描画操作を1つの実行に結合します。ただし、ページのスクロール時にトリガーされるホバーイベントなど、不要な再描画を回避する必要があります。また、スクロール時にホバーイベントを無効にして、スクロール時にページがスムーズになるようにすることができます。
要素の外観(色、背景、可視性など)が変更されると、再描画がトリガーされます。
8.要素とその内容をドキュメントツリーの他の部分から可能な限り独立させます
contains属性を使用すると、特定のDOM要素とその子要素を指定して、DOMツリー構造全体から独立させることができます。目的は、ブラウザが、毎回ページ全体をターゲットにすることなく、要素の一部のみを再描画および再配置できるようにすることです。つまり、ブラウザが、ページ全体ではなくDOMの限られた領域について、レイアウト、スタイル、ペイント、サイズ、またはそれらの任意の組み合わせを再計算できるようにします。
実際の使用では、次の5つの値のいずれかを設定することで、要素がドキュメントツリーからどのように独立しているかを指定できます。
- layout:この値は、要素の内部レイアウトが外部の影響を受けず、要素とそのコンテンツが上位レベルに影響を与えないことを意味します。コンテナの子孫は、コンテナの外部の要素のレイアウトを次のように引き起こしてはなりません。変更、またはその逆
- paint:この値は、要素の子を要素のスコープ外に表示できず、要素にコンテンツオーバーフローがないことを示します(または、オーバーフローしても表示されません)。コンテナのコンテンツは表示されます。コンテナのサイズを超えて描画されることはありません。コンテナがぼやけていると、コンテンツはまったく描画されません。
- size:この値は、要素ボックスのサイズがその内容に依存しないことを示します。つまり、要素ボックスのサイズを計算するときにその子要素は無視されます。その内容が変更された場合、コンテナは位置を引き起こしてはなりません。移動するページ
- content:この値はcontainの省略形です:layout paint
- strict:この値はcontainの省略形です:layout paint size
9、@ importの使用は避けてください
@importを使用してcssを導入すると、ブラウザーの並列ダウンロードに影響します。@importで参照されるcssファイルは、それを参照するcssファイルがダウンロードされた場合にのみダウンロードされます。解析後、ブラウザはダウンロードする別のcssがあることを認識し、ダウンロードし、ダウンロード後に解析を開始して、レンダリングツリーを構築します。 、など外部cssファイルで@importを使用してブラウザを並行してダウンロードできないようにする一連の操作により、ページの読み込み時に追加の遅延が発生します。
リンクタグを使用することをお勧めします。
10、GPUレンダリングアニメーションをオンにします
ブラウザは、リフローを適切にトリガーしない(したがって、描画を引き起こす)CSSアニメーションおよびアニメーションプロパティを処理するように最適化されています。
パフォーマンスを向上させるために、アニメーション化されたノードをメインスレッドからGPUに移動できます。コンポジションの原因となるプロパティには、3D変換(変換:translateZ()、rotate3d()など)、アニメーション、変換と不透明度、位置:固定、変更、フィルターが含まれます。たとえば、、などの一部の要素も、それぞれのレイヤーに配置されています。要素をレイヤーにプロモートする場合(合成とも呼ばれます)、アニメーション遷移プロパティはGPUで実行されるため、特にモバイルデバイスでのパフォーマンスが向上します。
11、cssファイルをマージします
ページが10個のcssファイルをロードする場合、各ファイルは1kであるため、100k個のcssファイルをロードするよりも遅くなります。
参照:https://blog.csdn.net/weixin_38015898/article/details/107215259
その他の最適化ソリューションについては、https://juejin.cn/post/6942661408181977118を参照してください。
この記事へのリンク:https://blog.csdn.net/qq_39903567/article/details/115262201