Pagefind:纯静态站点的全文搜索
构建期索引、客户端零请求检索——Pagefind 的工作原理、中文分词处理与构建脚本的接入方式
Pagefind:纯静态站点的全文搜索
给静态博客加搜索,传统方案是生成一个几百 KB 的 JSON 索引让浏览器下载。Pagefind 换了个思路:索引在构建期生成,切片存放,浏览器按需加载——搜索时实际下载的往往只有几十 KB。
工作原理
npx pagefind --site out构建后跑一条命令,Pagefind 扫描 out/ 里的 HTML,按页面提取内容,把倒排索引切成小块存在 /pagefind/ 目录。每个块覆盖一部分词项,用户输入查询时,客户端只加载「包含这些词」的块,按需渐进加载。文章越多,这个按需加载的优势越明显——全量索引方案是文章翻倍、下载体积翻倍,Pagefind 几乎不变。
中文分词
Pagefind 对 CJK 的支持不需要额外配置:构建期它把中文文本按字/词切分进索引,检索「静态导出」能命中包含「静态导出部署」的段落。实测两个注意点:一是混合中英文的文章,英文词按词干匹配,中文按切分匹配,两边都能查;二是标题的权重天然高于正文,把关键词放进标题对搜索排序的提升比堆在正文里大得多。
与其他方案的分工
本站现在有两套检索:Pagefind 管关键词,站内问答(RAG)管自然语言。分工标准很朴素——「我记得写过什么东西」用搜索,能精确命中关键词;「这个配置为什么这么设」用问答,需要语义理解。两者共用同一批文章,互不替代。
接入构建脚本
{
"scripts": {
"build": "next build && npx pagefind --site out"
}
}顺序必须是 next build 之后再跑 Pagefind——它索引的是构建产物而不是源码。CI 里的 E2E 因此有个隐性依赖:跑搜索断言前必须确认 Pagefind 已执行,否则 /pagefind/pagefind.js 是 404,搜索框永远转圈。
客户端接入
const pagefind = await import('/pagefind/pagefind.js');
await pagefind.search('向量检索');
// 返回结果带 excerpt 与跳转 URL动态 import 很关键:搜索框没打开前不加载任何索引代码。Pagefind 的 UI 组件可以开箱即用,但自建对话框的好处是样式与站点主题一致——本站搜索、问答两个弹窗共用一套交互范式,就是自建的理由。
性能数字
构建 12 篇文章的索引约 1 秒;/pagefind/ 目录总计约 300 KB,单次查询实际加载 20-40 KB;查询响应在低端设备上也在 10ms 量级。对比运行时搜索方案(每次请求打后端或加载全量索引),这个数字没有悬念。
基于站内文章回答,并标注引用来源
留言
加载中…