代表的な面接トピック

フロントエンド面接:Long Animation Frames API を使用してフィールド INP を診断するにはどうすればよいですか?

フロントエンド難しい
Offer.cc 編集チーム公開日 更新日

質問

ラボのメトリクスは健全に見えますが、一部の実ユーザーで INP が悪化しています。Long Animation Frames API(LoAF)を使用して、レポートコストとプライバシーリスクを抑制しながら、入力遅延、スクリプト処理、レンダリングコストを切り分けるフィールド診断パイプラインを設計してください。

プロンプトとコンテキスト

ページは Lighthouse では良好に見えますが、実ユーザーからはクリックが固まったように感じられるという報告があります。既存の RUM は INP の値のみをレポートしており、イベントハンドラー、requestAnimationFrame、スタイルやレイアウト、サードパーティスクリプトのどれが遅延の原因であるかを特定できません。LoAF の監視、相関付け、サンプリング、集約、および修正ループを設計してください。

面接官が見ているポイント

  • INP の入力遅延(input delay)、処理時間(processing duration)、表示遅延(presentation delay)を理解しているか。
  • LoAF が 50 ミリ秒を超えるフレームを測定し、スクリプトの帰属(attribution)やレンダリングのタイミングを公開することを知っているか。
  • すべての生イベントをアップロードするのではなく、インタラクション、LoAF、ページバージョン、デバイスコンテキストを関連付けているか。
  • ブラウザのサポート状況、バッファ、クロスオリジンスクリプト、プライバシーリスクに対処しているか。
  • データをコードの修正、リグレッションチェック、アラート通知に結び付けているか。

最初に確認すべき質問

  1. 目的は INP の診断、アニメーションの滑らかさ、ロングタスクの監視、またはこれら 3 つすべてですか?
  2. サンプリングレート、1 日のユーザー数、レポートのコスト予算、保持期間はどのくらいですか?
  3. URL、スクリプトソース、インタラクションタイプ、ページバージョンを記録することは許可されていますか?
  4. サポートすべきブラウザはどれですか?また、LoAF が利用できない場合のフォールバックは何ですか?
  5. アラートと修正のオーナーとなるチームはどこですか?また、しきい値には p75、p95、あるいはデバイスコホートを使用すべきですか?

30秒での回答

「私なら、INP のフェーズ内訳と LoAF の監視を 1 つの RUM 相関パスにまとめます。long-animation-frame には PerformanceObserver を使用し、高い INP を示したインタラクションウィンドウと重なるフレームのみを保持して、duration、blockingDuration、renderStart、styleAndLayoutStart、およびスクリプト帰属情報を維持します。サポート状況を検知し、フィールドを墨消し(リダクション)し、動的にサンプリングを行い、ページバージョン、デバイスコホート、匿名セッションキーとともにレポートをバッチ送信します。インタラクションおよびリリースごとに集約し、アラートを sourceURL と関数に紐付けます。同じコホートとサンプリングを用いて各修正を検証します。」

ステップごとの詳細解説

1. INP フェーズを分割する

入力遅延はキューイングからハンドラー開始までの時間、処理時間はハンドラーの実行時間、表示遅延は処理終了から次の描画フレームまでの時間です。LoAF は INP を置き換えるものではありません。遅いフェーズを特定するためのフレームコンテキストを追加します。

2. LoAF エントリを監視する

パフォーマンスタイムラインを繰り返し読み取るのではなく、PerformanceObserver を使用して long-animation-frame を監視します。しきい値は 50 ミリ秒であり、エントリには durationblockingDurationrenderStartstyleAndLayoutStartfirstUIEventTimestampscripts が含まれます。

js
if (PerformanceObserver.supportedEntryTypes.includes("long-animation-frame")) {
  const observer = new PerformanceObserver((list) => {
    for (const entry of list.getEntries()) {
      queueFrameForCorrelation(entry);
    }
  });
  observer.observe({ type: "long-animation-frame", buffered: true });
}

3. インタラクションとリリースを関連付ける

短期間の INP インタラクションサマリーと LoAF エントリのリングバッファを保持します。インタラクションが終了したら、firstUIEventTimestampstartTimeduration を使用して交差するフレームを見つけ、最も説明力の高い少数のフレームのみを保持します。完全な入力内容ではなく、ページバージョン、実験コホート、デバイスクラス、匿名セッションキーを付与します。

