迁移到 Astro 5 Content Layer 之后,我的博客构建时间从 28 秒降到了 6 秒。
不是官方宣传的数字,是我自己项目实测的。
为什么要迁移
Astro 5.0 引入了 Content Layer API,官方说构建速度提升最多 5 倍,内存使用减少 25-50%。我的博客有 90+ 篇文章,算中等规模,之前每次 astro build 要等将近半分钟。部署到 Cloudflare Pages 时,这个等待时间更明显。
旧版 content collections 的问题在于,每次构建都会把所有 Markdown 文件全部读取、解析、转换,即使你只改了一篇文章。文件一多,构建时间线性增长。
Content Layer 的改变是引入了 loader 机制,内容来源和内容使用解耦了。loader 负责从磁盘、API、CMS 拉数据,Astro 只管消费。
实际改动
改动分三步。
第一步,升级 Astro
npx @astrojs/upgrade从 4.x 升到 5.x,CLI 自动处理大部分依赖。
第二步,改 content config
旧版 src/content.config.ts,
import { defineCollection, z } from 'astro:content';
const blog = defineCollection({
type: 'content',
schema: z.object({
title: z.string(),
pubDate: z.coerce.date(),
category: z.string(),
tags: z.array(z.string()),
}),
});
export const collections = { blog };新版(Content Layer),
import { defineCollection, z } from 'astro:content';
import { glob } from 'astro/loaders';
const blog = defineCollection({
loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/blog' }),
schema: z.object({
title: z.string(),
pubDate: z.coerce.date(),
category: z.string(),
tags: z.array(z.string()),
}),
});
export const collections = { blog };核心变化,type: 'content' 换成了 loader: glob(...),显式声明内容来源。
第三步,改文章路由
旧版用 getEntryBySlug,新版用 getEntry,参数从 slug 改成了 id。这个改动会导致已有文章的 URL 变化,搜索引擎收录的都是旧 slug。
解决办法是在 loader 里自定义 generateId,
loader: glob({
pattern: '**/*.{md,mdx}',
base: './src/content/blog',
generateId: ({ entry }) => entry.replace(/\.(md|mdx)$/, ''),
})这样 id 就等于文件名(不含扩展名),和旧 slug 一致,路由不变。
踩过的坑
坑一,MDX 文件的 id 带后缀
默认情况下 glob loader 生成的 id 会包含文件扩展名。my-post.mdx 的 id 是 my-post.mdx 而不是 my-post。上面的 generateId 修复了这个问题。
坑二,render() 的导入方式变了
旧版,
import { render } from 'astro:content';
const { Content } = await render(entry);新版(Content Layer),
const { Content } = await render(entry);
// render 直接从 entry 上调用API 更简洁了,但迁移时要逐个改。
坑三,部分插件不兼容
我用的 remark-wiki-links 插件在 Astro 5 下报错,因为 Content Layer 改变了 Markdown 处理流程。需要等插件更新或者自己 fork 修。
迁移后的效果
| 指标 | 迁移前 | 迁移后 |
|---|---|---|
| 构建时间 | 28s | 6s |
| 内存峰值 | ~800MB | ~450MB |
| 文章数量 | 90+ | 90+ |
构建速度的提升比官方宣传的还大。可能是因为我的旧配置比较粗糙,迁移时顺手优化了几个地方。
值不值得迁
如果你的博客文章少于 30 篇,构建时间本来就不长,不急着迁。
如果超过 50 篇,每次部署都在等构建,强烈建议迁。5 倍的构建速度差异,积少成多,每周省下来的时间够写半篇文章了。