pin_drop当前位置:知识文库 ❯ 图文

框架集成:23 SSG静态生成与HTML - 详细教程与实战指南

一、教程简介

静态站点生成(SSG)是在构建时预渲染所有页面为静态HTML文件的技术。与SSR每次请求都渲染不同,SSG只在构建时渲染一次,生成的HTML文件可以直接部署到CDN,访问速度极快。本教程将介绍SSG原理、Next.js SSG/ISR、Nuxt Generate、Astro框架、静态生成的优势、增量静态再生(ISR)以及混合渲染策略。


二、核心概念

SSG原理与优势

特性 CSR SSR SSG
渲染时机 浏览器 每次请求 构建时
HTML内容 空壳 完整 完整
服务器负载
CDN缓存 可以 有限 完美
首屏速度 最快
SEO
实时数据 支持 支持 需客户端获取
构建时间 页面多时较长
适用场景 工具/后台 动态内容 博客/文档/营销

SSG的核心优势:构建时生成静态HTML,可以直接部署到CDN,访问速度最快,服务器负载为零,SEO友好。适合内容不频繁变化的页面,如博客、文档、营销页面、产品目录等。


三、各框架SSG实现

Next.js SSG / ISR

代码示例

// Next.js App Router - 静态生成

// 1. 默认静态生成(无动态数据)
// app/about/page.tsx
export default function AboutPage() {
  return <h1>关于我们</h1>;
}
// 构建时自动生成静态HTML

// 2. 带数据的静态生成
// app/posts/[id]/page.tsx
export default async function PostPage({ params }) {
  const post = await getPost(params.id);
  return <article>{post.content}</article>;
}

// 生成静态路径
export async function generateStaticParams() {
  const posts = await getPosts();
  return posts.map(post => ({ id: String(post.id) }));
}

// 3. ISR - 增量静态再生
// 设置revalidation时间
async function getPost(id) {
  const res = await fetch(`https://api.example.com/posts/${id}`, {
    next: { revalidate: 60 }  // 60秒后重新验证
  });
  return res.json();
}

// 4. On-demand Revalidation(按需重新验证)
// app/api/revalidate/route.ts
import { revalidatePath, revalidateTag } from 'next/cache';

export async function POST(request) {
  const path = request.nextUrl.searchParams.get('path');
  if (path) {
    revalidatePath(path);  // 重新验证指定路径
    return Response.json({ revalidated: true, now: Date.now() });
  }
  return Response.json({ revalidated: false });
}

// 5. 静态导出(完全静态站点)
// next.config.js
module.exports = {
  output: 'export',  // 生成纯静态站点
  images: { unoptimized: true },  // 禁用图片优化
};

Nuxt Generate与Astro

代码示例

// Nuxt.js 静态生成
// nuxt.config.ts
export default defineNuxtConfig({
  // 预渲染所有路由
  nitro: {
    prerender: {
      crawlLinks: true,     // 自动爬取链接
      routes: ['/sitemap.xml'],  // 额外路由
    }
  }
});

// 运行静态生成
// npx nuxi generate

// 混合渲染
// nuxt.config.ts
export default defineNuxtConfig({
  routeRules: {
    '/': { prerender: true },        // SSG
    '/blog/**': { swr: 3600 },       // ISR(1小时)
    '/admin/**': { ssr: false },      // CSR
    '/api/**': { cors: true },        // API
  }
});

// ================================
// Astro - 内容优先的静态站点框架
// src/pages/index.astro
---
import Layout from '../layouts/Layout.astro';
const posts = await Astro.glob('./blog/*.md');
---
<Layout title="首页">
  <h1>博客文章</h1>
  {posts.map(post => (
    <article>
      <h2><a href={post.url}>{post.frontmatter.title}</a></h2>
      <p>{post.frontmatter.description}</p>
    </article>
  ))}
</Layout>

// Astro的核心优势:
// 1. 零JavaScript默认 - 不发送JS到客户端
// 2. Islands Architecture - 选择性hydration
// 3. 支持多框架组件
//    import ReactComponent from './Component.jsx';
//    import VueComponent from './Component.vue';
//    import SvelteComponent from './Component.svelte';

// Islands Architecture(岛屿架构)
<Layout>
  <!-- 静态HTML,无JS -->
  <h1>文章标题</h1>
  <p>文章内容...</p>

  <!-- 交互岛屿:只有这部分发送JS -->
  <ReactComponent client:load />
  <VueComponent client:visible />
  <SvelteComponent client:idle />
</Layout>

// client:指令
// client:load     - 页面加载时hydration
// client:visible  - 可见时hydration
// client:idle     - 浏览器空闲时hydration
// client:media    - 匹配媒体查询时hydration
// client:only     - 只在客户端渲染(跳过SSR)

