初回入力遅延を最適化する

ユーザー操作に迅速に応答する方法。

<ph type="x-smartling-placeholder">

クリックしても何も起こらないこのページを操作できないのはなぜですか?😢

First Contentful Paint(FCP)と Largest Contentful Paint(LCP)は、コンテンツの作成にかかった時間を測定する指標です。 ページ上で視覚的にレンダリング(ペイント)します。ペイント時間は重要ですが、 応答性: ページがユーザー操作にどれだけすばやく反応するかを示します。

First Input Delay(FID)は、Core Web Vitals の指標の一つで、ユーザーの サイトのインタラクティビティと応答性の第一印象。ユーザーが ブラウザが実際にそのページに応答できた時点まで、最初にそのページを操作する です。FID はフィールド指標であり、次の値にすることはできません。 実際の環境をシミュレートします。以下を測定するには、実際のユーザー操作が必要です。 応答の遅延。

良好な fid 値は 2.5 秒で、不良な値は 4.0 秒より大きく、その中間値は改善が必要です。

ラボで FID を予測できるように、 Total Blocking Time(TBT)を推奨します。測定するものは異なりますが TBT の改善は、通常 FID の改善に対応します。

FID 不振の主な原因は、JavaScript の負荷が高い実行です。JavaScript の解析方法を最適化すると、 コンパイルされ、ウェブページで実行されると、FID が直接削減されます。

JavaScript の負荷が高い

ブラウザは、メインスレッドで JavaScript を実行している間は、ほとんどのユーザー入力に応答できません。つまり、 メインスレッドがビジー状態のときに、ブラウザはユーザーの操作に応答できません。これを改善する方法は次のとおりです。

時間のかかるタスクを分割

すでに 1 つのページで読み込まれる JavaScript の量を減らすと、 長時間実行されるコードを小さな非同期タスクに分割する場合に役立ちます。

長いタスクとは、ユーザーが JavaScript で処理を実行する時間で、 UI が反応しないことがありますメインスレッドを 50 ミリ秒以上ブロックするコードは、 長時間のタスクと見なされます時間のかかるタスクは JavaScript の肥大化(ユーザーが必要とする以上のものの読み込みと実行など)。 長いタスクを分割することで、サイトでの入力遅延を軽減できます。

<ph type="x-smartling-placeholder">
</ph> Chrome DevTools の長時間タスク
Chrome DevTools の [Performance] パネルに長時間かかるタスクを可視化

コード分割や 長時間のタスク。TBT はフィールド指標ではありませんが、最終的な目標に向けての進捗状況を確認するのに有用です。 Time To Interactive(TTI)と FID の両方を 改善することを目指しています

インタラクションの準備が整うようにページを最適化する

ウェブアプリの FID スコアと TBT スコアが低い場合、 JavaScript:

ファーストパーティのスクリプトの実行は、インタラクションの準備が遅れる可能性がある

  • JavaScript の肥大化、大量の実行、非効率的なチャンクにより、 ページがユーザー入力に応答し、FID、TBT、TTI に影響を与える可能性があります。コードの段階的な読み込みと 課題を分散させ、インタラクションの準備を改善できます。
  • サーバーサイドでレンダリングされたアプリは、画面にピクセルが描画されているように見えることがある ただし、大規模なスクリプトの実行(例: リハイドレーションでイベントリスナーを接続します)。これには数百ミリ秒、場合によっては ルートベースのコード分割が使用されている場合、偶数秒間も課金されません。ロジックのシフトを増やすことを検討する または、ビルド時により多くのコンテンツを静的に生成する場合。

以下は、ファーストパーティのスクリプトの読み込みを最適化する前と後の TBT スコアです。 説明します。重要でないコンポーネントのスクリプトの読み込み(と実行)にかかるコストのかかる処理を、 クリティカル パスに含まれていたため、ユーザーはより早くページを操作できるようになりました。

ファースト パーティ スクリプトの最適化により、Lighthouse の TBT スコアが改善されました。

データ取得は、インタラクションの準備のさまざまな側面に影響を与える可能性があります

  • カスケード取得のウォーターフォール(例: JavaScript やコンポーネントのデータ取得)を待機すると、 インタラクションのレイテンシに影響する 可能性がありますカスケードのデータ取得への依存を最小限に抑えることを目指します。
  • 大規模なインライン データストアでは HTML 解析時間が長くなり、ペイントとインタラクションの両方に影響を与える可能性がある できます。クライアントサイドで後処理する必要があるデータの量を最小限に抑えるようにします。