4. スクリプトとレンダリングのコストを説明する

blockingDuration は入力や優先度の高い処理をブロックする時間を推定します。renderStartstyleAndLayoutStart はプリレンダリング、スタイル/レイアウト、その他のフェーズを切り分けるのに役立ちます。scripts はメインスレッドの URL、関数、呼び出し元のタイプを特定できますが、クロスオリジンの iframe、Worker、拡張機能では帰属情報が不完全になる場合があります。

5. サンプリングとプライバシー管理を設計する

デフォルトでは高い INP、異常なロングフレーム、または少量のランダムサンプルをレポートし、匿名セッションごとにレート制限を設けます。スクリプトドメインを許可リスト化またはハッシュ化し、クエリパラメータ、ユーザー入力、DOM テキストを除去し、機密ページでは詳細な帰属情報を無効にします。サーバー側で保持、アクセス、削除、およびバージョン管理されたサンプリングポリシーを強制します。

6. 集約と修正のループを閉じる

単一のサイト平均ではなく、インタラクション、リリース、デバイス、ネットワーク、スクリプトソースごとに p75/p95 を集約します。アラートには入力、処理、表示の各フェーズと共通の帰属情報を表示します。問題が別のデバイスやインタラクションに移動していないことを確認するために、同じサンプリングとコホートを使用して前後の比較を行います。

優れた回答例

「私ならまず、INP のフェーズ内訳を使用して入力、処理、表示のどれが支配的であるかを判断し、次に LoAF のエビデンスを追加します。クライアントは機能を検知して long-animation-frame を監視し、高い INP インタラクションと交差するエントリのみを duration、blockingDuration、レンダリングタイミング、利用可能なスクリプト帰属情報とともに保持します。相関付けにはユーザー入力ではなく、リリース、実験コホート、デバイス、匿名セッションキーを使用します。詳細な帰属情報はサンプリングと墨消しを行い、保持制限を設けます。非対応ブラウザでも基本的な INP は引き続きレポートします。サーバー側ではインタラクション、リリース、デバイスごとに集約し、原因と思われるソースコードに対してアラートを発令し、コホートレベルのリグレッションチェックで修正を検証します。」

よくある間違い

  • 単一の INP 数値のみをレポートする → フェーズやコードの診断ができない → INP フェーズと LoAF フレームを関連付ける。
  • すべてのロングフレームを生のままアップロードする → 高コストかつコンテキストが露出する → サンプリング、墨消しを行い、高い INP と交差するフレームのみを保持する。
  • 50 ミリ秒を INP の合格ラインとして扱う → フレームのしきい値とプロダクトメトリクスを混同している → しきい値とパーセンタイル目標を明確に分けて説明する。
  • すべてのスクリプトに帰属情報があると想定する → クロスオリジンのフレームや Worker では不完全になる → ギャップをマークし、リリースおよびデバイスコホートとともに分析する。
  • サイト平均のみを確認する → デバイス固有の深刻な問題が見落とされる → インタラクション、デバイス、ネットワーク、リリースごとにセグメント化する。

フォローアップと回答

LoAF は Long Tasks API を置き換えますか?

直接置き換えるわけではありません。LoAF はフレームを測定し、より豊富なコンテキストを提供しますが、Long Tasks は既存の監視や対応ブラウザにおいて依然として有用です。古いシグナルを突然削除するのではなく、移行期間中は両方を比較してください。

なぜすべてのスクリプト URL をアップロードしないのですか?

URL には識別子、クエリパラメータ、内部パスが含まれる可能性があり、データ量も増加するためです。ページの機密性に応じて、パラメータの除去、ドメインの制限、値のハッシュ化、またはバージョン管理されたソースマッピングのみを保持するようにします。

レイアウトコストとスクリプト実行をどのように区別しますか?

renderStartstyleAndLayoutStartduration、およびスクリプトエントリを比較します。スクリプト時間が短く、スタイル/レイアウトの間隔が大きい場合は、DOM サイズ、セレクター、同期レイアウトを調査し、ラボトレースで確認します。

LoAF に対応していないブラウザはどうしますか?

機能検知を行い、基本的な INP、Event Timing、または Long Tasks にフォールバックし、サーバー側で監視バージョンをタグ付けします。それらのユーザーを全体的なエクスペリエンスメトリクスから除外するのではなく、セグメント化されたレポートで診断機能の差異を開示します。

公開情報ソース

関連する質問