如何在十萬條數據中,實現毫秒級前端模糊搜索?
一個常見的場景是:在下拉選擇框、數據表格或搜索欄中,用戶輸入關鍵詞,系統需要從成千上萬條數據中實時篩選出匹配項。
當數據量達到10萬級別時,傳統的前端搜索方案往往會引發災難性的UI卡頓,甚至導致瀏覽器崩潰。

為何 Array.filter 會干掉我們的應用
讓我們先看看最直觀的實現方式:
// 假設我們有10萬條用戶數據
const allUsers = [
{ id: 1, name: "story", email: "story@fedjavascript.com" },
// ... 99999 more users
];
const query = 'userNameOrEmail';
// 在10萬條數據下,這個時間會非常長
const results = allUsers.filter(user =>
user.name.toLowerCase().includes(query) ||
user.email.toLowerCase().includes(query)
);這種方法的致命缺陷在于:O(n) 復雜度:每次輸入,都會完整遍歷10萬條數據,且會阻塞 UI 主線程。
從“運行時計算”到“預計算與索引”
解決性能問題的核心思想是空間換時間和預計算。在數據加載之初,就為其建立一個快速查找索引。
自己從零實現一個高效的索引和模糊匹配算法(如Trie樹、Levenshtein距離算法)是復雜且耗時的,幸運的是,社區已經有了非常成熟強大的開源庫。
以 FlexSearch.js 為例來重構上面的例子:

index.add 過程就是建立索引的預計算環節,它可能需要幾百毫秒甚至幾秒(取決于數據復雜度和設備性能),但這是一次性的投入。
現在,將 filter 替換為 index.search。
const query = 'userNameOrEmail';
// 通常在 1ms 以內!
const results = index.search(query, { limit: 100 });
// search() 返回包含文檔ID的匹配結果集,可據此從 allUsers find 數據index.search 的速度是驚人的,因為它利用了預先構建的索引,查詢耗時通常在1毫秒以內,即使是10萬條數據。
最佳實踐是將所有與FlexSearch相關的操作都放入Web Worker中,FlexSearch內置了對Worker的支持,創建索引時設置 worker 為 true 即可。
對于用戶的連續輸入,建議使用防抖確保只在用戶停止輸入一小段時間后(如200ms)才執行搜索,減少不必要的搜索。





























