代表的な面接トピック

フロントエンド面接:Client Hints を活用したプライバシー保護対応のレスポンシブ画像パイプラインをどう設計するか?

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

質問

コンテンツサイトでデバイス幅や DPR に応じた画像配信が必要ですが、CDN 側はキャッシュの断片化を懸念し、法務側はデバイスフィンガープリンティングを懸念しています。パイプライン、フォールバック、および効果測定の手法を設計してください。

プロンプトと適用範囲

あるコンテンツサイトが、スマートフォン、タブレット、デスクトップに対して異なる幅や DPR 値で画像を配信しています。プロダクト側は初回ビューの転送量削減を求めていますが、CDN 側は WidthDPR ごとにキャッシュエントリが作られることでキャッシュが断片化することを懸念しています。法務側は必要最小限のデバイス情報のみを要求しています。パイプラインを設計し、Client Hints なしの場合の挙動を説明し、CLS や重複ダウンロードを防ぎ、結果をどのように測定するかを定義してください。

これはブラウザのリソース選択、HTTP キャッシュ、パフォーマンス、アクセシビリティ、プログレッシブエンハンスメントをテストするものです。幅、DPR、トラフィックは測定すべき変数であり、データなしに固定の改善割合を約束してはなりません。

面接官がテストしている点

  • ブラウザが候補を選択できるように、srcsetsizes を使って実際の描画スロットを記述できるか。
  • Accept-CH、後続のリクエスト、Vary、および CDN キャッシュキーを1つのデータフローに結びつけられるか。
  • 高カーディナリティなヒントによるプライバシー、フィンガープリンティング、キャッシュ爆発のリスクを認識しているか。
  • JavaScript に依存しないフォールバック、寸法領域の確保、alt、測定ループを提供できるか。

最初に明確にすべき質問

  1. その画像はコンテンツ、装飾、それともアートディレクションされたヒーロー画像ですか?これによって alt や picture 要素の扱いが変わります。
  2. 各ブレークポイントにおける CSS スロットの幅とアスペクト比はどうなっていますか?sizes は単にビューポートではなく、スロットを記述する必要があります。
  3. CDN は正規化された幅、フォーマット、品質の値をキーにできますか?許可される幅の候補数はいくつですか?
  4. Client Hints、モダンフォーマット、レスポンシブプリロードに対するターゲットブラウザのサポート状況はどうですか?
  5. 初回ビューのメトリクス、キャッシュヒット率、画像バイト数、エラー率のベースラインはどうなっていますか?

30秒で答えるフレームワーク

まずはネイティブのレスポンシブ画像を使用し、その後サーバー/CDN のプログレッシブエンハンスメントとして Client Hints を追加します。ブラウザは srcsetsizes を使用して候補を選択します。サーバーがヒントによってレスポンスを変える場合は、Accept-CH を通知し、レスポンスに実際に影響を与えるフィールドをキャッシュポリシーに反映させます。バケット化された幅と正規化された DPR のみを許可し、安全なデフォルト値とヒントなしのパスを用意します。LCP、CLS、画像バイト数、ヒット率、エラー率で検証し、高エントロピーなヒントが本当に必要かを確認します。

ステップごとの回答

1. 有限の候補セットとスロットを定義する

元のアスペクト比を維持しながら、画像ごとに有限な幅のセット(例: 320、640、960、1280 など。これらは普遍的な標準ではなく一例です)を生成します。各レイアウトブレークポイントで予想される表示幅を sizes で表現します。ブラウザは DPR、ネットワーク、自身のポリシーも考慮します。必須のフォールバックとして src を維持します。

html
<img
  src="/img/card-640.jpg"
  srcset="/img/card-320.jpg 320w, /img/card-640.jpg 640w, /img/card-960.jpg 960w, /img/card-1280.jpg 1280w"
  sizes="(min-width: 66rem) 33vw, (min-width: 44rem) 50vw, 100vw"
  width="640"
  height="400"
  alt="Article cover"
  loading="lazy"
  decoding="async"
>

2. フォーマットとアートディレクションに picture を使用する

フォーマットの選択やモバイル用の別クロップが必要な場合は picture 要素を使用し、最後は src を持つ img 要素のフォールバックで締めくくります。フォーマットと幅の選択は分けて管理してください。固定のプリロードによって誤ったリソースが強制取得されるべきではありません。

3. Client Hints のループを最小限に保つ

レスポンスでは Accept-CH を使用して、DPRWidth など、サーバーが実際に使用するヒントを要求できます。ブラウザがそれらを送信するかどうか、いつ送信するかは、ブラウザのポリシー、権限、サポート状況に依存します。未知のヒントは無視し、キャッシュ可能なレスポンスを実際に変化させるフィールドのみを宣言してください。

http
Accept-CH: DPR, Width
Vary: Accept, DPR, Width

Vary はセマンティックな宣言であり、無制限にバリアントを作成する許可ではありません。Width を有限のバケットにマッピングするか、DPR を正規化するか、正規化した結果を CDN キーに含めます。任意の未加工パラメータをアップストリーム URL にそのまま連結してはいけません。

4. プライバシー、権限、入力の安全性を処理する

