ブラウザのプリロード スキャナに対抗しない

ブラウザ プリロード スキャナとは何か、それがどのようにパフォーマンス向上に役立つのか、どうすればバグを回避できるのかを解説します。

ページ速度を最適化するうえで見落とされがちな側面の一つとして、ブラウザの内部構造についての知識が欠かせません。ブラウザでは、デベロッパーが不可能な方法でパフォーマンスを改善するために特定の最適化を行いますが、それは、その最適化が意図せず阻止されない限りです。

理解しておくべき内部ブラウザ最適化の 1 つは、ブラウザのプリロード スキャナです。この投稿では、プリロード スキャナの仕組みに加えて、プリロード スキャナの回避方法について説明します。

プリロード スキャナとは

どのブラウザにも、未加工のマークアップをトークン化してオブジェクト モデルに処理するプライマリ HTML パーサーがあります。これは、<link> 要素で読み込まれたスタイルシートや、async または defer 属性のない <script> 要素で読み込まれたスクリプトなど、ブロッキング リソースを検出したときにパーサーが一時停止するまで、順調に続きます。

HTML パーサーの図。
図 1: ブラウザのメイン HTML パーサーをブロックする方法の図。この場合、パーサーは外部 CSS ファイルの <link> 要素に遭遇します。これにより、CSS がダウンロードされて解析されるまで、ブラウザはドキュメントの残りの部分の解析やレンダリングをブロックします。

CSS ファイルの場合、スタイルが設定されていないコンテンツ(FOUC)がフラッシュされるのを防ぐため、レンダリングはブロックされます。

スタイルなしの状態(左)とスタイルありの状態(右)の web.dev ホームページ。 <ph type="x-smartling-placeholder">
</ph> 図2: FOUC のシミュレーション例。左はスタイルなしの web.dev のフロントページです。右は、スタイルが適用された同じページです。スタイルシートのダウンロードと処理中にブラウザがレンダリングをブロックしない場合、スタイル化されていない状態が一瞬で発生することがあります。

また、defer または async 属性のない <script> 要素が検出された場合、ブラウザはページの解析とレンダリングをブロックします。

これは、メインの HTML パーサーが機能している間に、特定のスクリプトが DOM を変更するかどうかをブラウザが確実に把握できないためです。そのため、ブロックされた解析とレンダリングの影響が軽微になるように、JavaScript をドキュメントの最後に読み込むのが一般的です。

これが、ブラウザで解析とレンダリングの両方をブロックすることが推奨されている正当な理由です。しかし、これらの重要なステップのいずれかをブロックすることは望ましくありません。他の重要なリソースの発見が遅れて番組を進行できなくなる可能性があるためです。幸いなことに、ブラウザは「プリロード スキャナ」という二次的な HTML パーサーを使用して、この問題を最善を尽くします。

プライマリ HTML パーサー(左)とプリロード スキャナ(右)の両図(セカンダリ HTML パーサー) <ph type="x-smartling-placeholder">
</ph> 図3: プリロード スキャナがプライマリ HTML パーサーと並行して機能し、アセットを投機的に読み込む仕組みを示した図。ここでは、<body> 要素の画像マークアップの処理を開始する前に CSS を読み込んで処理するため、プライマリ HTML パーサーがブロックされています。一方、プリロード スキャナは、未加工のマークアップを先読みして画像リソースを見つけ、プライマリ HTML パーサーのブロックが解除される前に読み込みを開始できます。

プリロード スキャナの役割は投機的です。つまり、プライマリ HTML パーサーが検出する前に、未加工のマークアップを調べて、状況によってフェッチするリソースを見つけます。

プリロード スキャナが動作していることを確認する方法

プリロード スキャナは、レンダリングと解析がブロックされているため存在します。この 2 つのパフォーマンスの問題がまったく発生していなければ、プリロード スキャナはあまり役に立たないでしょう。ウェブページにプリロード スキャナが役立つかどうかを判断するには、こうしたブロック現象が重要になります。そのためには、プリロード スキャナが動作している場所を検出するためのリクエストを人為的に遅延させます。

基本的なテキストと画像に関するこちらのページを例に、スタイルシートを追加します。CSS ファイルはレンダリングと解析の両方をブロックするため、プロキシ サービスを通じてスタイルシートで人為的な遅延(2 秒)が発生します。この遅延により、プリロード スキャナが動作している場所をネットワーク ウォーターフォールで簡単に確認できます。

