SSR / SSG / Hybrid Rendering (Deep Workflow)
Rendering is an architecture decision, not a framework toggle. Guide users to map freshness, personalization, cost, and complexity per route—avoid “SSR everything” or “static everything” by default.
When to Offer This Workflow
Trigger conditions:
- - Choosing rendering strategy for marketing vs app shell vs dashboards
- SEO + auth + dynamic data conflicts
- Slow TTFB, stale content, or expensive server work per request
- Hydration bugs, double data fetch, or client/server environment mismatch
Initial offer:
Use six stages: (1) route & data classification, (2) choose rendering mode(s), (3) data loading & cache layers, (4) streaming & partial SSR, (5) hydration & client boundaries, (6) validate (SEO, perf, ops). Confirm framework and hosting (Node server, serverless, edge).
Stage 1: Route & Data Classification
Goal: Each route has clear freshness, auth, and personalization needs.
Dimensions
- - Public vs authenticated: can HTML be shared or per-user?
- Update frequency: static marketing, hourly blog, real-time inventory
- Source of truth: CMS, DB, API with rate limits, edge KV
Output
A matrix: route pattern → public/private → max staleness acceptable → personalization level.
Exit condition: No ambiguous “dynamic page” without stating what changes and how often.
Stage 2: Choose Rendering Mode(s)
Goal: Pick SSG, SSR, ISR/ondemand revalidate, CSR with SSR shell, or edge—per route.
Heuristics
- - SSG / prerender: stable content, best TTFB/CDN cache, great SEO—watch rebuild/revalidate story
- SSR: must reflect request-time data (A/B, geo, auth gating) or strict freshness
- Client-heavy: acceptable for post-auth app surfaces if SEO not needed
- Hybrid: static shell + client islands; or static generation with server components for parts (framework-specific)
Trade-offs
- - SSR cost and latency vs SSG staleness
- Edge rendering: geography and limits (CPU, Node APIs)
Exit condition: Documented per-route strategy with rationale.
Stage 3: Data Loading & Cache Layers
Goal: One coherent story for where data is fetched and how it is cached (CDN, full-page, data cache, edge).
Practices
- - Cache-Control / surrogate keys / tag-based invalidation—align with framework primitives (e.g.,
revalidate, fetch cache) - Deduplicate requests between server and client where frameworks allow
- Avoid accidental private data in shared cache—vary by cookie/auth correctly or disable cache
Stale-While-Revalidate
- - Great for mostly fresh—document user-visible staleness acceptance
Exit condition: Data flow diagram: origin → edge → browser; invalidation owner identified.
Stage 4: Streaming & Partial SSR
Goal: Improve perceived performance with suspense/streaming where supported.
Guidance
- - Defer slow fragments; show skeletons with accessible semantics
- Ordering: ensure critical LCP resources not blocked by deferred junk
- Headers: understand chunked response implications for intermediaries
Exit condition: Slow dependencies isolated; UX fallbacks defined.
Stage 5: Hydration & Client Boundaries
Goal: Correct interactive UI without double work or mismatches.
Checklist
- - Server/client component or module boundaries (framework-specific)
- useEffect vs server fetch duplication—waterfalls
- Environment: no
window on server; no secret APIs in client bundles - Hydration mismatch: locale, random IDs, time—suppress or serialize state
Exit condition: Known interactive islands listed; mismatch risks mitigated.
Stage 6: Validate (SEO, Performance, Ops)
Goal: Rendering choices show up correctly in search, metrics, and logs.
SEO
- - View source / rendered HTML for critical content; meta and canonical per mode
- Auth: soft paywalls—decide what crawlers see ethically and technically
Performance
- - TTFB vs FCP/LCP; server time vs edge cache hit
- RUM segmented by route and cache hit
Ops
- - Cold starts on serverless SSR; concurrency limits; regional failover
Final Review Checklist
- - [ ] Per-route rendering choice documented with freshness/personalization
- [ ] Caching and invalidation story is explicit and safe for auth
- [ ] Streaming/skeletons don’t harm LCP or a11y
- [ ] Hydration and env boundaries verified
- [ ] SEO and RUM validation for top templates
Tips for Effective Guidance
- - Name staleness in seconds/minutes—“real-time” is rarely real-time.
- When user uses Next.js, tie advice to App Router vs Pages semantics explicitly if known.
- Warn: edge ≠ full Node—API surface differs.
Handling Deviations
- - SPA-only: focus on meta for landing routes and prerender for marketing if added later.
- No server: SSG + client or external prerender service—be honest about limits.
SSR / SSG / 混合渲染(深度工作流)
渲染是一个架构决策,而非框架开关。引导用户针对每条路由明确新鲜度、个性化、成本和复杂度——避免默认全量SSR或全量静态。
何时提供此工作流
触发条件:
- - 为营销页面 vs 应用壳 vs 仪表盘选择渲染策略
- SEO + 认证 + 动态数据冲突
- TTFB缓慢、内容过时或每次请求的服务器工作成本高昂
- 水合错误、重复数据获取或客户端/服务端环境不匹配
初始建议:
使用六个阶段:(1) 路由与数据分类,(2) 选择渲染模式,(3) 数据加载与缓存层,(4) 流式渲染与部分SSR,(5) 水合与客户端边界,(6) 验证(SEO、性能、运维)。确认框架和托管方式(Node服务器、无服务器、边缘计算)。
阶段1:路由与数据分类
目标: 每条路由都有明确的新鲜度、认证和个性化需求。
维度
- - 公开 vs 认证:HTML是否可以共享还是按用户生成?
- 更新频率:静态营销页面、每小时更新的博客、实时库存
- 数据源:CMS、数据库、带速率限制的API、边缘KV存储
输出
一个矩阵:路由模式 → 公开/私有 → 可接受的最大过期时间 → 个性化程度。
退出条件: 没有模糊的动态页面而不说明什么在变化以及变化频率。
阶段2:选择渲染模式
目标: 为每条路由选择SSG、SSR、ISR/按需重新验证、带SSR壳的CSR或边缘计算。
启发式规则
- - SSG / 预渲染:内容稳定,最佳TTFB/CDN缓存,优秀SEO——关注重建/重新验证机制
- SSR:必须反映请求时数据(A/B测试、地理位置、认证门控)或严格的新鲜度
- 客户端重:对于认证后的应用界面,如果不需要SEO,可以接受
- 混合:静态壳 + 客户端孤岛;或静态生成配合服务端组件处理部分内容(框架特定)
权衡
- - SSR的成本和延迟 vs SSG的过时问题
- 边缘渲染:地理限制和资源限制(CPU、Node API)
退出条件: 记录每条路由的策略及理由。
阶段3:数据加载与缓存层
目标: 为数据获取位置和缓存方式(CDN、全页缓存、数据缓存、边缘计算)提供一个连贯的方案。
实践
- - Cache-Control / 代理键 / 基于标签的失效——与框架原语对齐(例如revalidate、fetch缓存)
- 在框架允许的情况下去重服务端和客户端之间的请求
- 避免在共享缓存中意外包含私有数据——根据cookie/认证正确区分或禁用缓存
过期时重新验证
- - 适用于基本新鲜的场景——记录用户可见的过期接受程度
退出条件: 数据流图:源 → 边缘 → 浏览器;明确失效负责人。
阶段4:流式渲染与部分SSR
目标: 在支持的地方使用Suspense/流式渲染提升感知性能。
指导
- - 延迟慢速片段;使用可访问的语义展示骨架屏
- 顺序:确保关键的LCP资源不被延迟的次要内容阻塞
- 头部:理解分块响应对中间件的影响
退出条件: 慢速依赖被隔离;定义了用户体验降级方案。
阶段5:水合与客户端边界
目标: 实现正确的交互式UI,避免重复工作或不匹配。
检查清单
- - 服务端/客户端组件或模块边界(框架特定)
- useEffect vs 服务端获取的重复——瀑布流问题
- 环境:服务端无window;客户端包中无秘密API
- 水合不匹配:本地化、随机ID、时间——抑制或序列化状态
退出条件: 列出已知的交互孤岛;减轻了不匹配风险。
阶段6:验证(SEO、性能、运维)
目标: 渲染选择在搜索、指标和日志中正确体现。
SEO
- - 查看源代码/渲染后的HTML中关键内容;每种模式的元标签和规范链接
- 认证:软付费墙——从技术和伦理角度决定爬虫能看到什么
性能
- - TTFB vs FCP/LCP;服务端时间 vs 边缘缓存命中
- 按路由和缓存命中分段的真实用户监控
运维
- - 无服务器SSR的冷启动;并发限制;区域故障转移
最终审查清单
- - [ ] 每条路由的渲染选择已记录新鲜度/个性化
- [ ] 缓存和失效方案明确且对认证安全
- [ ] 流式渲染/骨架屏不影响LCP或可访问性
- [ ] 水合和环境边界已验证
- [ ] 主要模板的SEO和真实用户监控验证完成
有效指导技巧
- - 用秒/分钟表示过期时间——实时很少是真正的实时。
- 当用户使用Next.js时,如果已知,明确将建议关联到App Router vs Pages的语义。
- 警告:边缘计算 ≠ 完整Node——API接口不同。
处理偏差
- - 仅SPA:如果后续添加,关注落地页的元标签和营销页的预渲染。
- 无服务端:SSG + 客户端或外部预渲染服务——诚实地说明限制。