博客长到二十多篇的时候,我自己都开始找不到旧文。市面上现成的搜索服务要挂第三方脚本,搜索引擎的站点内搜索又慢半拍——干脆用纯 JS 手搓一个。本文是它的架构笔记。
整体思路:索引离线,查询在线
搜索分两半。重的一半离线做:服务器上的统计任务每 5 分钟扫描全部文章,剥掉 HTML 标签,把标题、日期、分类和正文前 4000 字写进 search-index.json。轻的一半在线做:浏览器只在第一次输入时拉取索引(约几十 KB),之后全部本地运算。
查询与打分
- 命中判定:小写化后做
indexOf,够用且零依赖; - 加权:标题命中 +10 分,正文命中 +1 分——"标题里说到"的文章几乎总是更相关;
- 摘要截取:从命中位置前 30 字开始截 80 字,关键词加
<mark>高亮,让用户不点开也能确认; - 防抖:160ms 输入防抖,连续敲键盘不会每敲一个字就跑一遍检索。
交互细节是体面所在
按 / 聚焦搜索框(学习 Vim 的肌肉记忆)、Esc 一键清空退出、搜索时隐藏文章列表避免视觉打架、清空即恢复。这些细节单看都小,合起来决定了"这个站有没有被认真对待"。
静态站做搜索的正确姿势,不是把搜索做轻,是把重活搬到构建时——浏览器只该负责最后一击。
下一步
现在的搜索是子串匹配,中文分词还欠着。等文章过百,计划升级成 2-gram 倒排索引——正好首页控制台里有现成的构建管线,加一步就能跑。搜索引擎和据点一样,先能用,再变好。