クリティカル パスの把握

クリティカル レンダリング パスとは、ウェブページがブラウザでのレンダリングを開始するまでのステップを指します。ブラウザでページをレンダリングするには、HTML ドキュメント自体と、そのドキュメントのレンダリングに必要なすべての重要なリソースが必要です。

HTML ドキュメントをブラウザに渡す方法については、以前の HTML のパフォーマンスに関する一般的な考慮事項のモジュールで説明しています。ただし、このモジュールでは、ページをレンダリングするために HTML ドキュメントをダウンロードした後のブラウザの動作について詳しく説明します。

ウェブは本質的に拡散されています。使用前にインストールされるネイティブ アプリとは異なり、ブラウザはページのレンダリングに必要なすべてのリソースを持つウェブサイトに依存できません。そのため、ブラウザはページを段階的にレンダリングすることを得意としています。通常、ネイティブ アプリにはインストール フェーズと実行フェーズがあります。しかし、ウェブページとウェブアプリの場合、この 2 つのフェーズの境界はあまり明確ではなく、ブラウザは特にこの点を念頭に置いて設計されています。

ブラウザは、ページをレンダリングするためのリソースを獲得すると、通常、レンダリングを開始します。したがって、レンダリングするタイミング、すなわち、タイミングが早すぎるか、

HTML があるだけで、CSS や JavaScript がない状態でブラウザができるだけ早くレンダリングすると、ページは一時的に破損しているように見え、最終的なレンダリングのために大きく変化します。これは、最初のレンダリングのためにブラウザがより多くのリソースを確保してユーザー エクスペリエンスを向上させるまで、最初に空白の画面を表示する場合よりもエクスペリエンスが低下します。

一方、ブラウザが順次レンダリングを行う代わりに、すべてのリソースが使用可能になるまで待機すると、ユーザーは長時間待機したままになります。かなり早い段階でページが使用可能であった場合は、不必要に待たされることがよくあります。

ブラウザは、明らかに不完全なエクスペリエンスにならないように、待機するリソースの最小数を認識している必要があります。一方、ブラウザでは、ユーザーにコンテンツを表示するまで、必要以上に長く待たないようにしてください。ブラウザが最初のレンダリングを行う前に実行する一連のステップを、クリティカル レンダリング パスといいます。

クリティカル レンダリング パスを把握することで、最初のページ レンダリングを必要以上にブロックすることがないようにすることで、ウェブのパフォーマンスを改善できます。ただし、最初のレンダリングに必要なリソースをクリティカル レンダリング パスから削除して、レンダリングが早すぎないようにすることも重要です。

(クリティカルな)レンダリング パス

レンダリング パスには次の手順が含まれます。

  • HTML からドキュメント オブジェクト モデル(DOM)を構築する。
  • CSS から CSS Object Model(CSSOM)を作成する
  • DOM または CSSOM を変更する JavaScript を適用する。
  • DOM と CSSOM からレンダリング ツリーを構築する
  • ページに対してスタイル操作とレイアウト操作を行って、どの要素がどこに収まるかを確認します。
  • メモリ内の要素のピクセルをペイントします。
  • ピクセルが重なっている場合は合成します。
  • 結果として得られるすべてのピクセルを物理的に画面に描画します。
前のリストで説明したレンダリング プロセスの図。

これらのすべてのステップが完了して初めて、ユーザーの画面にコンテンツが表示されます。

このレンダリング プロセスは複数回行われます。最初のレンダリングでこのプロセスが呼び出されますが、ページのレンダリングに影響するリソースが増えると、ブラウザはこのプロセス(またはその一部)を再実行して、ユーザーに表示される内容を更新します。クリティカル レンダリング パスでは、最初のレンダリングで前述したプロセスに重点を置き、そのプロセスに必要なクリティカル リソースに依存します。

クリティカル レンダリング パス上にあるリソース

ブラウザは、いくつかの重要なリソースのダウンロードを待ってから、最初のレンダリングを完了する必要があります。次のようなリソースが該当します。

  • HTML の一部。
  • <head> 要素内のレンダリングをブロックする CSS。
  • <head> 要素内のレンダリングをブロックする JavaScript。

重要なポイントは、ブラウザは HTML をストリーミング方式で処理することです。ブラウザはページの HTML の一部を取得するとすぐに処理を開始します。これにより、ブラウザはページの残りの部分の HTML を受け取る前に、多くの場合、ページをレンダリングすることを決定できます。

重要な点として、初回のレンダリングにおいて、ブラウザは通常、次の処理を待機しません

  • すべての HTML です。
  • フォント。
  • イメージ。
  • <head> 要素の外に配置された、レンダリングをブロックしない JavaScript(HTML の最後に配置された <script> 要素など)。
  • <head> 要素の外にレンダリングをブロックしない CSS、または現在のビューポートに適用されない media 属性の値を持つ CSS