四、混合渲染策略

代码示例

// 现代框架支持在同一应用中混合使用不同渲染模式

// Next.js App Router 渲染模式
// 1. 静态生成(默认)
//    - 无fetch的页面自动SSG
//    - 带fetch + cache: 'force-cache' 的页面SSG

// 2. 服务端渲染
//    - fetch + cache: 'no-store'
//    - 使用cookies()/headers()等动态API

// 3. ISR
//    - fetch + next: { revalidate: N }

// 4. CSR
//    - 'use client' + ssr: false
//    - 动态导入

// 渲染模式决策树:
// 页面需要实时数据?
//   是 → 数据变化频率?
//     每次请求都变 → SSR
//     定期变化 → ISR
//   否 → 页面数量?
//     少(<1000) → SSG
//     多(>1000) → ISR + 按需生成

// SvelteKit渲染模式
// +page.ts
export const prerender = true;   // SSG
export const prerender = false;  // SSR
export const ssr = false;        // CSR

// Nuxt路由规则
routeRules: {
  '/': { prerender: true },
  '/blog/*': { swr: 3600 },
  '/admin/*': { ssr: false },
  '/api/*': { cors: true },
}
框架 SSG方案 ISR支持 混合渲染 特色
Next.js generateStaticParams 原生支持 完善 App Router + RSC
Nuxt.js nuxi generate SWR模式 完善 自动路由 + Nitro
Astro 默认SSG 有限 Islands 零JS + 多框架
SvelteKit prerender 有限 完善 轻量 + 快速
Angular prerender命令 有限 有限 企业级方案

五、浏览器兼容性

特性 Chrome Firefox Safari Edge 说明
SSG HTML 全部 全部 全部 全部 标准HTML
ISR 全部 全部 全部 全部 服务端功能
Astro Islands 60+ 60+ 12+ 79+ 需部分JS
Service Worker 40+ 44+ 11.1+ 17+ 离线支持
View Transitions 111+ 不支持 18+ 111+ 页面切换动画

六、注意事项与最佳实践

  • SSG适合内容不频繁变化的页面:博客、文档、营销页面、产品目录

  • 大量页面考虑ISR:避免构建时间过长,使用ISR按需生成

  • 客户端获取动态数据:SSG页面的动态部分在客户端获取

  • Astro适合内容站点:零JS默认、岛屿架构,内容站点的最佳选择

  • 预渲染关键页面:即使使用SSR,也可以预渲染首页等关键页面

  • 构建时间优化:并行生成、增量构建、缓存构建结果


七、常见问题与解决方案

常见问题

SSG如何处理动态内容?

SSG页面在构建时生成静态HTML,动态内容通过客户端JavaScript获取。使用SWR/React Query等库在客户端获取最新数据,实现"静态外壳+动态内容"的模式。

ISR的revalidate时间怎么设置?

根据内容更新频率设置。新闻类网站5-60秒,电商产品页1-5分钟,博客1-24小时。也可以使用on-demand revalidation,在内容更新时主动触发重新生成。

Astro和Next.js怎么选?

内容为主、交互较少的站点选Astro(零JS、极致性能);需要复杂交互和动态功能的选Next.js(功能更全面)。两者也可以结合使用。

SSG的构建时间太长怎么办?

1) 使用增量构建(只重新生成变化的页面);2) 并行生成;3) 减少预渲染页面数量;4) 使用ISR替代全量SSG;5) 优化数据获取逻辑。

SSG站点如何实现搜索功能?

使用客户端搜索方案(如Algolia、FlexSearch、Pagefind),构建时生成搜索索引,客户端加载索引实现即时搜索。


八、总结

本教程介绍了SSG静态生成与HTML的关系。SSG在构建时预渲染所有页面为静态HTML,可以直接部署到CDN,访问速度最快。Next.js的SSG/ISR、Nuxt Generate、Astro是主要的SSG方案。ISR解决了SSG内容更新慢的问题,按需重新生成页面。Astro的岛屿架构实现了"零JS默认+选择性hydration"的创新模式。现代框架支持混合渲染,不同页面可以使用不同的渲染策略。选择SSG/SSR/CSR应根据页面类型和业务需求灵活组合。

标签: SSG 静态生成 ISR Astro Next.js Nuxt.js

本文涉及AI创作

内容由AI创作,请仔细甄别

list快速访问

上一篇: 框架集成:22 SSR服务端渲染与HTM - 详细教程与实战指南 下一篇: 框架集成:24. 框架SEO与HTML: - 详细教程与实战指南

poll相关推荐