WebPageTest ネットワークのウォーターフォール チャートは、スタイルシートで設定された 2 秒の人為的な遅延を示しています。 <ph type="x-smartling-placeholder">
</ph> 図4: モバイル デバイスの Chrome で 3G 接続をシミュレートして実行したウェブページWebPageTest ネットワーク ウォーターフォール チャート。スタイルシートの読み込みが開始される前にプロキシによって 2 秒間人為的に遅延される場合でも、マークアップ ペイロードの後半にある画像はプリロード スキャナによって検出されます。

ウォーターフォールからわかるように、レンダリングとドキュメントの解析がブロックされていても、プリロード スキャナは <img> 要素を検出します。この最適化を行わないと、ブラウザはブロック期間中にオポチュニスティックにフェッチできず、リソース リクエストが同時実行ではなく連続的に行われます。

簡単な例を挙げて、プリロード スキャナを破る実際のパターンと、それを修正する方法を見ていきましょう。

async スクリプトを挿入しました

<head> に、次のようなインライン JavaScript を含む HTML があるとします。

<script>
  const scriptEl = document.createElement('script');
  scriptEl.src = '/yall.min.js';

  document.head.appendChild(scriptEl);
</script>

挿入されたスクリプトはデフォルトで async であるため、このスクリプトが挿入されると、async 属性が適用された場合と同じように動作します。つまり、レンダリングがブロックされるのではなく、できるだけ早く実行されます。最適だと思いませんか?ただし、このインライン <script> が、外部 CSS ファイルを読み込む <link> 要素の後に配置されていると想定すると、最適な結果は得られません。

この WebPageTest チャートは、スクリプトの挿入時に無効化されたプリロード スキャンを示しています。 <ph type="x-smartling-placeholder">
</ph> 図5: 3G 接続のシミュレーションによりモバイル デバイスの Chrome で実行されたウェブページの WebPageTest ネットワークのウォーターフォール チャート。このページには、1 つのスタイルシートと、挿入された async スクリプトが含まれています。プリロード スキャナは、スクリプトがクライアントに挿入されているため、レンダリング ブロック フェーズ中にスクリプトを見つけることができません。

ここで何が起こったのかを詳しく見ていきましょう。

  1. 0 秒後に、メイン ドキュメントがリクエストされます。
  2. 1.4 秒で、ナビゲーション リクエストの最初のバイトが到着します。
  3. 2.0 秒で、CSS と画像がリクエストされます。
  4. パーサーはスタイルシートの読み込みをブロックされ、async スクリプトを挿入するインライン JavaScript は、そのスタイルシートの 2.6 秒後に後から読み込まれるため、スクリプトによって提供される機能はすぐに使用できません。

スクリプトのリクエストはスタイルシートのダウンロードが完了した後にのみ発生するため、最適な方法ではありません。これにより、スクリプトの実行を遅らせることができます。一方、<img> 要素はサーバーが提供するマークアップで検出できるため、プリロード スキャナで検出されます。

それでは、スクリプトを DOM に挿入するのではなく、通常の <script> タグを async 属性とともに使用するとどうなるでしょうか。

<script src="/yall.min.js" async></script>

結果は次のとおりです。

スタイルシートのダウンロードと処理中にブラウザのプライマリ HTML パーサーがブロックされていても、HTML スクリプト要素を使用して読み込まれた非同期スクリプトがブラウザのプリロード スキャナで検出される仕組みを示す WebPageTest ネットワークのウォーターフォール。 <ph type="x-smartling-placeholder">
</ph> 図6: 3G 接続のシミュレーションによりモバイル デバイスの Chrome で実行されたウェブページの WebPageTest ネットワークのウォーターフォール チャート。このページには、1 つのスタイルシートと 1 つの async <script> 要素が含まれています。プリロード スキャナは、レンダリング ブロック フェーズ中にスクリプトを見つけ、CSS と同時に読み込みます。

rel=preload を使用すると、これらの問題を解決できると思われたくなるかもしれませんが、これは確かに効果がありますが、なんらかの副作用が生じることがあります。結局のところ、<script> 要素を DOM に挿入しないことで回避できる問題を修正するために、rel=preload を使用する理由は何でしょうか。

