代表的な面接トピック

フロントエンド面接:アクセシブルで復元可能な無限スクロールリストの設計

フロントエンド普通
Offer.cc 編集チーム公開日 更新日

質問

無限スクロールのコンテンツリストを設計してください。ローディングがどのように開始され、重複リクエストがどのように防止され、障害からどのように復旧し、キーボードやスクリーンリーダーのユーザーがどのように操作するか、またページネーションやトップへ戻るコントロールをどのような場合に提供するかを説明してください。

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

このフロントエンドの質問では、長いリストのインタラクション状態、ネットワーク境界、およびアクセシビリティをテストします。課題は単にオブザーバーをセンチネルに接続することではなく、ローディング、キャンセル、失敗、リトライ、位置復元、および代替ナビゲーションに関する完全な規約を定義することです。

面接官が評価するポイント

  • Intersection Observerまたは同等のメカニズムでローディングをトリガーし、プリフェッチ距離を調整できるか。
  • カーソル状態、リクエストの重複排除、および順序制御によって、ページの重複、順序の不整合、無限リトライを防げるか。
  • キーボード、スクリーンリーダー、拡大ズーム、低速ネットワークのユーザーに対して、可視で操作可能な状態が提供されているか。
  • 無限スクロールにページネーション、コンテンツへのスキップパス、または位置復元が必要なタイミングを認識できているか。

尋ねるべき明確化のための質問

リストがタイムライン、検索結果、グリッドのいずれであるか、順序が安定しているか、サーバーがカーソルを発行できるか、ページサイズとファーストコンテンツターゲットについて確認します。ディープリンク、戻るナビゲーションでの復元、動的なコンテンツの高さ、モバイルデータの制約について質問します。

30秒の回答フレームワーク

安定したカーソルベースのページネーションと、削除可能なローディングセンチネルを使用します。アクティブなリクエストがなく、次のカーソルが存在し、センチネルがプリフェッチウィンドウに入った場合にのみロードします。順序を維持しながらカーソルとアイテムidで重複排除を行います。ローディング、失敗、リトライ、リスト末尾の状態はフォーカス可能かつ可視にします。また、スクロールが唯一のナビゲーション方法にならないよう、明確なページネーションまたは「さらに読み込む」パス、コンテンツへのスキップ、位置復元を提供します。

ステップバイステップの詳細解説

1. データと位置の規約を定義する

新規レコードによってシフトしないカーソルを優先します。次のカーソルと安定したアイテムidを返します。挿入後にページ番号によってアイテムが重複したりスキップされたりしないよう、既知のカーソル、確認済みid、リクエスト状態をクライアント側で保持します。別のページへ遷移する際は、ルート、カーソル、アンカーオフセットを記録し、データの準備ができた段階で表示されていたアイテムを復元します。

2. トリガーと並行性制御を設計する

Intersection Observerは「下部付近にある」というシグナルを発行するだけであり、無制限のフェッチを許可するものではありません。ロード前に、hasNextloading、リトライバジェット、およびネットワーク状態を確認します。カーソルごとに1つのリクエストを許可します。アイテムの高さとレイテンシを使用してプリフェッチのしきい値を調整し、高速スクロール用の明示的なボタンを用意して、オブザーバーのコールバックの連続実行によってバーストが発生しないようにします。

3. レスポンス、キャンセル、および失敗の処理

レスポンスが期待されるカーソルに属していることを検証します。遅れて届いたレスポンスを無差別に末尾に追加するのではなく、破棄するか既知のセットにマージします。ページから離脱した場合は、レンダリング済みデータをクリアすることなくアクティブなリクエストをキャンセルできます。失敗状態では問題を説明し、リトライボタンを公開し、読み込み済み件数を表示します。自動リトライには制限付きの指数バックオフを使用し、障害発生時のリクエスト集中を防ぎます。

4. アクセシブルな代替パスを提供する