Client Hints はリクエストのメタデータであり、認証情報ではありません。提示された課題を解決する低エントロピーなヒントを優先し、プロファイリング目的でデバイスモデルデータを要求することは避けてください。幅、品質、フォーマットのパラメータを制限して許可リスト化します。また、画像変換サーバーは SSRF、オープンリダイレクト、過大な処理負荷から保護される必要があります。

5. プログレッシブエンハンスメントとアクセシビリティを維持する

ヒントが存在しない、拒否された、または CDN でミスヒットした場合でも、srcset/sizes とサーバーのデフォルト設定によって画像がロードされます。CLS を削減するために、widthheight、または同等のアスペクト比ボックスを設定します。ファーストビュー(above-the-fold)の LCP 画像には loading="eager"fetchpriority="high" を控えめに使用し、ファーストビュー外(below-the-fold)の画像は遅延読み込み(lazy-load)し、コンテンツ画像には意味のある alt テキストを提供します。

6. ロールバック可能な測定計画を構築する

比較可能なトラフィックとコンテンツをコントロール群とトリートメント群に分割します。LCP、INP、CLS、画像転送バイト数、デコード時間、ヒット率、エラー率、実際の表示幅、デバイスクラスを記録します。ヒット率が低下したり重複ダウンロードが増加した場合は、バリアントを追加する前に、ヒントのディメンションを削減するか、バケットを広げるか、Client Hints をロールバックします。

高品質な回答例

私ならブラウザネイティブの選択を最優先にします。有限の srcset、正確な sizes、固有の寸法(intrinsic dimensions)、そしてアクセシブルな alt テキストを提供します。picture 要素はフォーマットやアートディレクションが必要な場合にのみ使用し、信頼性の高い img 要素フォールバックを設けます。サーバーは実際に使用するヒントに対して Accept-CH を通知できますが、ヒントがサポートされていない、拒否されている、またはまだ利用できない場合でも最初のリクエストが正しく機能しなければなりません。

ヒントによってレスポンスが変わる場合、CDN キーを正規化された幅のバケット、DPR バケット、フォーマット、および許可リスト化された品質に制限します。Vary には表現に影響を与えるフィールドのみをリストします。生の幅やネットワーク値はカーディナリティが高くなる可能性があるため、個別にキャッシュオブジェクトを作成すべきではありません。具体的な必要性がない限りデバイスモデルデータは要求せず、ヒントを認証として扱うことは決してしません。最後に、ロールアウトを拡大する前に、同一コンテンツを用いた LCP/CLS、バイト数、ヒット率、エラー率に関する A/B テストを実施します。

よくある失敗パターン

  • 常に sizes="100vw" と記述し、マルチカラムレイアウトを無視して過大な候補画像を生成してしまう。
  • 後続リクエスト、権限、Accept-CHVary、キャッシュキーの文脈を考慮せずに説明してしまう。
  • 生の幅、DPR、またはネットワーク値ごとに CDN バリアントを作成してしまう。
  • 測定のためにクライアント側の JavaScript を必須とし、ファーストペイントやフォールバックの動作を損なってしまう。
  • レスポンシブ選択と競合する固定の preload リンクを使用してしまい、二重ダウンロードを発生させる。
  • alt、寸法の確保、パラメータの許可リスト化、または高エントロピーによるプライバシーリスクを無視する。

フォローアップ質問と模範回答

Vary は多ければ多いほど常に正しいですか?

いいえ。キャッシュ可能な表現を変更するリクエストフィールドのみを特定すべきです。高カーディナリティなフィールドはバリアントを増やしヒット率を低下させるため、正規化するか有限のサーバーポリシーを使用してください。

srcset が既に存在するのに、なぜ Client Hints を追加するのですか?

srcsetsizes はブラウザが自身のスロット情報を利用して選択できるようにするものであり、通常は第一の選択肢です。Client Hints は、サーバーまたは CDN がデバイスやネットワークのメタデータを使用してレスポンスを変換する必要がある場合のオプショナルな補足であり、フォールバックを置き換えるものではありません。

初回の HTML リクエストに Width は含まれますか?

含まれると想定すべきではありません。Accept-CH のネゴシエーションは後続のリクエストに影響し、送信はブラウザのサポートや権限に左右されます。したがって、最初のリクエストは単体で機能する必要があります。

キャッシュバケットが細かすぎるかどうかをどう判断しますか?

バケットごとのヒット率、バリアント数、エッジストレージ使用量、リクエストボリュームを追跡します。隣接する幅を統合してバイト数と LCP を比較し、パフォーマンス向上がキャッシュコストを下回った時点で集約(コンバージ)させます。

高エントロピーなヒントはどのような場合に避けるべきですか?

プロダクトがおおまかな幅、フォーマット、またはデータセーバーの挙動のみを必要とする場合です。デバイスモデルのヒントはフィンガープリンティングの対象面とキャッシュディメンションを増加させるため、単に「役立つかもしれない」という理由で有効にすべきではありません。

レスポンシブプリロードが重複ダウンロードを起こしていないことをどう確認しますか?

レスポンシブプリロードをサポートしているブラウザとサポートしていないブラウザでネットワークトレースをキャプチャします。プリロードと最終的な img 要素の選択が同一の URL に解決されることを確認します。一致しない場合は、HTML の srcset のみを信頼できる単一のパスとして残します。

公開情報ソース

関連する質問