WebPageTest のウォーターフォール。rel=preload リソース ヒントを使用して非同期挿入スクリプトの検出を促進する方法を示しています。ただし、意図しない副作用が生じる可能性があります。 <ph type="x-smartling-placeholder">
</ph> 図7: 3G 接続のシミュレーションによりモバイル デバイスの Chrome で実行されたウェブページの WebPageTest ネットワークのウォーターフォール チャート。このページには 1 つのスタイルシートと挿入された async スクリプトが含まれていますが、早期に検出できるように async スクリプトはプリロードされています。

プリロードによってこの問題は「修正」されますが、新しい問題が発生します。最初の 2 つのデモの async スクリプトは、<head> で読み込まれているにもかかわらず、優先度が「低」で読み込まれます。一方、スタイルシートは優先度が「最高」で読み込まれます。async スクリプトがプリロードされている最後のデモでは、スタイルシートは「最高」で読み込まれています。スクリプトの優先度は「高」に変更されています。

リソースの優先度を上げると、ブラウザはそのリソースに割り当てる帯域幅を増やします。つまり、スタイルシートの優先度が最も高い場合でも、スクリプトの優先度が高いと帯域幅の競合が発生する可能性があります。これは、接続が遅い場合や、リソースが非常に大きい場合に要因となる可能性があります。

ここでの答えは明白です。起動時にスクリプトが必要な場合は、DOM に挿入してもプリロード スキャナを無効にしないでください。<script> 要素の配置や、deferasync などの属性を必要に応じて試します。

JavaScript による遅延読み込み

遅延読み込みはデータを保存するための優れた方法で、多くの場合、画像に適用されます。ただし、遅延読み込みは、いわば「スクロールせずに見える範囲」にある画像に誤って適用されることがあります。

これにより、リソースの検出可能性に問題が生じる可能性があり、プリロード スキャナが懸念されます。また、イメージへの参照の検出、ダウンロード、デコード、表示にかかる時間が不必要に遅延する可能性があります。例として、次の画像マークアップを見てみましょう。

<img data-src="/sand-wasp.jpg" alt="Sand Wasp" width="384" height="255">

data- 接頭辞の使用は、JavaScript による遅延ローダーでは一般的なパターンです。画像がビューポートにスクロールされると、遅延読み込み機能によって data- 接頭辞が削除されます。つまり、上記の例では data-srcsrc になります。この更新により、ブラウザにリソースの取得を求めるメッセージが表示されます。

このパターンは、起動時にビューポートに表示される画像に適用されるまで問題はありません。プリロード スキャナは、src(または srcset)属性と同じ方法で data-src 属性を読み取るため、画像参照は早期に検出されません。さらに悪いことに、遅延ローダの JavaScript がダウンロード、コンパイル、実行を行ったまで画像の読み込みが遅延します。

WebPageTest ネットワークのウォーターフォール チャートは、ブラウザのプリロード スキャナが画像リソースを見つけることができず、ワークロードへの遅延読み込みに必要な JavaScript が実行された場合にのみ読み込まれるため、起動時にビューポートにある遅延読み込みの画像が必然的に遅延する仕組みを示しています。イメージが本来よりもずっと遅れて検出される。 <ph type="x-smartling-placeholder">
</ph> 図8: 3G 接続のシミュレーションによりモバイル デバイスの Chrome で実行されたウェブページの WebPageTest ネットワークのウォーターフォール チャート。画像リソースは、起動時にビューポートに表示されているにもかかわらず、不必要に遅延読み込みされます。これにより、プリロード スキャナが機能しなくなり、不要な遅延が発生します。

画像のサイズ(ビューポートのサイズに依存する場合があります)によっては、Largest Contentful Paint(LCP)の候補要素になる可能性があります。プリロード スキャナが、ページのスタイルシートがレンダリングをブロックしているときに、画像リソースを事前に推測して取得できない場合、LCP が低下します。

この問題を解決するには、画像マークアップを変更します。

<img src="/sand-wasp.jpg" alt="Sand Wasp" width="384" height="255">

プリロード スキャナはより迅速に画像リソースを検出して取得できるため、これは起動時にビューポートにある画像に最適なパターンです。

