業務でインクリメンタルサーチ機能を実装することになったので、方針を検討しました。実装の際に考慮すべきことを、備忘録としてまとめます。
最後まで読めばインクリメンタルサーチ機能の実装方針や考慮すべき観点を理解できるかなと思います。
インクリメンタルサーチ機能の2つの実装方針
インクリメンタルサーチ機能の実装方針として大きく以下の2つがあります。
- フィールドにテキストが入力される都度、APIを叩いて検索結果を取得する
- あらかじめ検索候補を全件取得しておき、テキストの入力に応じてフロントエンド側でフィルタリング処理をする
それぞれ以下のメリット・デメリットがあると考えました。
1. フィールドにテキストが入力される都度、APIを叩いて検索結果を取得する
メリットとしては以下の2つが考えられます。
- 初期表示時点でのデータ取得が不要なので画面をロードする速度が速い
- 最新のデータを取得できる
フィールドにテキストが入力されるまではAPIを叩いたりしないため、画面の初期読み込み時に余計な処理が含まれません。そのため相対的に表示速度は速くなります。また最新のデータから検索できるためリアルタイム性にも優れているのがこの方針です。
一方で以下のデメリットがあります。
- 入力の都度APIを叩くためサーバへの負荷も大きい
- サーバと通信するため検索結果をスピーディに提示できずユーザ体験で劣る
1文字でも入力・削除するたびにAPIを叩いてしまうため、リクエストの頻度が増えてしまいます。結果的にサーバへの負荷の増大やレスポンス遅延に起因してユーザ体験の劣化につながってしまいます。
2. あらかじめ検索候補を全件取得しておき、テキストの入力に応じてフロントエンド側でフィルタリング処理をする
あらかじめ検索候補を全件取得する方針には以下のメリットがあります。
- テキスト入力の都度サーバへリクエストを送る必要がないため、レスポンスが速い
1の方針とは異なりAPIを叩くのは最初の1回だけです。テキストを入力する度にいちいちサーバを介さずに済むためレスポンスが速いです。結果的にユーザ体験の向上につながります。
もちろん以下のようなデメリットもあります。
- 最初に全データを取得するため画面の初期読み込みに時間がかかる恐れ
- 最新のデータを反映できない
検索対象のデータの件数によっては最初に全件を取得してしまうと画面の初期ロードに時間がかかってしまう恐れがあります。また一度画面を表示した後で検索対象のデータが更新されてしまった場合、画面をリロードしないと最新のデータを反映できません。
方針を選択する観点
上記の2方針のどちらを採用するか検討するには以下の観点を考えましょう。
- 検索対象のデータの件数は多いか少ないか?
- データのリアルタイム性にこだわる必要があるか?
検索対象のデータが膨大な場合、2の方針だと画面の初期ロードにすごく時間がかかってしまうため、1を採用した方が良いです。またデータのリアルタイム性にこだわる必要がある場合も1を採用すべきです。検索対象のデータが少なく、リアルタイム性をそこまで重視する必要がない・あるいはそもそも頻繁にはデータが更新されない場合は2の方針が良いのかなと思います。
なお今回の業務では検索対象のデータが85件と少なく将来的に爆発的に増える見込みではないこと、マスタデータのため更新の頻度が少ないことを理由に方針2を採用しました。
発展:デバウンスとスロットリング
方針1の「入力の都度APIを叩く」だとリクエストの回数が多いためサーバへの負荷も増大してしまうと話しましたが、この問題を解消するアプローチとしてデバウンスとスロットリングがあります。どちらもリクエストの回数を制限し、パフォーマンスを向上させるためのテクニックです。
デバウンスとは
デバウンスはイベント(マウスのクリックなど)がトリガーされた後、指定した時間が経過するまでイベントハンドラー(イベントに対して実行される関数)の実行を遅延させるテクニックです。指定された時間内に同じイベントが再度トリガーされた場合、タイマーはリセットされ、また待機時間が開始されます。
たとえばユーザが検索フィールドにテキストを入力しているとき、入力の都度APIリクエストを送信するのではなく、ユーザが一定時間(500ミリ秒など)入力を止めた時点でリクエストを送信します。これにより不要なリクエストを減らしてパフォーマンスを向上させられます。
デバウンスは「停止するまで待つ」アプローチだと言えます。
スロットリング
スロットリングはイベントがトリガーされる頻度を減らすテクニックです。「最小の待機時間」を指定することで、この時間が経過するまで次のイベントは無視されます。
たとえばユーザが検索フィールドにテキストを入力しているとき、どんなに速くタイプしたとしてもスロットリングに設定した時間間隔(300ミリ秒など)でしかリクエストを送信しません。これにより不要なリクエストを減らしてパフォーマンスを向上させられます。
スロットリングは「一定間隔で処理する」アプローチだと言えます。
まとめ
インクリメンタルサーチ機能の実装には、データの件数とリアルタイム性を考慮して方針を選択する必要があると学びました。また今回の業務では考慮しませんでしたが、デバウンスやスロットリングなどより高度なテクニックへの理解も深められました。
コメント