多くの場合、フォントと画像は、後続のページの再レンダリングでブラウザによって入力されるコンテンツと見なされるため、最初のレンダリングを保留する必要はありません。ただし、最初のレンダリングでは、フォントを待機してテキストが非表示になるか、または画像が使用可能になるまで、空白の領域が残ることがあります。さらに悪いのは、特定の種類のコンテンツ(特に HTML で画像サイズが指定されていない場合)に十分なスペースが確保されていない場合、そのコンテンツが後で読み込まれるとページのレイアウトが変化する可能性があることです。ユーザー エクスペリエンスのこの側面は、Cumulative Layout Shift(CLS)指標で測定されます。

<head> 要素は、クリティカル レンダリング パスを処理するための鍵となります。そのため、次のセクションで詳しく説明します<head> 要素の内容の最適化は、ウェブ パフォーマンスの重要な要素です。とはいえ、今のところ、クリティカル レンダリング パスを理解するために必要なことは、<head> 要素にはページとそのリソースに関するメタデータが含まれ、ユーザーに表示される実際のコンテンツはないことだけです。表示コンテンツは、<head> 要素に続く <body> 要素内に含まれます。ブラウザがコンテンツをレンダリングするには、レンダリングするコンテンツと、レンダリング方法に関するメタデータの両方が必要です。

ただし、<head> 要素で参照されるすべてのリソースが最初のページ レンダリングに厳密に必要なわけではないため、ブラウザはリソースを待機するだけです。クリティカル レンダリング パスにあるリソースを特定するには、レンダリング ブロックとパーサー ブロックの CSS と JavaScript について理解する必要があります。

レンダリング ブロック リソース

一部のリソースは非常に重要とみなされるため、ブラウザはそれらを処理するまでページ レンダリングを一時停止します。CSS はデフォルトでこのカテゴリに分類されます。

ブラウザは、<style> 要素内のインライン CSS であるか、<link rel=stylesheet href="..."> 要素で指定された外部参照リソースであるかにかかわらず、CSS を認識すると、その CSS のダウンロードと処理が完了するまでコンテンツのレンダリングを回避します。

リソースがレンダリングをブロックしたからといって、ブラウザによる他の処理が停止するとは限りません。ブラウザは可能な限り効率的であるため、CSS リソースをダウンロードする必要があると判断した場合、ブラウザは CSS リソースをリクエストしてレンダリングを一時停止しますが、HTML の残りの部分の処理は継続し、その間に行うべき他の作業を探します。

CSS などのレンダリングをブロックするリソース。検出時にページのすべてのレンダリングをブロックするために使用されます。つまり、一部の CSS がレンダリングをブロックしているかどうかは、ブラウザでその CSS が検出されたかどうかによって決まります。一部のブラウザ(最初は Firefox、現在は Chrome)では、レンダリングをブロックするリソースより下位のコンテンツのレンダリングのみがブロックされます。つまり、クリティカル レンダリング ブロック パスでは、ページ全体のレンダリングを効果的にブロックするため、通常は <head> 内のレンダリング ブロック リソースを使用します。

最近のイノベーションとして、Chrome 105 に追加された blocking=render 属性があります。これにより、<link><script><style> の各要素を、処理が完了するまでは明示的にレンダリングをブロックするようにマークできますが、その間もパーサーはドキュメントの処理を続行できます。

パーサー ブロック リソース

パーサー ブロック リソースとは、ブラウザが HTML の解析を続行して他の作業を探すのを妨げるリソースです。JavaScript は実行時に DOM または CSSOM を変更できるため、デフォルトでは、JavaScript がパーサーをブロックします(非同期または遅延と明確にマークされている場合を除く)。したがって、リクエストされた JavaScript がページの HTML に及ぼす影響をすべて把握するまで、ブラウザは他のリソースの処理を続行できません。したがって、同期 JavaScript はパーサーをブロックします。

パーサー ブロック リソースは、実質的にもレンダリング ブロックです。パーサーは、処理が完了するまで、解析ブロック リソースを超えて処理を続行できないため、それ以降のコンテンツにアクセスしてレンダリングすることはできません。ブラウザは、それまでに受け取った HTML をレンダリングできます。ただし、クリティカル レンダリング パスに関しては、<head> にパーサー ブロック リソースがあると、すべてのページ コンテンツのレンダリングが実質的にブロックされます。

パーサーをブロックすると、単にレンダリングをブロックするだけでなく、パフォーマンス コストが大幅に増える可能性があります。このためブラウザでは、プライマリ HTML パーサーがブロックされている間に、プリロード スキャナと呼ばれるセカンダリ HTML パーサーを使用して今後のリソースをダウンロードすることで、このコストを削減しようとします。実際に HTML を解析するほど効果はありませんが、少なくともブラウザのネットワーク機能がブロックされたパーサーより先を行くことが可能になるため、今後再びブロックされる可能性は低くなります。

ブロックしているリソースの特定

多くのパフォーマンス監査ツールは、レンダリング リソースとパーサー ブロック リソースを識別します。WebPageTest では、レンダリングをブロックするリソースに、リソースの URL の左側にオレンジ色の円が表示されます。

WebPageTest で生成されたネットワーク ウォーターフォール図のスクリーンショット。パーサー ブロック リソースは、リソースの URL の左にオレンジ色の円で示され、レンダリング開始時間は濃い緑色の線で示されます。

