Nuxt 3 个人站收录慢半拍:我把 sitemap 做成动态分片加 Redis 缓存
新文章发布后,搜索引擎总要慢半拍才收录。我把原来的大 sitemap 改成 sitemap-index 分片,再用 Redis 缓存 XML,并结合 lastmod 与主动失效,让爬虫更快发现新内容。

作者
ZHOUYI
之前最难受的是:文章已经发了,Search Console 却像没看见。排查后发现旧 sitemap 是一个大而全的静态文件,发布后不会立刻更新;就算更新了,爬虫也要等下次来抓。对个人站来说,新内容本来就少,慢半拍就很影响流量。
先把 sitemap 拆成 index 和分片
我没有继续堆一个大 sitemap,而是改成 sitemap-index:文章、标签、专题各一份分片。文章分片再按更新时间排序,只保留最近一批。这样文件小,lastmod 更明显,爬虫更容易判断该不该重抓。
Redis 缓存负责快,失效策略负责准
实现上我在 Nuxt 服务端加了几个 sitemap 路由:/sitemap.xml 返回 index,/sitemap-posts.xml 返回文章。生成逻辑从 MongoDB 查最近更新的公开文章,再交给 Redis 缓存 XML 文本。这样不用每次请求都查库,也方便后续接 CDN。
- 发布或修改文章时,更新文章的 lastmod。
- 请求 sitemap 时,先读 Redis 里的 XML 文本。
- 内容版本变化时,主动删除对应 sitemap key。
- sitemap-index 也缓存,但同样跟随分片变化刷新。
export default defineEventHandler(async (event) => {
const key = 'sitemap:posts'
const cached = await redis.get(key)
if (cached) return cached
const posts = await getRecentPosts()
const xml = renderPostsSitemap(posts)
await redis.set(key, xml, 'EX', 600)
return xml
})踩坑:别只靠过期时间
我一开始只给 Redis 设置了过期时间,结果文章改了标题或正文,sitemap 里的 lastmod 还是旧值。后来改成发布、修改、删除时主动删除对应 key,同时刷新 sitemap-index。这样缓存负责快,事件负责准。
“sitemap 不是给爬虫一份固定名单,而是告诉它:最近哪里变了。”
现在新文章发布后,我会顺手提交一次 sitemap 或 URL,剩下的交给爬虫。收录不会立刻发生,但至少链路不再拖后腿。对个人站来说,SEO 不一定靠大招,更多是把 lastmod、缓存失效和分片这些小事情做顺。