Pagefind

专为静态站点(SSG)设计的开源全文搜索引擎,基于 Rust 构建,利用倒排索引和索引分片实现极低带宽的客户端搜索。

#type / resource #status / growing #tech / dev / frontend #resource / pagefind #media / tool

[!info] related notes

Pagefind

这是什么

Pagefind 是一款专为静态站点生成器(SSG)设计的开源全文搜索引擎。

它用 Rust 编写,以 CLI 工具的形式在站点构建完成后运行,扫描所有生成的 HTML 文件,产出一组静态搜索索引文件。用户在前端页面中搜索时,浏览器直接读取这些索引文件完成检索,完全不需要后端服务。

官方仓库:pagefind on GitHub

适用平台 / 适用场景

Pagefind 可以和任何 SSG 框架搭配使用,不要求特定集成插件:

  • Hugo、Astro、Eleventy、Jekyll、Hexo、Docusaurus 等均可直接接入
  • 输出是纯静态文件,可部署到任何静态托管服务(Cloudflare Pages、Vercel、Netlify、GitHub Pages)
  • 最适合内容型网站:文档站、博客、知识库、个人数字花园

核心特点 / 优势 / 局限

完全静态,零服务端成本

搜索逻辑全部运行在浏览器中。索引在构建阶段由 Rust CLI 预先生成,以静态文件形式随站点一起部署。不需要 Algolia 之类的付费搜索 API,也不需要运行搜索服务端。

极低带宽占用——索引分片架构

Pagefind 没有把所有索引数据塞进一个大文件,而是将倒排索引按词条范围切分成几百个极小的分片文件。浏览器搜索时只下载命中的那一个分片,首屏搜索加载可以控制在几十 KB 以内。

异步懒加载结果数据

搜索返回的结果对象默认只包含页面 ID 和排名信息,不包含标题和摘要正文。当页面真正要渲染搜索结果卡片时,再调用 result.data() 按需拉取该页面的精简摘要。用户查什么,就只下载什么。

搜索性能优秀

因为索引是构建时预建好的,浏览器端搜索只做轻量的索引分片查找,不需要在前端遍历全站数据。对几千页规模的站点,搜索响应通常在 10ms 以内。

自带 UI 组件

Pagefind 提供了一个开箱即用的 Web Component(<pagefind-ui>),可以直接嵌入到任何 HTML 页面中,不需要额外的前端框架适配。也可以只用它的 JS API 自行构建搜索界面。

常见用途

典型工作流

  1. SSG 构建命令生成静态 HTML(例如 pnpm build
  2. 运行 npx pagefind --site dist(指定构建输出目录)
  3. Pagefind 扫描所有 HTML,在 dist/pagefind/ 下生成索引文件
  4. 部署时这些索引文件随站点一起上传到 CDN

在 Astro 项目中的集成经验

在 Astro 项目中使用 Pagefind 时,推荐在客户端用动态导入的方式加载:

// 当用户在搜索框输入时,动态拉取并初始化 pagefind
let pagefind;
inputElement.addEventListener('input', async (e) => {
  if (!pagefind) {
    pagefind = await import('/pagefind/pagefind.js');
    await pagefind.init();
  }
  const queryValue = e.target.value;
  if (queryValue.length > 0) {
    const search = await pagefind.search(queryValue);
    // 遍历结果,按需拉取每篇文章的摘要
    for (const result of search.results) {
      const data = await result.data();
      // 用 data.meta.title、data.excerpt 等渲染卡片
    }
  }
});

开发环境的降级处理

Pagefind 必须先构建(pnpm build)出静态页面后才能建立索引。本地开发运行 pnpm dev 时,/pagefind/pagefind.js 不存在,搜索会报错。

推荐的处理方式是做错误拦截和优雅降级:

  • import('/pagefind/pagefind.js') 外包一层 try...catch
  • 捕获异常后,在页面上展示一条友好提示(比如橙色提示框告知”开发环境下搜索不可用”)
  • 降级为只搜索常驻的本地数据(如 Homelab 资产列表),保证开发其他页面时不受影响

与全量序列化方案的对比

很多 SSG 项目的搜索功能最初采用”全量序列化”方案:在构建时把所有文章的标题、标签、摘要序列化成一个大 JSON 数组,直接内联到 HTML 的 <script> 标签中。浏览器加载后,用 array.filter(...) 在前端做全量循环匹配。

这种方案在笔记数量少时没有问题,但当内容规模增长到几千篇时,问题就会暴露:HTML 文件体积暴增(可能达到数百 KB),每次打开搜索页都要下载和解析全量数据,移动端设备可能出现明显卡顿。

Pagefind 的方案从架构层面解决了这个问题:Rust 预建索引 + 浏览器按需拉取分片 + 结果数据懒加载,让搜索页的初始加载体积从数百 KB 降到几十 KB,搜索响应也从前端的 O(n) 遍历变成了索引级别的 O(1) 查找。

相关链接 / 官方入口

  • 官方文档:pagefind.app
  • GitHub 仓库:CloudCannon/pagefind
  • 同类工具对比:Algolia DocSearch(需要服务端 API)、Lunr.js(全量加载,无分片)、FlexSearch(内存索引,无静态分片)
创建于 2026/6/21 更新于 2026/6/21