フォームの値をリアルタイムに取得して、検索結果を表示する実装した際にハマったポイント
こんにちは。エンジニアのmasuzakaです。
とある案件でJavaScriptでフォームの値をリアルタイムに取得し、その値を用いて検索結果を表示する機能を作成しました。
その際にハマったポイントを共有します。
目次
・アウトプット
・ハマったポイント
・短期間に呼び出されるinputイベントの処理の捌き方
アウトプット
今回実装したのは、下記のような検索ボックスに文字を入力するたびに、部分一致するワードを絞り込んで検索結果を表示するという機能です。(ここでは説明のためにHarry Potter APIを使用して、同じようにレスポンスの結果を絞り込みするサンプルを作成してします。)
See the Pen ブログ用 by 増坂航 (@fsrrytdx-the-sans) on CodePen.
このような流れで処理をしています。
1.ユーザーが検索ボックスに文字を入力
↓
2.addEventListenerのinputイベントが発火し処理がスタート
↓
3.検索対象のデータ情報が記載されているJSONをJavaScriptのfetchで読み込む
↓
4.JSONから部分一致で絞り込みをする
↓
5.絞り込み結果をappendChildで追加する
ハマったポイント
inputイベントはフォーム( input 要素)や選択メニュー( select 要素 )、テキストエリア( textarea 要素)にてユーザーの操作によって値が変更されたときに発生するイベントです。
PCのタイピングが速いユーザーが利用した場合、検索キーワードを入力するまでにかなりの量の処理が走ってしまいます。
そのように高速でタイピングした場合、レスポンスが競合してしまい、同じ検索結果がレンダリングされてしまう事象が発生することがありました。
例えば下記のような感じです。(これは対応策を入れる前のRonというテキストを高速で入力した場合の検索結果です)
このようにならないようにするために、短期間に呼び出されるinputイベントの捌き方を工夫する必要がありました。
短期間に呼び出されるinputイベントの処理の捌き方
今回の対応では、デバウンスという仕組みをJavaScriptに組み込んで解決しました。
デバウンスとは、特定の処理が高頻度で呼び出されるのを防ぐテクニックの1つです。
任意の時間(デバウンスタイム)を設定してその時間が経過するまで処理の時間を遅延させることができます。
デバウンスタイム中に処理が呼び出されるとタイマーはリセットされ、処理の実行を遅延します。
プログラムにすると下記のようになりました。
See the Pen ブログ用 by 増坂航 (@fsrrytdx-the-sans) on CodePen.
ここではデバウンスタイムを1秒に設定してあります。
ユーザーが検索ボックスに値を入力してからinputイベントによる処理をするまでに、1秒間の猶予を設定しています。
適切なデバウンスタイムを設定することにより、検索結果が重複してレンダリングされることを防ぐことができました。
しかし、入力してから少なくとも1秒間は検索結果のレンダリングが始まらないので、ユーザーがブラウザ上で即座にフィードバックを受けることができず、ユーザー体験を低下させることにもなります。
短すぎるとデバウンスの効果が薄れ、長すぎるとレスポンスが遅くなり、ユーザー体験を低下させます。
試行錯誤をして適切なデバウンスタイムを設定しましょう。
関連記事
お仕事のご相談、採用についてなど、お気軽にお問い合わせください。