在重型框架与微服务横行的时代,搭建一个博客搜索常常意味着要跑一个 Node.js/Python 后端,甚至连接 Elasticsearch 或 Algolia 云服务。然而,当你的站点只有几百篇文章时,为什么不把全部索引交给浏览器内存?

01把计算交还给终端:200 行代码的极简主义

现代计算机和手机的浏览器引擎(V8, JavaScriptCore)处理文本的速度远超想象。对于一个拥有数百篇文章的个人知识库,全部文章的标题、摘要、标签与正文关键词序列化为 JSON 后,文件大小通常不超过 50KB(甚至小于一张压缩后的 WebP 图片)。

在页面初次加载时将其载入客户端内存,当访客敲下键盘,浏览器可以在 3 毫秒之内 完成内存数组遍历、子串打分与 DOM 渲染。没有任何网络往返(0ms Network Latency),体验如同本地原生应用。

02倒排匹配与高亮算法的核心实现

一个健壮的轻量级静态检索需要解决两个核心痛点:多关键词交集搜索(AND 逻辑)与 HTML 特殊字符安全高亮。

// 核心检索与关键词多重交集过滤
function searchPosts(posts, queryString) {
  const terms = queryString.toLowerCase().trim().split(/\s+/).filter(Boolean);
  if (!terms.length) return posts;

  return posts.filter(post => {
    const corpus = [
      post.title, post.titleEn,
      post.excerpt, post.excerptEn,
      post.keywords, post.cat
    ].join(' ').toLowerCase();

    // 所有输入的关键词片段都必须命中 (AND 逻辑)
    return terms.every(term => corpus.includes(term));
  });
}

03无障碍与极速键盘导航

瑞士风格的极客体验不仅在于视觉,更在于交互效率。本站为检索系统赋予了完整的快捷键生命周期:

  • 全局按键 /:在任何页面直接激活并聚焦搜索框。
  • 敲击 Enter:直接打开搜索结果列表的第一篇目标文章。
  • 按键 ESC:一键清空并失焦,恢复浏览流。
最优雅的架构不是能够再添加什么,而是当你剥离了所有数据库与服务器时,核心体验依旧坚不可摧。

静态搜索是本站「零依赖、无后端、永不宕机」原则的最佳实践。代码透明、双击运行、随处部署——这正是 Web 最原始也是最迷人的纯粹力量。