起動時にビューポートに表示される画像の読み込みシナリオを示す WebPageTest ネットワークのウォーターフォール チャート。イメージの読み込みを遅らせることはありません。つまり、読み込むスクリプトに依存せず、プリロード スキャナでより早く画像を検出できます。 <ph type="x-smartling-placeholder">
</ph> 図9: 3G 接続をシミュレートしたモバイル デバイスの Chrome で実行されたウェブページの WebPageTest ネットワークのウォーターフォール チャート。プリロード スキャナは、CSS と JavaScript の読み込み開始前に画像リソースを検出するため、ブラウザがいち早く読み込むことができます。

この簡素化された例では、低速の接続での LCP が 100 ミリ秒改善されています。それほど大きな改善に思えないかもしれませんが、マークアップを手っ取り早く修正できれば、多くのウェブページがこの例よりも複雑になります。つまり、LCP の候補は、他の多くのリソースを使用して帯域幅を奪い合うことになる可能性があるため、このような最適化がますます重要になります。

CSS 背景画像

ブラウザのプリロード スキャナはマークアップをスキャンします。background-image プロパティによって参照される画像の取得を伴う可能性がある CSS など、他のリソースタイプはスキャンされません。

HTML と同様に、ブラウザは CSS を CSSOM という独自のオブジェクト モデルに処理します。CSSOM の構築時に外部リソースが検出された場合、それらのリソースはプリロード スキャナからではなく、検出時にリクエストされます。

たとえば、ページの LCP 候補が、CSS の background-image プロパティを持つ要素であるとします。リソースを読み込むと、次のようになります。

background-image プロパティを使用して CSS から読み込まれた LCP 候補のページを示す WebPageTest ネットワークのウォーターフォール チャート。LCP 候補の画像は、ブラウザのプリロード スキャナで検証できないリソースタイプであるため、CSS のダウンロードと処理が完了するまでリソースの読み込みが遅延し、LCP 候補のペイント時間が遅延します。 <ph type="x-smartling-placeholder">
</ph> 図10: 3G 接続のシミュレーションによりモバイル デバイスの Chrome で実行されたウェブページの WebPageTest ネットワークのウォーターフォール チャート。ページの LCP 候補が、CSS の background-image プロパティを含む要素である(3 行目)。リクエストされた画像は、CSS パーサーが画像を見つけるまで取得されません。

この場合、プリロードスキャナーはあまり役に立たず、関与していません。それでも、ページ上の LCP 候補が background-image CSS プロパティからのものである場合、その画像をプリロードする必要があります。

<!-- Make sure this is in the <head> below any
     stylesheets, so as not to block them from loading -->
<link rel="preload" as="image" href="lcp-image.jpg">

この rel=preload ヒントは小さいですが、ブラウザが画像をより早く検出できるようにします。

rel=preload ヒントを使用しているため、CSS 背景画像(LCP 候補)の読み込みが大幅に早くなっている WebPageTest ネットワークのウォーターフォール チャート。LCP 時間は約 250 ミリ秒改善されています。
図 11: モバイル デバイスの Chrome でシミュレートされた 3G 接続経由で実行されたウェブページの WebPageTest ネットワーク ウォーターフォール チャート。ページの LCP 候補が、CSS の background-image プロパティを含む要素である(3 行目)。rel=preload ヒントを使用すると、ブラウザはヒントなしの場合よりも約 250 ミリ秒以内に画像を検出できます。

rel=preload ヒントを使用すると、LCP 候補がより早く検出されるため、LCP 時間が短縮されます。このヒントは問題の解決に役立ちますが、画像 LCP 候補を CSS から読み込む必要はあるかどうかを判断することをおすすめします。<img> タグを使用すると、ビューポートに適した画像の読み込みをより細かく制御しながら、プリロード スキャナで画像を検出できます。

リソースのインライン化が多すぎる

インライン化とは、HTML 内にリソースを配置する手法です。<style> 要素内のスタイルシート、<script> 要素内のスクリプト、また、base64 エンコードを使用すると、ほぼすべてのリソースのインライン化が可能です。

リソースのインライン化は、リソースに対して個別のリクエストが発行されないため、ダウンロードよりも短時間で実行できます。ドキュメントに挿入され、すぐに読み込まれます。ただし、次のような大きなデメリットがあります。

  • HTML をキャッシュに保存していない場合(HTML レスポンスが動的である場合はキャッシュに保存できない場合)は、インライン リソースはキャッシュに保存されません。インライン化されたリソースは再利用できないため、パフォーマンスに影響します。
  • HTML をキャッシュに保存できる場合でも、インライン化されたリソースはドキュメント間で共有されません。そのため、送信元全体でキャッシュに保存して再利用できる外部ファイルと比較して、キャッシュ保存の効率が低下します。
  • インラインが多すぎると、追加のインライン コンテンツのダウンロードに時間がかかるため、プリロード スキャナがドキュメントの後半でリソースを検出するのが遅くなります。