レンダリングを開始する前に、レンダリング ブロック リソースをすべてダウンロードして処理する必要があります。これは、ウォーターフォールの濃い緑色の線で示されます。

Lighthouse では、レンダリング ブロック リソースも、より細かな方法でハイライト表示されます。これは、そのリソースが実際にページのレンダリングを遅延させる場合に限られます。これにより、レンダリング ブロックを最小限に抑える誤検出の回避に役立ちます。Lighthouse で前の WebPageTest の図と同じページ URL を実行すると、いずれかのスタイルシートがレンダリングをブロックするリソースとして識別されます。

Lighthouse によるレンダリング ブロック リソースの排除状況を示すスクリーンショット。監査では、レンダリングをブロックしたリソースと、レンダリングをブロックした時間が表示されます。

クリティカル レンダリング パスの最適化

クリティカル レンダリング パスを最適化するには、前のモジュールで説明した HTML 受信時間(最初のバイトまでの時間(TTFB)指標で表される)を短縮し、レンダリング ブロック リソースの影響を軽減する必要があります。これらのコンセプトについては、次のモジュールで説明します。

クリティカル コンテンツ レンダリング パス

長い間、クリティカル レンダリング パスは最初のレンダリングに関係していました。しかし、ウェブ パフォーマンスに関するユーザー中心の指標が増えてきたため、クリティカル レンダリング パスのエンドポイントをファースト ペイントにするか、その後に続くコンテンツの多いペイントの一つにするかという疑問があります。

別の見解としては、コンテンツフル レンダリング パス(またはキーパス(一般的には「キーパス」)の一部として)Largest Contentful Paint(LCP)または First Contentful Paint(FCP)までにかかる時間に注目します。この場合、クリティカル レンダリング パスの一般的な定義のように、必ずしもブロックとは限らないが、Contentful Paint のレンダリングに必要なリソースを含める必要があります。

「重大」と定義した内容の正確な定義に関係なく、最初のレンダリングと主要なコンテンツを阻害している要因を理解することが重要です。First Paint は、ユーザーにとってあらゆるものをレンダリングできる最初の機会を測定します。理想的には、背景色などではなく、意味のあるものにする必要がありますが、コンテンツにコンテンツがなくても、従来から定義されていたクリティカル レンダリング パスを測定するための根拠となる何かをユーザーに提示することにはまだ価値があります。それと同時に、メイン コンテンツがユーザーに表示されたタイミングを測定することにも価値があります。

コンテンツ フル レンダリング パスの特定

多くのツールで、LCP 要素とレンダリングのタイミングを識別できます。Lighthouse では、LCP 要素だけでなく、LCP のフェーズと各フェーズにかかった時間も把握できるため、最適化に力を入れるべきポイントを把握できます。

Lighthouse の LCP 監査のスクリーンショット。ページの LCP 要素と、TTFB、読み込み遅延、読み込み時間、レンダリング遅延などの各フェーズにかかった時間が表示されています。

より複雑なサイトの場合、Lighthouse では、一連の重要なリクエストのチェーンも別の監査でハイライト表示されます。

Lighthouse のクリティカル リクエスト チェーン図のスクリーンショット。他のクリティカル リソースの下にネストされているクリティカル リソースと、クリティカル リクエスト チェーンに関連する合計レイテンシが表示されています。

この Lighthouse の監査では、読み込まれたすべてのリソースを高い優先度でモニタリングします。そのため、実際にレンダリングをブロックしていなくても、Chrome が優先度の高いリソースとして設定しているウェブフォントやその他のコンテンツが含まれます。

理解度テスト

クリティカル レンダリング パスとは何を指しますか?

最初のページ レンダリングを実行するために必要な最小リソース量。
ページを完全にレンダリングするために必要な最小リソース量。

クリティカル レンダリング パスにはどのようなリソースが関係していますか?

<head> 要素内のレンダリングをブロックする JavaScript。
HTML の一部。
<head> 要素内のレンダリングをブロックする CSS。

レンダリング ブロックがページ レンダリングに必要な部分であるのはなぜですか?

ページが完全にレンダリングされるまで、ユーザーにページが表示されないようにする。
ページが最初に使用できない状態または一見破損している状態でレンダリングされないようにする。

JavaScript が HTML パーサーをブロックするのはなぜですか(<script> 要素で deferasyncmodule の各属性が指定されていないと想定しています)。

同期 JavaScript は DOM を変更する可能性があるため、パーサーが到達した時点で実行する必要があります。
これらの属性が 1 つもない場合、<script> はパーサー ブロックとレンダリング ブロックとなります。
すべての JavaScript は、これらの属性に関係なく、パーサー ブロックを行います。

次のトピック: リソースの読み込みを最適化する

このモジュールでは、ブラウザがウェブページをレンダリングする仕組みと、特にページの最初のレンダリングを完了するために必要なものについて、いくつかの理論について説明しました。次のモジュールでは、リソースの読み込みを最適化する方法を学習することで、このレンダリング パスを最適化する方法について学習します。