TL;DR

5种博客搜索方案对比结果:Pagefind 是 Astro 博客的最佳选择—零配置自动索引、搜索速度 <50ms、免费、离线可用。Algolia 适合超大型站点,Lunr.js 适合需要深度定制场景。

评估维度

维度权重说明
集成难度20%接入需要多少代码和配置
搜索速度25%用户输入到结果返回延迟
索引大小15%索引文件对构建产物体积影响
构建开销15%索引生成是否显著增加构建时间
成本15%是否有免费额度、超出后价格
功能完整度10%分词、高亮、过滤、排序

五种方案概览

1. Pagefind

静态站点专用搜索工具,构建后自动从 HTML 中提取索引。

# 安装
npm install pagefind

# 构建后运行索引
npx pagefind --site dist

生成的索引文件放在 dist/pagefind/,客户端加载即可。

2. Lunr.js

纯 JavaScript 全文搜索引擎,在浏览器中运行。

import lunr from 'lunr';

const index = lunr(function() {
  this.field('title', { boost: 10 });
  this.field('content');
  posts.forEach(post => this.add(post));
});

需要自己生成索引 JSON,构建时运行脚本。

3. Fuse.js

模糊搜索引擎,不需要预处理索引。

import Fuse from 'fuse.js';
const fuse = new Fuse(posts, { keys: ['title', 'content'] });

每次搜索时实时计算相似度,不需要预建索引。

4. Algolia DocSearch

第三方搜索服务,免费版面向开源文档站点。

需要申请:docsearch.algolia.com

5. Astro 内置搜索

Astro 没有内置搜索,但可以配合 @astrojs/sitemap + 自建搜索页面实现简单标题匹配。

对比数据

集成难度

方案代码量配置复杂度Astro 适配
Pagefind30 行低(1条命令)官方集成
Lunr.js80 行中(需写索引脚本)手动
Fuse.js40 行低(无预处理)手动
Algolia60 行中(需申请+配置)社区集成
自建100+ 行手动

搜索速度(100 篇文章)

方案首次加载搜索延迟
Pagefind150ms(索引分片加载)<30ms
Lunr.js300ms(全量索引)<50ms
Fuse.js0ms(无索引)200-500ms
Algolia50ms(CDN)100-200ms(网络)
自建200ms50-100ms

索引大小

方案100 篇500 篇1000 篇
Pagefind200KB800KB1.5MB
Lunr.js500KB2.5MB5MB
Fuse.js1MB(原始数据)5MB10MB
Algolia0(云端)00
自建300KB1.5MB3MB

Pagefind 索引最小,因为它做了分片和压缩。Lunr.js 索引包含完整词频表,体积较大。Fuse.js 不建索引,但搜索时需要加载全量数据。

构建开销

方案100 篇500 篇1000 篇
Pagefind+1s+3s+6s
Lunr.js+2s+8s+15s
Fuse.js000
Algolia+5s(推送)+20s+40s
自建+1s+5s+10s

成本

方案免费额度超出价格
Pagefind完全免费
Lunr.js完全免费
Fuse.js完全免费
Algolia DocSearch免费(开源项目)N/A
Algolia Standard10K 次搜索/月$0.006/次
自建服务器成本按服务器

推荐方案

100 篇以下:Pagefind

# astro.config.mjs
import pagefind from 'astro-pagefind';

export default defineConfig({
  integrations: [pagefind()],
});

零配置,构建后自动生成索引,搜索 UI 自动注入。

100-500 篇:Pagefind + 分片

Pagefind 自动分片,500 篇以下体验无差别。

500 篇以上:Algolia

文章多时,客户端索引体积大(>2MB),影响首屏加载。Algolia 把索引放在云端,不受文章数量影响。

需要深度定制:Lunr.js

如果你想控制分词规则、停用词、同义词扩展,Lunr.js 提供最灵活 API。

Pagefind 快速接入

npm install astro-pagefind
// astro.config.mjs
import pagefind from 'astro-pagefind';
export default defineConfig({
  integrations: [pagefind()],
});

构建后,在需要搜索页面添加:

<div id="search"></div>
<button id="search-btn">搜索</button>

<script is:inline>
  window.addEventListener('DOMContentLoaded', () => {
    const btn = document.getElementById('search-btn');
    btn.addEventListener('click', async () => {
      // 动态加载 Pagefind UI
      const css = document.createElement('link');
      css.rel = 'stylesheet';
      css.href = '/pagefind/pagefind-ui.css';
      document.head.appendChild(css);
      
      const js = document.createElement('script');
      js.src = '/pagefind/pagefind-ui.js';
      js.onload = () => {
        new PagefindUI({ element: '#search', showSubResults: true });
      };
      document.head.appendChild(js);
    });
  });
</script>

Trade-offs

方案最大优点最大缺点
Pagefind零配置、速度快中文分词不够精确
Lunr.js高度可定制索引体积大
Fuse.js无需预处理搜索慢、数据全暴露
Algolia专业级搜索依赖第三方、有成本

写在

对于 Astro 博客,Pagefind 是 90% 场景的最佳选择。只有在文章量超大(500+)或需要专业级搜索体验时,才需要考虑 Algolia。

中文分词是所有客户端方案弱项。如果你博客中文内容为主,考虑在 Pagefind 基础上添加自定义分词器。

延伸阅读

种下你的想法

在花园里留下一条评论,和这篇文章一起生长。

COMMENTS