こちらのページを例として使用します。特定の条件下では、LCP の候補がページ上部の画像で、CSS が <link> 要素によって読み込まれる別のファイルにある場合、また、このページでは 4 つのウェブフォントが使用されており、これらは CSS リソースから個別のファイルとしてリクエストされます。

4 つのフォントが参照されている外部 CSS ファイルを含む、WebPageTest ネットワークのウォーターフォール チャート。LCP 候補イメージは、やがてプリロード スキャナによって検出されます。 <ph type="x-smartling-placeholder">
</ph> 図12: 3G 接続のシミュレーションによりモバイル デバイスの Chrome で実行されたウェブページの WebPageTest ネットワークのウォーターフォール チャート。ページの LCP 候補は <img> 要素から読み込まれた画像ですが、ページの読み込みに必要な CSS とフォントが個別のリソースにあるため、プリロード スキャナによって検出されます。これにより、プリロード スキャナの処理が遅延することはありません。

CSS とすべてのフォントが base64 リソースとしてインライン化されている場合はどうなるでしょうか。

4 つのフォントが参照されている外部 CSS ファイルを含むページの WebPageTest ネットワーク ウォーターフォール チャート。プリロード スキャナで LCP イメージの検出が大幅に遅れる。
図 13: モバイル デバイスの Chrome でシミュレートされた 3G 接続経由で実行されたウェブページの WebPageTest ネットワーク ウォーターフォール チャート。ページの LCP 候補は <img> 要素から読み込まれる画像ですが、CSS とその 4 つのフォントリソースが `` にインライン化されているため、これらのリソースが完全にダウンロードされるまで、プリロード スキャナが画像を検出できません。

インライン化の影響は、この例の LCP だけでなく、一般的なパフォーマンスにも悪影響を及ぼします。何もインライン化していないバージョンのページでは、約 3.5 秒で LCP 画像が描画されます。すべてをインライン化するページでは、7 秒強まで LCP 画像が描画されません。

プリロード スキャナ以外にも、さまざまな機能があります。base64 はバイナリ リソースとして非効率的な形式であるため、フォントのインライン化は優れた戦略ではありません。もう一つの問題は、外部フォント リソースは、CSSOM によって必要だと判断されない限りダウンロードされないことです。これらのフォントが base64 としてインライン化されると、現在のページで必要かどうかにかかわらずダウンロードされます。

プリロードで改善できる可能性はありますか?会話のLCP 画像をプリロードして LCP 時間を短縮することはできますが、キャッシュに保存できない可能性のある HTML をインライン リソースで膨らませると、パフォーマンスに悪影響が及ぶ可能性があります。First Contentful Paint(FCP)もこのパターンの影響を受けます。何もインライン化されていないバージョンのページでは、FCP は約 2.7 秒です。すべてがインライン化されたバージョンでは、FCP は約 5.8 秒です。

HTML への埋め込み(特に Base64 エンコードのリソース)には細心の注意を払ってください。リソースが非常に少ない場合を除き、通常はおすすめしません。可能な限りインライン化する。インライン化しすぎると、処理されなくなる。

クライアントサイドの JavaScript を使用したマークアップのレンダリング

JavaScript は間違いなくページ速度に影響する。デベロッパーはインタラクティビティ機能の提供だけでなく、コンテンツそのものの提供にも Gemini に頼る傾向があります。これは、いくつかの点で開発者エクスペリエンスの向上につながります。デベロッパーにとってのメリットが、必ずしもユーザーにとってのメリットになるとは限りません。

プリロード スキャナを回避できるパターンの 1 つは、クライアントサイドの JavaScript を使用したマークアップのレンダリングです。

