1. 概述與需求分析
- 功能:在網頁中實時搜索用戶代碼、關鍵字;展示匹配行、文件名;支持高亮、正則、模糊匹配。
- 非功能:大文件集(幾十萬行)、高并發、響應 <100ms;支持增量索引和熱更新。
2. 系統架構與技術選型
- 前端:HTML5 + Vue/React + Web Worker
- 客戶端索引:Fuse.js 或 Lunr.js(輕量、可打包到瀏覽器)
- 后端(可選):Node.js + Elasticlunr 或 Elasticsearch;提供 RESTful 搜索 API
- 通信:Fetch/axios + debounce(防抖)
- 存儲:JSON 索引文件或輕量 KV(Redis)
系統架構示意:
┌───────┐ ┌──────────┐ ┌────────────┐
│ 瀏覽器 │←Fetch→│ Node.js │←→ │ Elasticsearch │
│ React │ │ API 層 │ │ /Elasticlunr│
└───────┘ └──────────┘ └────────────┘↑│└─Web Worker + Fuse.js/Lunr.js
3. 前端實現(UI + 交互)
- 基礎 UI
- 輸入框
<input>
+ 清空按鈕 - 結果列表
<ul><li>
:文件名、行號、代碼片段
- 輸入框
- 防抖處理
function debounce(fn, delay = 200) {let timer;return (...args) => {clearTimeout(timer);timer = setTimeout(() => fn(...args), delay);}; } // 用法: inputEl.addEventListener('input', debounce(onSearch, 300));
- Web Worker 異步搜索
- 主線程啟動 Worker,把查詢詞和索引數據傳入
- Worker 內部執行 Fuse.js 或 Lunr.js 的
search()
,回傳結果 - 渲染高亮:用正則替換
<mark>
// worker.js
importScripts('https://unpkg.com/fuse.js');
let fuse;
self.onmessage = ({ data }) => {if (data.type === 'init') {fuse = new Fuse(data.list, data.options);} else if (data.type === 'query') {const results = fuse.search(data.keyword);self.postMessage({ results });}
};
// main.js
const worker = new Worker('worker.js');
worker.postMessage({ type: 'init', list: fileList, options: fuseOptions });
worker.onmessage = ({ data }) => {renderResults(data.results);
};
4. 索引與搜索算法
- 倒排索引 vs 文本搜索庫
- 倒排索引:手寫維護每個詞→行號列表,優勢可控,復雜度 O(k + m)
- Fuse.js:基于 n-gram 矩陣,支持模糊、權重
- 配置示例(Fuse.js)
const options = {includeMatches: true,threshold: 0.3,keys: ['content'],getFn: (obj, path) => obj[path], }; const fuse = new Fuse(docs, options);
- 正則與精準匹配
- 對于“以 XXX 開頭”或“全詞匹配”,可在結果基礎上用
RegExp
二次過濾,提高精度。
- 對于“以 XXX 開頭”或“全詞匹配”,可在結果基礎上用
5. 服務端設計與 API
- RESTful 接口
GET /api/search?keyword=foo&page=1&pageSize=20
- 分頁與限流
page
、pageSize
控制結果量- 后端可對熱門關鍵詞(熱詞)做緩存
- 增量索引
- 當倉庫文件變更時(Webhook),觸發后臺進程更新索引。
6. 性能優化與緩存策略
- 客戶端:
- 緩存上次查詢結果、重復關鍵詞快速返回
- Web Worker 復用、避免頻繁初始化
- 服務端:
- Redis 緩存熱門搜索
- Elasticsearch 分片與 replica 調優
- 算法層面:
- 預先分詞(前綴樹、n-gram)
- 按文件分組并行搜索,異步合并
7. 高級功能拓展
- 語法感知
- 用 Tree?sitter/CodeMirror 解析 AST,按標識符級別搜索
- 跨語言支持
- 不同語言代碼分索引,關鍵詞加語言標簽
- 結果聚合
- 統計關鍵詞出現次數、文件熱度排序
- UI 增強
- 上下文折疊/展開、跳轉到文件行號
8. 復雜度分析
- 假設文檔集總詞數 N,查詢詞長 k:
- 倒排索引檢索:O(k + R),R 為匹配行數
- Fuse.js(模糊匹配):預處理 O(N·L)(L 平均詞長);單次查詢 O(N)
- 并行分片搜索能將查詢時間近似縮短到 O(N/P),P 為分片數
9. 安全與可維護性
- 輸入校驗:禁止任意正則注入,限制關鍵詞長度/字符集
- XSS 防護:高亮時對用戶輸入轉義再插
<mark>
- 代碼組織:
- 按模塊拆分:UI、Worker、API 客戶端、緩存
- 單元測試:模擬搜索結果、重構時保證穩定性