Next.js 静态站点生成 (SSG)
什么是静态站点生成 (SSG)?
静态站点生成(Static Site Generation,简称 SSG)是 Next.js 提供的一种预渲染策略。它允许你在构建时生成静态 HTML 文件,而不是在每次请求时动态生成页面。这些静态文件可以直接由 CDN 提供服务,从而显著提高页面加载速度和性能。
与服务器端渲染 (SSR) 不同,SSG 在构建时生成页面,因此非常适合内容不频繁变化的网站,例如博客、文档站点或产品展示页面。
为什么使用 SSG?
- 性能优化:静态文件加载速度快,减少了服务器处理时间。
- SEO 友好:预渲染的 HTML 文件可以被搜索引擎轻松抓取。
- 成本效益:静态文件可以通过 CDN 分发,减少服务器负载和成本。
- 离线支持:静态文件可以轻松缓存,支持离线访问。
如何在 Next.js 中使用 SSG?
Next.js 提供了两种方式来实现静态站点生成:
- 静态生成无数据:页面内容完全静态,不依赖外部数据。
- 静态生成带数据:页面内容依赖外部数据,数据在构建时获取并生成静态页面。
1. 静态生成无数据
如果你的页面内容是完全静态的,可以直接导出一个 React 组件,Next.js 会在构建时将其转换为静态 HTML。
// pages/about.js
export default function About() {
return (
<div>
<h1>关于我们</h1>
<p>这是一个静态生成的页面。</p>
</div>
);
}
在构建时,Next.js 会生成一个 about.html
文件,内容如下:
<div>
<h1>关于我们</h1>
<p>这是一个静态生成的页面。</p>
</div>
2. 静态生成带数据
如果你的页面需要从外部获取数据,可以使用 getStaticProps
函数。这个函数在构建时运行,并将数据作为 props 传递给页面组件。
// pages/blog/[slug].js
import fs from 'fs';
import path from 'path';
export async function getStaticProps({ params }) {
const filePath = path.join(process.cwd(), 'posts', `${params.slug}.md`);
const fileContent = fs.readFileSync(filePath, 'utf8');
return {
props: {
post: fileContent,
},
};
}
export async function getStaticPaths() {
const postsDirectory = path.join(process.cwd(), 'posts');
const filenames = fs.readdirSync(postsDirectory);
const paths = filenames.map((filename) => ({
params: { slug: filename.replace('.md', '') },
}));
return {
paths,
fallback: false,
};
}
export default function BlogPost({ post }) {
return (
<div>
<h1>博客文章</h1>
<div>{post}</div>
</div>
);
}
在这个例子中,getStaticProps
从文件系统中读取 Markdown 文件内容,并将其作为 post
prop 传递给页面组件。getStaticPaths
则用于生成所有可能的路径,以便在构建时预渲染所有页面。
fallback: false
表示如果访问的路径不存在,将返回 404 页面。你可以将其设置为 true
或 'blocking'
以启用动态生成。
实际应用场景
博客站点
静态站点生成非常适合博客站点。你可以在构建时从 Markdown 文件或 CMS 中获取所有文章内容,并生成静态页面。这样,用户访问时可以直接加载预渲染的 HTML,无需等待服务器处理。
产品展示页面
如果你的网站有大量产品页面,且产品信息不频繁更新,可以使用 SSG 预渲染所有产品页面。这样既能提高性能,又能确保搜索引擎可以抓取所有页面。
总结
静态站点生成 (SSG) 是 Next.js 中一种强大的预渲染策略,特别适合内容不频繁变化的网站。通过预渲染页面,你可以显著提高性能、优化 SEO,并降低服务器成本。
附加资源
练习
- 创建一个简单的博客站点,使用 SSG 从 Markdown 文件生成静态页面。
- 尝试将
fallback
设置为true
或'blocking'
,观察页面行为的变化。 - 使用
getStaticProps
从 API 获取数据,并生成静态页面。