クライアント上で JavaScript を使用して画像とテキストが完全にレンダリングされた基本的なページを示す WebPageTest ネットワークのウォーターフォール。マークアップは JavaScript に含まれているため、プリロード スキャナはどのリソースも検出できません。さらに、JavaScript フレームワークで必要となる追加のネットワークと処理時間により、すべてのリソースで遅延が発生します。 <ph type="x-smartling-placeholder">
</ph> 図14: クライアントがレンダリングするウェブページの WebPageTest ネットワークのウォーターフォール チャートは、3G 接続をシミュレートしたモバイル デバイスの Chrome で動作します。コンテンツは JavaScript に含まれ、レンダリングはフレームワークに依存するため、クライアントがレンダリングするマークアップの画像リソースはプリロード スキャナに表示されません。同等のサーバーでレンダリングされた状態を図9.

マークアップのペイロードが JavaScript によってブラウザ内に含まれ、完全にレンダリングされている場合、そのマークアップ内のリソースはプリロード スキャナから実質的に認識できません。これにより重要なリソースの検出が遅れ、LCP にも確実に影響します。これらの例では、LCP 画像のリクエストは、JavaScript の表示を必要としない同等のサーバー レンダリングに比べると、著しく遅延しています。

これはこの記事の焦点とは少し異なりますが、マークアップのレンダリングがクライアントに及ぼす影響は、プリロード スキャナを無効にするだけにとどまりません。たとえば、JavaScript を導入して必要のないエクスペリエンスを強化すると、不要な処理時間が発生し、Next Paint(INP)に影響する可能性があります。クライアントで非常に大量のマークアップをレンダリングすると、サーバーから送信される同じ量のマークアップと比較して、長いタスクが発生する可能性が高くなります。その理由は、JavaScript に伴う追加の処理以外に、ブラウザがサーバーからマークアップをストリーミングし、長いタスクを制限するような方法でレンダリングをチャンク化するからです。一方、クライアントがレンダリングするマークアップは、単一のモノリシック タスクとして処理されるため、ページの INP に影響する可能性があります。

このシナリオに対する対処方法は、「ページのマークアップを、クライアント上でレンダリングされるのではなく、サーバーから提供できないのはなぜか」という質問に対する答えによって異なります。答えが「いいえ」の場合は、サーバーサイド レンダリング(SSR)または静的に生成されたマークアップを検討してください。これにより、プリロード スキャナが重要なリソースを事前に検出して、状況に応じてフェッチできるようになります。

ページのマークアップの一部に機能を付加するために JavaScript が必要な場合でも、SSR(Vanilla JavaScript またはハイドレーション)を使用して両方の利点を活かすことができます。

プリロード スキャナが

プリロード スキャナは、起動時にページの読み込み時間を短縮する非常に効果的なブラウザ最適化です。重要なリソースを事前に検出できないパターンを避けることで、開発を簡素化するだけでなく、ウェブに関する主な指標など、多くの指標でより良い結果をもたらす優れたユーザー エクスペリエンスを実現できます。

以下に、この投稿の重要なポイントをまとめます。

  • ブラウザのプリロード スキャナは二次的な HTML パーサーです。より早く取得できるリソースを、不都合に検出するためにプライマリ パーサーの前にスキャンします。
  • 最初のナビゲーション リクエストでサーバーによって提供されるマークアップに存在しないリソースは、プリロード スキャナで検出できません。プリロード スキャナを無効にする方法には、次のようなものがあります(これらに限定されません)。
    • JavaScript を使用してリソースを DOM に挿入します。スクリプト、画像、スタイルシートなど、サーバーからの最初のマークアップ ペイロードに含める方がよいリソースであれば何でもかまいません。
    • JavaScript ソリューションを使用して、折り返しの上の画像や iframe を遅延読み込みする。
    • JavaScript を使用して、ドキュメント サブリソースへの参照を含む可能性のあるマークアップをクライアントでレンダリングする。
  • プリロード スキャナは HTML のみをスキャンします。LCP の候補など、重要なアセットへの参照が含まれている可能性がある他のリソース(特に CSS)のコンテンツは調査しません。

なんらかの理由で、プリロード スキャナの読み込みパフォーマンスの高速化能力に悪影響を及ぼすパターンを回避できない場合は、rel=preload リソースヒントを検討してください。rel=preload を使用する場合は、ラボツールでテストを行い、意図した効果が得られることを確認してください。最後に、プリロードするリソースの数が多くなりすぎないようにしましょう。優先度を高く設定しても、何も優先度が上がらないからです。

リソース

Unsplash のヒーロー画像(著者: Mohammad Rahmani)