静态站点没有服务器端运行时,搜索功能的实现方式与动态站点有本质区别。核心问题是:索引在哪里生成,查询在哪里执行。
方案分类
构建时索引 + 客户端查询
代表方案:Pagefind、FlexSearch、MiniSearch
- 原理:构建时生成搜索索引(通常是 JSON 文件),客户端加载索引后执行查询。
- 优点:完全静态,无需外部服务,隐私友好。
- 缺点:索引文件随内容量增长而增大,首次加载可能较慢。
- 适用场景:内容量中等(几百到几千篇)、对隐私敏感、不想依赖外部服务。
外部服务索引 + API 查询
代表方案:Algolia DocSearch、MeiliSearch
- 原理:内容同步到外部服务,客户端通过 API 查询。
- 优点:搜索质量高,支持模糊匹配、同义词、权重等高级功能。
- 缺点:依赖外部服务,有成本(免费额度有限),隐私问题(内容发送到第三方)。
- 适用场景:内容量大、对搜索质量要求高、有预算。
服务端查询
代表方案:自建 Elasticsearch、SQLite FTS
- 原理:服务器端维护索引,客户端发送查询请求。
- 优点:完全控制,可定制性最高。
- 缺点:需要维护服务器,增加复杂性。
- 适用场景:有运维能力、对隐私和性能有极端要求。
本博客的选择
本博客选择 Pagefind,原因:
- 完全静态:索引在构建时生成,查询在客户端执行,无需外部服务。
- 隐私友好:搜索数据不离开用户浏览器。
- 轻量:索引文件经过压缩,对构建产物大小的影响可控。
- 易集成:与 Astro 的构建流程自然衔接。
Pagefind 的局限是搜索质量不如 Algolia 等商业服务,但对于个人博客的内容量来说完全够用。
集成要点
# 构建后生成索引
npx pagefind --site dist
在客户端加载 Pagefind:
window.addEventListener('DOMContentLoaded', async () => {
const pagefind = await import('/pagefind/pagefind.js');
await pagefind.init();
const search = await pagefind.search('关键词');
// 处理结果
});
权衡总结
| 方案 | 隐私 | 搜索质量 | 维护成本 | 适用内容量 |
|---|---|---|---|---|
| Pagefind | 高 | 中 | 低 | 中小 |
| Algolia | 低 | 高 | 中 | 大 |
| 自建服务 | 高 | 高 | 高 | 不限 |
本笔记的状态
这是一个 growing 状态的笔记。目前只覆盖了基本的方案对比,后续会补充实际集成中的性能测试数据和具体的配置细节。
评论