Appearance
服务端渲染(SSR)与客户端渲染(CSR)
本手册从"页面到底在哪里渲染"这一根本问题出发,梳理传统 SSR、现代同构 SSR、CSR 三种基础范式,再深入 SSG / ISR、React Server Components 等现代衍生方案,最后落到量化对比、选型指南与 Next.js 双 Router 实战,帮助你构建完整的渲染架构知识体系。
导航目录
一、渲染范式篇
二、现代衍生方案篇
三、对比与选型篇
四、框架实战篇
一、传统服务端渲染(SSR)
核心概念
传统服务端渲染(SSR) 指由服务器在每次请求时动态拼装出完整 HTML 再返回给浏览器。页面的数据获取、模板渲染全部在服务端完成,浏览器拿到的就是"开箱即用"的完整页面,代表技术有 JSP、PHP、ASP、EJS 等模板引擎。
技术原理
核心流程
- 请求处理:用户发起页面请求,服务器接收 HTTP 请求
- 数据获取:服务器执行后端逻辑,从数据库或 API 获取数据
- 模板渲染:使用模板引擎(JSP、EJS 等)将数据注入 HTML 模板
- 响应返回:生成完整的 HTML 文档并返回给客户端
- 客户端展示:浏览器直接渲染接收到的静态 HTML
请求流程图:
text
浏览器 服务器 数据库/API
| 1. 发起页面请求 | |
| ──────────────────────►| |
| | 2. 查询数据 |
| | ────────────────────────►|
| | 返回数据 |
| | ◄────────────────────────|
| | [3. 模板引擎注入渲染 HTML]|
| 4. 返回完整 HTML | |
| ◄──────────────────────| |
| [5. 直接渲染展示,无需等待 JS] |技术实现示例
功能说明:传统服务端渲染的 JSP 实现示例,展示了服务器如何生成动态 HTML。
java
// JSP 示例
<%@ page contentType="text/html;charset=UTF-8" %>
<html>
<head>
<title>商品列表</title>
</head>
<body>
<h1>商品列表</h1>
<%
List<Product> products = productService.getProducts();
for(Product product : products) {
%>
<div class="product">
<h2><%= product.getName() %></h2>
<p>价格: <%= product.getPrice() %></p>
</div>
<% } %>
</body>
</html>优势分析
性能优势
- 首屏加载快:用户无需等待 JavaScript 下载和执行
- SEO 友好:搜索引擎爬虫直接获取完整内容
- 低客户端要求:即使在 JavaScript 禁用情况下也能正常显示
开发优势
- 技术栈统一:前后端使用相同语言和技术栈
- 简单直接:开发流程直观,学习曲线平缓
局限性
用户体验问题
- 页面刷新:每次导航都需要完整页面重载
- 交互延迟:简单的交互也需要与服务器通信
- 状态丢失:页面跳转时客户端状态无法保持
开发维护挑战
- 代码耦合:业务逻辑与展示逻辑紧密绑定
- 分工模糊:前端后端开发职责界限不清晰
- 技术债务:随着项目扩大,维护成本指数级增长
优劣一览
| 优势 ✅ | 局限性 ❌ |
|---|---|
| 首屏快,无需等待 JS 下载执行 | 每次导航都整页刷新,交互体验差 |
| SEO 友好,爬虫直接拿到内容 | 简单交互也要往返服务器,延迟高 |
| JS 禁用也能显示,低客户端要求 | 跳转丢失客户端状态 |
| 前后端技术栈统一,学习曲线平缓 | 业务与展示逻辑耦合,维护成本高 |
演进方向
传统 SSR 的痛点在于"每次交互都回服务器"。为了兼顾 SSR 的首屏 / SEO 优势与 SPA 的流畅交互,才诞生了下一节的同构渲染——同一套组件代码在服务端与客户端各跑一次。
二、现代服务端渲染(同构渲染)
核心概念
同构渲染(Isomorphic / Universal Rendering) 指同一套组件代码既能在服务端运行生成首屏 HTML,又能在客户端"注水"接管交互。它把传统 SSR 的首屏优势与 CSR 的流畅交互结合起来,是现代 SSR 框架(Next.js / Nuxt.js)的技术基石。
架构设计
同构渲染核心概念
功能说明:展示同构渲染的完整流程,包括服务端渲染和客户端注水两个阶段。
javascript
// 服务端渲染
// server.js
import { renderToString } from "react-dom/server";
import App from "./App";
app.get("/", (req, res) => {
const html = renderToString(<App />);
res.send(`
<html>
<head><title>同构应用</title></head>
<body>
<div id="root">${html}</div>
<script src="/client.js"></script>
</body>
</html>
`);
});
// 客户端注水
// client.js
import { hydrateRoot } from "react-dom/client";
import App from "./App";
hydrateRoot(document.getElementById("root"), <App />);关键技术流程
服务端渲染阶段
- 执行 React/Vue 组件渲染
- 处理数据获取和状态初始化
- 生成静态 HTML 字符串
客户端注水阶段
- 复用服务端渲染的 DOM 结构
- 绑定事件处理器和交互逻辑
- 接管后续的路由和状态管理
同构渲染时序图:
text
浏览器 SSR 服务器
| 请求页面 |
| ─────────────────────────────────►|
| [renderToString 生成 HTML] |
| 返回带内容的 HTML(首屏可见) |
| ◄─────────────────────────────────|
| [展示静态 HTML,此时不可交互] |
| 下载 client.js |
| ─────────────────────────────────►|
| 返回 JS bundle |
| ◄─────────────────────────────────|
| [hydrateRoot 注水:复用 DOM+绑事件]|
| [页面变为可交互(TTI)] |首屏可见(FCP) 在 HTML 返回时即达成,但 可交互(TTI) 要等 JS 下载并注水完成,两者之间存在一段「可见但点不动」的窗口期。
水合不匹配(Hydration Mismatch)
什么是水合不匹配
注水时 React 会比对客户端首次渲染结果与服务端返回的 HTML,若两者不一致就会报 hydration 警告并丢弃服务端 DOM 重新渲染,导致闪烁与性能损耗,是同构 SSR 最高频的坑。
常见原因:
- 使用了
Date.now()、Math.random()等服务端/客户端结果不同的值 - 直接读取
window、localStorage等浏览器专属 API - 服务端与客户端的数据源/状态不一致
- HTML 结构非法嵌套(如
<p>里放<div>)被浏览器自动纠正
javascript
// ❌ 错误:服务端与客户端渲染结果不同
function Bad() {
return <div>{Date.now()}</div>;
}
// ✅ 正确:把浏览器相关逻辑放到 useEffect(仅客户端执行)
function Good() {
const [time, setTime] = useState(null);
useEffect(() => {
setTime(Date.now());
}, []);
return <div>{time}</div>;
}性能优化策略
缓存机制
功能说明:实现页面级缓存,减少重复渲染,提高服务端渲染性能。
javascript
// 页面级缓存示例
const microCache = new Map();
app.get("*", (req, res) => {
const cacheKey = req.url;
// 检查缓存
if (microCache.has(cacheKey)) {
return res.send(microCache.get(cacheKey));
}
// 渲染页面
const html = renderToString(<App />);
// 设置缓存(2分钟过期)
microCache.set(cacheKey, html);
setTimeout(() => microCache.delete(cacheKey), 120000);
res.send(html);
});流式渲染优化
功能说明:使用 React 18 的流式渲染功能,实现页面内容的渐进式加载,提升用户体验。
javascript
// React 18 流式渲染
import { renderToPipeableStream } from "react-dom/server";
app.use("*", (request, response) => {
const { pipe } = renderToPipeableStream(<App />, {
bootstrapScripts: ["/main.js"],
onShellReady() {
response.setHeader("content-type", "text/html");
pipe(response);
},
});
});技术挑战与解决方案
环境适配问题
功能说明:解决服务端和客户端环境差异问题,实现跨环境兼容的数据获取和 API 调用。
javascript
// 环境检测与适配
const isServer = typeof window === "undefined";
// 条件性导入浏览器相关API
if (!isServer) {
const { animationFrame } = require("./browser-apis");
}
// 数据获取适配
class DataFetcher {
static async fetchData() {
if (isServer) {
// 服务端直接调用API
return await database.query();
} else {
// 客户端通过HTTP请求
return await fetch("/api/data").then((r) => r.json());
}
}
}三、客户端渲染(CSR)
核心概念
客户端渲染(CSR) 指服务器只返回一个几乎空白的 HTML 外壳(仅含一个 #root 挂载点和 JS 引用),页面的 DOM 结构、数据获取与渲染全部由浏览器执行 JavaScript 完成。这是 React / Vue 单页应用(SPA)的默认工作方式。
架构演进
单页面应用(SPA)架构
text
应用结构:
- index.html (入口文件)
- bundle.js (应用代码包)
- 路由管理 (React Router, Vue Router)
- 状态管理 (Redux, Vuex)
- API通信层 (RESTful/GraphQL)CSR 加载流程图:
text
浏览器 服务器 / API
| 1. 请求页面 |
| ─────────────────────────────► | 服务器
| 2. 返回空壳 HTML(仅 root) |
| ◄───────────────────────────── |
| 3. 下载 bundle.js |
| ─────────────────────────────► | 服务器
| 返回 JS |
| ◄───────────────────────────── |
| 4. 执行 JS,渲染组件(白屏结束)|
| 5. 请求数据 |
| ─────────────────────────────► | API 服务
| 返回数据 |
| ◄───────────────────────────── |
| 6. 数据渲染,页面完整可交互 |CSR 首屏需经历「空壳 → 下载 JS → 执行渲染 → 请求数据」多个串行阶段,因此首屏较慢且爬虫拿到的是空壳 HTML(SEO 弱)。
现代 CSR 技术栈
功能说明:展示现代客户端渲染的完整技术栈,包括路由管理、状态管理和组件渲染。
javascript
// React SPA 示例
import { createRoot } from "react-dom/client";
import { BrowserRouter } from "react-router-dom";
import { Provider } from "react-redux";
import App from "./App";
import store from "./store";
const container = document.getElementById("root");
const root = createRoot(container);
root.render(
<Provider store={store}>
<BrowserRouter>
<App />
</BrowserRouter>
</Provider>
);性能优化技术
代码分割与懒加载
功能说明:使用 React.lazy 实现路由级代码分割,减少初始加载体积,提升应用性能。
javascript
// React.lazy 实现路由级代码分割
import { lazy, Suspense } from "react";
const Home = lazy(() => import("./components/Home"));
const About = lazy(() => import("./components/About"));
function App() {
return (
<Suspense fallback={<div>加载中...</div>}>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
</Suspense>
);
}资源预加载策略
功能说明:通过预加载关键资源和数据,提升页面加载速度和用户体验。
html
<!-- 关键资源预加载 -->
<link rel="preload" href="/critical.css" as="style" />
<link rel="preload" href="/main.js" as="script" />
<link rel="prefetch" href="/about-bundle.js" as="script" />
<!-- 数据预获取 -->
<script>
// 预获取下一页数据
if (isHighSpeedNetwork()) {
fetch("/api/next-page-data").then(() => {
// 缓存数据供后续使用
});
}
</script>SEO 优化方案
预渲染技术
功能说明:使用 Puppeteer 实现页面预渲染,提高 CSR 应用的 SEO 友好度。
javascript
// 使用Puppeteer进行预渲染
const puppeteer = require("puppeteer");
async function prerenderPage(url, outputPath) {
const browser = await puppeteer.launch();
const page = await browser.newPage();
// 设置用户代理为Googlebot
await page.setUserAgent("Googlebot/2.1");
await page.goto(url, { waitUntil: "networkidle0" });
const html = await page.content();
fs.writeFileSync(outputPath, html);
await browser.close();
}动态元标签管理
功能说明:使用 React Helmet 动态管理页面元标签,提升 CSR 应用的 SEO 效果。
javascript
// React Helmet 示例
import { Helmet } from "react-helmet";
function ProductPage({ product }) {
return (
<div>
<Helmet>
<title>{product.name} - 我的商店</title>
<meta name="description" content={product.description} />
<meta property="og:title" content={product.name} />
<meta property="og:description" content={product.description} />
</Helmet>
<h1>{product.name}</h1>
<p>{product.description}</p>
</div>
);
}四、静态生成 SSG 与增量再生 ISR
核心概念
SSG(Static Site Generation,静态站点生成) 在构建时就把页面渲染成静态 HTML,请求到来时直接返回、无需服务端实时计算,性能与 SSR 首屏相当却几乎零服务器成本。 ISR(Incremental Static Regeneration,增量静态再生) 是 Next.js 对 SSG 的增强:静态页面可以在后台按时间间隔或按需重新生成,兼顾静态性能与内容新鲜度。
SSG 与 ISR 的关系
text
构建时 build ──(预渲染)──► 静态 HTML 文件 ──(CDN 分发)──► 用户请求直接命中
▲ │
│ ┌─────────────────┤
(ISR revalidate 到期) │ │ SSG:内容永久静态 → 需重新构建才更新
后台再生新 HTML ─(悄悄替换)─┘ └ ISR:到期后台再生新 HTMLNext.js SSG 实现(Page Router)
功能说明:getStaticProps 在构建时执行、生成静态页面;getStaticPaths 声明需要预渲染的动态路由。
javascript
// pages/blog/[slug].js
// ① 声明要预渲染的路径(构建时确定)
export async function getStaticPaths() {
const posts = await fetchAllPosts();
return {
paths: posts.map((p) => ({ params: { slug: p.slug } })),
fallback: "blocking", // 未预渲染的路径首次访问时按需生成
};
}
// ② 构建时为每个路径生成 props(打包成静态 HTML)
export async function getStaticProps({ params }) {
const post = await fetchPost(params.slug);
return {
props: { post },
revalidate: 60, // ★ 加上这行即变为 ISR:最多每 60s 后台再生一次
};
}
export default function BlogPost({ post }) {
return <article>{post.content}</article>;
}ISR 的按需再验证(On-Demand Revalidation)
内容更新即时生效
除了基于时间的 revalidate,Next.js 还支持在内容变更时(如 CMS webhook 回调)主动触发指定页面重新生成,无需等待时间窗口,也无需整站重新构建。
javascript
// pages/api/revalidate.js —— CMS 更新后调用此接口
export default async function handler(req, res) {
// 校验密钥,防止恶意刷新
if (req.query.secret !== process.env.REVALIDATE_TOKEN) {
return res.status(401).json({ message: "Invalid token" });
}
// 触发指定路径重新生成
await res.revalidate(`/blog/${req.query.slug}`);
return res.json({ revalidated: true });
}SSR / SSG / ISR 三者对比
| 维度 | SSR(getServerSideProps) | SSG(getStaticProps) | ISR(getStaticProps + revalidate) |
|---|---|---|---|
| 渲染时机 | 每次请求实时渲染 | 构建时一次性预渲染 | 构建时预渲染 + 后台按需再生 |
| 首屏性能 | 好(需服务端计算) | 极好(CDN 直出) | 极好(CDN 直出) |
| 内容新鲜度 | 实时 | 构建后固定,需重新构建 | 准实时(revalidate 间隔内) |
| 服务器成本 | 高(每次都渲染) | 极低(无运行时渲染) | 低(仅到期时后台渲染) |
| 适用场景 | 高频变动的个性化页面 | 文档、营销页等极少变动内容 | 博客、商品详情等中低频更新内容 |
选型要点
不要把所有页面都做成 SSR。能静态化的尽量 SSG,需要一定新鲜度的用 ISR,只有真正强实时 / 强个性化(如用户后台、下单页)才用 SSR。这是 Next.js 性能优化的第一原则。
五、React Server Components(RSC)
核心概念
React Server Components(RSC,服务端组件) 是 React 18+ 引入的新范式:组件只在服务端运行,其代码不会打包进客户端 bundle,渲染结果以特殊的序列化格式流式传给浏览器。它与 SSR 不同——SSR 是"把组件渲染成 HTML 字符串",RSC 是"组件本身就活在服务端"。
RSC 与传统 SSR 的本质区别
| 维度 | 传统 SSR(含同构) | React Server Components |
|---|---|---|
| 组件运行位置 | 服务端渲染一次 + 客户端注水 | 服务端组件只在服务端跑 |
| 客户端 bundle | 组件代码要打包到客户端做注水 | 服务端组件零客户端 JS |
| 数据获取 | getServerSideProps 等外部钩子 | 组件内直接 await fetch() |
| 交互能力 | 全部组件可交互 | 需交互的部分标 'use client' |
服务端组件 vs 客户端组件
功能说明:默认所有组件都是服务端组件;需要状态、事件、浏览器 API 的组件用 'use client' 指令标记为客户端组件。
jsx
// app/page.jsx —— 默认即服务端组件(零客户端 bundle)
async function ProductList() {
// 直接在组件内访问数据库 / API,无需 getServerSideProps
const products = await db.product.findMany();
return (
<ul>
{products.map((p) => (
<ProductCard key={p.id} product={p} />
))}
</ul>
);
}
export default ProductList;jsx
// app/LikeButton.jsx —— 客户端组件(有交互)
"use client";
import { useState } from "react";
export default function LikeButton() {
const [liked, setLiked] = useState(false);
return (
<button onClick={() => setLiked(!liked)}>{liked ? "❤️" : "🤍"}</button>
);
}客户端边界(Client Boundary)
text
服务端组件 ProductList
│ (零 JS 直接查库)
▼
ProductCard 服务端组件
│ (导入并渲染)
▼
LikeButton 'use client'
│ (打包进客户端 bundle)
▼
浏览器注水,支持交互心智模型
把 'use client' 想象成一道边界线:线以上(服务端组件)负责数据获取与静态渲染、不进 bundle;线以下(客户端组件及其子树)负责交互、会进 bundle。合理下沉这道边界,能最大限度减小客户端 JS 体积。
RSC 使用限制
服务端组件不能使用
useState、useEffect、事件处理器、浏览器 API客户端组件不能直接
import服务端组件(但可通过children插槽传入)RSC 目前深度绑定 Next.js App Router 等支持框架,尚不能脱离框架裸用
六、深度对比分析与选型指南
技术指标量化对比
| 评估维度 | 传统 SSR | 现代 SSR | CSR | 混合渲染 |
|---|---|---|---|---|
| 首屏时间 | 100-300ms | 200-500ms | 500-2000ms | 300-800ms |
| 可交互时间 | 500-1000ms | 300-800ms | 1000-3000ms | 500-1200ms |
| SEO 支持度 | ★★★★★ | ★★★★★ | ★★☆☆☆ | ★★★★☆ |
| 开发复杂度 | ★★☆☆☆ | ★★★★☆ | ★★★☆☆ | ★★★★★ |
| 服务器成本 | ★★☆☆☆ | ★★★☆☆ | ★★★★★ | ★★★☆☆ |
| 用户体验 | ★★☆☆☆ | ★★★★☆ | ★★★★★ | ★★★★☆ |
场景化选型矩阵
内容型网站(新闻、博客)
- 推荐方案:现代 SSR(Next.js/Nuxt.js)
- 理由:SEO 需求强烈,内容更新频繁,需要良好的首屏性能
- 技术栈:Next.js + Headless CMS + CDN
企业级应用(管理后台、ERP)
- 推荐方案:CSR + 优化
- 理由:交互复杂,SEO 需求低,注重用户体验
- 技术栈:React/Vue + 状态管理 + PWA
电商平台
- 推荐方案:混合渲染
- 理由:商品页需要 SEO,个人中心需要丰富交互
- 技术栈:Next.js(商品页) + SPA(用户中心)
移动端 Web 应用
- 推荐方案:CSR + PWA
- 理由:原生应用体验,离线功能需求
- 技术栈:Vue/React + Service Worker + 应用壳架构
混合渲染策略
按路由差异化渲染
功能说明:针对不同路由采用不同的渲染策略,平衡性能和 SEO 需求。
javascript
// Next.js 混合渲染配置
// next.config.js
module.exports = {
async rewrites() {
return [
// 静态页面使用SSG
{ source: "/about", destination: "/about.html" },
// 动态页面使用SSR
{ source: "/products/:id", destination: "/server/products/:id" },
// API路由
{ source: "/api/:path*", destination: "/api/:path*" },
];
},
};边缘计算渲染
功能说明:使用 Cloudflare Workers 实现边缘 SSR,减少延迟,提升全球用户体验。
javascript
// Cloudflare Workers实现边缘SSR
export default {
async fetch(request, env) {
const url = new URL(request.url);
// 缓存检查
const cacheKey = url.pathname;
const cached = await env.CACHE.get(cacheKey);
if (cached) {
return new Response(cached, {
headers: { "Content-Type": "text/html" },
});
}
// 边缘渲染
const html = await renderApp(url);
// 设置缓存
await env.CACHE.put(cacheKey, html, { expirationTtl: 3600 });
return new Response(html, {
headers: { "Content-Type": "text/html" },
});
},
};七、Next.js 深度解析:Page Router vs App Router
两代路由方案
Page Router(pages/ 目录)是 Next.js 的经典方案,以"文件即页面"组织路由,数据获取靠 getServerSideProps / getStaticProps。 App Router(app/ 目录,Next.js 13+)是新一代方案,原生支持 React Server Components、嵌套布局、流式渲染,是官方主推方向。
架构哲学对比
Page Router:文件即路由
text
设计理念:基于页面的思维模型
pages/
index.tsx → /
about.tsx → /about
blog/
index.tsx → /blog
[slug].tsx → /blog/xxxApp Router:组件化路由
text
设计理念:基于组件的思维模型,支持布局共享和状态保持
app/
layout.tsx # 根布局
page.tsx → /
about/
page.tsx → /about
blog/
layout.tsx # 博客布局
page.tsx → /blog
[slug]/
page.tsx → /blog/xxx渲染模式技术细节
Page Router 渲染生命周期
功能说明:展示 Page Router 的页面级数据获取和渲染流程。
javascript
// 页面级数据获取
export async function getServerSideProps(context) {
// 每次请求时执行
const data = await fetchData(context.params);
return { props: { data } };
}
export default function Page({ data }) {
// 客户端注水
return <div>{data}</div>;
}App Router 组件级渲染
功能说明:展示 App Router 的组件级渲染能力,包括服务端组件、客户端组件和布局组件的使用。
javascript
// 服务端组件 - 零客户端bundle
async function ServerComponent() {
const data = await fetch("https://api.example.com/data");
return <div>{data}</div>;
}
// 客户端组件 - 支持交互
("use client");
function ClientComponent() {
const [state, setState] = useState();
return <button onClick={() => setState()}>点击</button>;
}
// 布局组件 - 共享UI
export default function Layout({ children }) {
return (
<html>
<body>
<nav>导航栏</nav>
{children}
</body>
</html>
);
}性能基准测试对比
加载性能指标
| 场景 | Page Router | App Router | 提升幅度 |
|---|---|---|---|
| 首屏加载 | 1.2s | 0.8s | 33% |
| 可交互时间 | 1.8s | 1.1s | 39% |
| Bundle 大小 | 120KB | 85KB | 29% |
| LCP 指标 | 2.1s | 1.4s | 33% |
流式渲染性能优势
javascript
// App Router流式渲染示例
export default async function Page() {
return (
<section>
<Suspense fallback={<div>加载用户信息...</div>}>
<UserProfile />
</Suspense>
<Suspense fallback={<div>加载商品列表...</div>}>
<ProductList />
</Suspense>
</section>
);
}
async function UserProfile() {
// 快速返回的数据
const user = await fetchUser();
return <div>欢迎, {user.name}</div>;
}
async function ProductList() {
// 慢速查询的数据
const products = await fetchProducts();
return products.map((product) => <div key={product.id}>{product.name}</div>);
}迁移策略与最佳实践
渐进式迁移方案
javascript
// 步骤1:并行运行两个Router
// next.config.js
module.exports = {
experimental: {
appDir: true, // 启用App Router
},
};
// 步骤2:逐步迁移页面
// app/legacy/[...slug]/page.tsx
export default function LegacyPage({ params }) {
// 重定向到pages目录下的旧页面
redirect(`/old/${params.slug.join("/")}`);
}
// 步骤3:新功能使用App Router混合渲染配置
javascript
// 针对不同路由采用不同策略
export const dynamicParams = true;
export async function generateStaticParams() {
// 静态生成高频页面
return [{ id: "1" }, { id: "2" }];
}
export async function generateMetadata({ params }) {
// 动态生成元数据
const product = await fetchProduct(params.id);
return { title: product.name };
}
export default async function Page({ params }) {
// 服务端渲染
const product = await fetchProduct(params.id);
return <ProductDetail product={product} />;
}八、未来趋势与演进方向
边缘渲染的兴起
- 边缘计算平台:Vercel Edge Functions, Cloudflare Workers
- 优势:更低延迟,更好的全球化部署
- 技术栈:React Server Components + 边缘运行时
AI 驱动的渲染优化
javascript
// 智能预渲染示例
async function smartPrerender(userBehavior) {
const prediction = await AIPredictor.predictNextPages(userBehavior);
prediction.pages.forEach((page) => {
// 预渲染预测页面
prerenderPage(page.url);
});
}WebAssembly 在渲染中的应用
- 高性能计算:复杂的图形渲染、数据处理
- 跨语言能力:Rust、C++编写的组件在浏览器中运行
- 混合渲染:Wasm + JavaScript 协同工作
结语
渲染方案没有银弹,本质是在首屏性能、SEO、交互体验、服务器成本之间做权衡:静态内容用 SSG / ISR,动态个性化用 SSR,重交互轻 SEO 用 CSR,追求极致体积再引入 RSC。理解每种范式"在哪里渲染、渲染几次、代码跑在哪端",就能在项目中做出合理的架构取舍。