センチネルを唯一のコントロールにしてはなりません。フォーカス可能な「さらに読み込む」、明示的なローディングおよびリスト末尾のアナウンス、セマンティックなリストマークアップ、安定した見出し、視認可能なフォーカスを提供します。長いリストにはページネーション、重複スキップパス、「リストの先頭へ戻る」リンクを公開できます。フォーカス移動にはルールが必要です。ノードの挿入によってキーボードユーザーが末尾に飛ばされてはなりません。

5. パフォーマンス、ユーザビリティ、および復元の検証

TabキーとEnterキーのみで複数ページの読み込みをテストし、スクリーンリーダーが新しいコンテンツや失敗を認識できるか検証します。低速ネットワーク、オフラインモード、高速スクロール、連続実行、戻る/進むナビゲーション、200%のズーム、動的な画像の高さを検証します。リクエスト数、重複率、初回ページおよびページごとのレイテンシ、キャンセル、復元の成功率を測定します。仮想化(バーチャライゼーション)が必要な場合は、セマンティクスとフォーカスが保持されているか検証します。

優れた回答例

リストを安定したカーソルとアイテムidに基づいて構築し、処理済みカーソル、確認済みid、アクティブなリクエスト、リトライ回数をクライアント状態で管理します。センチネルはプリフェッチウィンドウ内で1回のロードシグナルを発行します。レスポンスは現在のカーソルと一致する必要があり、重複または順序が崩れたアイテムは削除されます。失敗時にはフォーカス可能なリトライコントロールを表示し、オフラインモードでは読み込み済みコンテンツを保持します。無限スクロールと並行して、「さらに読み込む」、ページネーション、またはジャンプコントロールを提供し、キーボードやスクリーンリーダーのユーザーがスクロールホイールに依存しないようにします。戻るナビゲーションではアイテムアンカーを復元します。低速およびオフラインネットワーク、高速スクロール、ズーム、戻る/進む、スクリーンリーダーで動作を検証します。

よくある間違い

  • 挿入後の重複や欠落を考慮せずにページ番号を追加する。
  • カーソルの重複排除やインフライトロックなしで、オブザーバーのコールバックごとにリクエストを開始する。
  • 無限にリトライする、またはフォーカスを受け取れないテキストとしてリトライをレンダリングする。
  • キーボードによる読み込み、ページネーション、戻るパスを用意せず、スクロールを唯一のナビゲーションにする。
  • 新しいノードが届いたときにフォーカスを末尾に移動させ、リーダーの現在位置を失わせる。
  • 高速なデスクトップ接続環境でのみテストし、オフラインモード、ズーム、動的な高さ、復元を無視する。

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

なぜページ番号によるページネーションを使用しないのですか?

レコードが挿入または削除されると、ページの境界が移動します。安定した順序付けとカーソルを組み合わせることで、重複や欠落が減少します。スナップショットが許容される場合は、スナップショットトークンによって1つのブラウジング境界を定義できます。

発火が早すぎるセンチネルはどのように調整しますか?

平均アイテムの高さ、スクロール速度、ネットワークレイテンシ、キャンセル率からroot marginを調整し、観測可能にします。プリフェッチはhasNext、並行性ロック、およびリトライバジェットによって制限された状態を維持します。

上部に新しいアイテムが届いた場合、どのように位置を保持しますか?

アンカーアイテムとその相対オフセットを記録し、新しいノードを挿入してスクロールオフセットを補正します。スクリーンリーダーやキーボードのユーザー向けには、「新しいアイテム」コントロールを公開し、ジャンプするタイミングをユーザー自身が選択できるようにします。

どのような場合にページネーション設計に移行すべきですか?

ディープリンク、正確なページジャンプ、結果の比較、非常に長いリスト、または明確な閲覧セクションが重要な場合にページネーションを使用します。プログレッシブローディングを維持することは可能ですが、目に見えるページネーションまたは「さらに読み込む」パスが存在している必要があります。

公開情報ソース

関連する質問