😸
【DAY26】リアルタイム検索を導入してわかった、便利さと重さのバランス
【DAY26】リアルタイム検索を導入してわかった、便利さと重さのバランス
こんにちは、Keisukeです。
今日は、最近実装した「リアルタイム検索」機能について、その技術的背景や課題、そして改善ポイントを記録しておきます。
🔍 きっかけは「入力中でも結果が欲しい」という声
これまでの検索機能は、「検索ボタンを押したらデータ一覧が出る」という仕組みでした。
しかし、実際に自分で使っていて、「入力しながら即座に検索結果が出てきたら便利だな」と感じる場面が増え、リアルタイム検索の実装に踏み切りました。
🛠 技術的な実装方法(Firebase + JavaScript)
リアルタイム検索の基本的な流れは以下のようになります。
-
input
イベントでユーザーの入力を取得 - 入力が変わるたびに、Firestoreからデータを再取得
- 検索結果を表示するDOMを更新
コード例は以下のような感じです:
document.getElementById("search").addEventListener("input", async (e) => {
const keyword = e.target.value.trim();
if (keyword.length === 0) return;
const querySnapshot = await getDocs(collection(db, "items"));
const filtered = querySnapshot.docs.filter(doc =>
doc.data().title.includes(keyword)
);
displayResults(filtered);
});
シンプルな構造ですが、入力のたびに全データを読み込むと、非常に重くなります。
特にデータ量が多くなってくると、検索ごとに何百件も取得するのは現実的ではありません。
⚠️ 課題:便利すぎると重くなる
最初は「入力するたびに即座に結果が出て最高!」と思っていたのですが、試していくうちに問題が発覚。
- 1文字入力するたびにFirestoreへアクセス
- データ数が100件を超えると処理がワンテンポ遅れる
- モバイル環境では体感でラグを感じることも
つまり、「便利だけど、重い」というジレンマにぶつかりました。
🧠 解決策:デバウンスとローカルキャッシュ
そこで、次のような対策を取りました:
✅ デバウンス処理(入力から300ms待つ)
let timeout;
document.getElementById("search").addEventListener("input", (e) => {
clearTimeout(timeout);
timeout = setTimeout(() => {
performSearch(e.target.value.trim());
}, 300);
});
これにより、「連続したタイピング中の無駄なリクエスト」を防げます。
✅ 一度取得したデータをローカルに保存
起動時にFirestoreから全データを一度だけ取得し、以後はローカルでフィルタリングする形に変更。
検索精度とパフォーマンスの両立が可能になりました。
💬 結果:UX向上と負荷軽減の両立に成功
今では、1文字ずつ入力してもストレスなく検索結果が表示され、かつFirestoreへのアクセスも最小限になりました。
リアルタイム検索は、見た目以上に裏側の工夫が必要な機能です。
「使って気持ちいい体験」を技術で裏から支えることの大切さを、今回の実装を通じて改めて感じました。
ということで、DAY26は「リアルタイム検索の技術とその最適化」についての記録でした。
Discussion