サードパーティ スクリプトの実行により、インタラクションのレイテンシも遅延することがある

  • 多くのサイトにはサードパーティのタグや分析機能が含まれているため、ネットワークがビジー状態になり、 メインスレッドが定期的に応答しなくなり、インタラクションのレイテンシに影響する。小学 3 年生以上の子ども向け 第三者コードをオンデマンドで読み込む(例: スクロールしなければ見えない範囲の広告を ビューポートの近くまでスクロールされます)。
  • 場合によっては、サードパーティのスクリプトが優先度の点でファーストパーティのスクリプトより優先され、 帯域幅が大きくなり、ページがインタラクションに対応できるようになるまでの時間を遅らせることにもなります。試行 ユーザーに最大の価値をもたらすと判断したページを優先的に読み込みます。

ウェブワーカーを使用する

メインスレッドがブロックされることは、入力遅延の主な原因の一つです。ウェブ ワーカーを使用すると、 バックグラウンド スレッドで処理します。UI 以外のオペレーションを別のワーカー スレッドに移動すると、main 関数や FID が改善されます。

サイトで Web Worker を簡単に使用できるように、次のライブラリの使用を検討してください。

  • Comlink: 抽象化されたヘルパー ライブラリ postMessage であり、
  • Workway: 汎用のウェブ ワーカー エクスポータ
  • Workerize: モジュールをウェブ ワーカーに移動します。
で確認できます。

JavaScript の実行時間を短縮する

ページ内の JavaScript の量を制限すると、ブラウザが処理に要する時間を コードの実行時間が短縮されますこれにより、ブラウザがあらゆるリクエストにすばやく応答し、 向上します

ページで実行される JavaScript の量を減らすには:

  • 使用していない JavaScript を延期する
  • 使用していないポリフィルを最小限に抑える

使用していない JavaScript を延期する

デフォルトでは、すべての JavaScript はレンダリング ブロックを行います。ブラウザは、リンク先のスクリプト タグが 外部の JavaScript ファイルの場合は、その処理を一時停止し、ダウンロード、解析、コンパイル、実行を行う必要があります。 使用できます。そのため、ページの読み込みに必要なコードだけを 処理できます。

Chrome の [カバレッジ] タブ DevTools では、ウェブページで JavaScript がどの程度使用されていないかがわかります。

[カバレッジ] タブ

使用していない JavaScript を削減するには:

  • バンドルを複数のチャンクにコード分割する
  • async または defer を使用して、重要でない JavaScript(サードパーティのスクリプトを含む)を遅延させます。

コード分割とは、1 つの大きな JavaScript バンドルを小さなチャンクに分割する概念です。 (遅延読み込みともいいます)。 新しいブラウザのほとんどは動的インポートの構文をサポートしています。 オンデマンドでモジュールを取得できます。

import('module.js').then((module) => {
  // Do something with the module.
});

ルートの変更や変更など、特定のユーザー操作時に JavaScript を動的にインポートする 最初のページ読み込みで使用されていないコードは、 必要ありません。

動的インポートの構文は、一般的なブラウザのサポート以外にも、さまざまなビルドで使用できます。 支援します

  • webpack を使用している場合は、 傘下参入 モジュール バンドラとして Parcel を使用する場合は、 動的インポートのサポート
  • クライアントサイドのフレームワーク ReactAngular Vue は コンポーネント レベルでの遅延読み込みを容易にします。
で確認できます。

コード分割とは別に、常に非同期または defer を使用すると、 クリティカルパスやスクロールせずに見える範囲のコンテンツ

<script defer src="…"></script>
<script async src="…"></script>

特別な理由がない限り、すべてのサードパーティ スクリプトは defer のいずれかを使用して読み込む必要があります。 または async がデフォルトになります。

使用していないポリフィルを最小限に抑える

最新の JavaScript 構文を使用してコードを作成し、最新のブラウザ API を参照する場合、 古いブラウザで機能させるには、トランスパイルしてポリフィルを含める必要があります。

サイトにポリフィルやトランスパイルされたコードを含める場合、パフォーマンス上の主な懸念事項として、 新しいブラウザでは、必要なければダウンロードする必要はありません。JavaScript を削減するには 使用されていないポリフィルをできる限り最小限に抑えて、使用を 必要があります。

サイトでのポリフィルの使用を最適化するには:

  • Babel をトランスパイルとして使用する場合は、次のコマンドを使用します。 @babel/preset-env: ポリフィルのみを含めます。 ブラウザのサイズを 手動で設定することも可能Babel 7.9 の場合は、 さらに短縮する bugfixes オプション 最適化するために
  • module/nomodule パターンを使用して、2 つのバンドルを別々に配信します(@babel/preset-env も は target.esmodules を介してサポートします)

    <script type="module" src="modern.js"></script>
    <script nomodule src="legacy.js" defer></script>
    

    Babel でコンパイルされた新しい ECMAScript 機能の多くが、すでに環境でサポートされている サポートしています。このようにすることで トランスパイルされたコードのみが、実際に必要なブラウザで使用されます。

で確認できます。

デベロッパー ツール

FID の測定とデバッグには、いくつかのツールを使用できます。

Philip Walton、Kayce Basques、Ilya Grigorik、Annie Sullivan のレビューに感謝します。