名称: 现代Web应用架构 描述: “用于在JavaScript/TypeScript中设计或构建现代Web应用程序(包括SPA/SSR/SSG/ISR/RSC)时使用:架构权衡、状态/数据模式、性能、测试、交付和团队扩展。”
现代Web应用架构 (SPA/SSR/SSG/RSC)
概述
为设计和构建现代Web应用程序(包括SPA和混合渲染应用)提供全面指导。本技能强调权衡、明确边界和生产就绪实践(性能、可访问性、安全性、测试、交付)。
核心原则: 架构中的一切都是权衡。没有“正确”答案,只有针对您特定上下文的最不坏的组合。
操作模式(如何使用本技能)
激活时,按此顺序工作:
- 澄清上下文(最多5-10个问题) → 用户、路由、SEO、交互性、数据、认证、团队、约束。
- 为每个路由选择渲染策略(不是“整个应用一种策略”)。
- 定义边界 → 功能/领域模块、共享库、所有权和稳定接口。
- 规划状态+数据 → 本地/共享/全局/服务器/URL状态、缓存策略、失效、乐观更新。
- 规划非功能性需求 → 性能预算+测量、可访问性计划、安全态势、可观测性。
- 生成工件 → 带有明确权衡的简短建议,以及具体后续步骤(文件夹结构、ADRs、清单)。
如果用户无法回答问题,陈述合理的假设并继续(不要阻塞)。
何时使用
- 启动新的SPA或Web应用程序
- 选择渲染策略(CSR、SSR、SSG、ISR、RSC)
- 实现状态管理
- 优化核心Web指标(LCP/INP/CLS)
- 为多个前端团队扩展
- 做出架构权衡决策
- 从传统前端迁移到现代前端
快速发现问题(首先询问)
- 前3个用户旅程及其目标延迟是什么(例如,“搜索 → 产品 → 结账”)?
- 是否有任何路由需要SEO?哪些是公开的与需要认证的?
- 数据形态是什么:主要是CRUD、实时、离线优先、重表单、大表格/图表?
- 约束是什么:浏览器支持、包限制、上市时间、合规性(SOC2/HIPAA/PCI)?
- 团队拓扑是什么:多少开发者/团队、发布节奏、所有权边界?
- 您的首选技术栈(React/Vue/Angular/原生),是否开放使用TypeScript?
参考文件
| 主题 | 何时加载 |
|---|---|
| @references/design-patterns.md | 实现JS模式(模块、观察者、工厂等) |
| @references/react-patterns.md | React组件、钩子、状态、组合 |
| @references/spa-fundamentals.md | SPA架构、路由、模块组织 |
| @references/micro-frontends.md | 扩展团队、独立部署 |
| @references/performance.md | 包大小、加载、核心Web指标 |
| @references/architecture-decisions.md | 权衡、耦合、适应性函数 |
| @references/rendering-strategies.md | CSR vs SSR vs SSG vs ISR vs RSC |
| @references/state-management.md | 本地、全局、服务器状态模式 |
| @references/security-and-auth.md | 认证选择、令牌存储、XSS/CSRF、CSP、API边界 |
| @references/accessibility-and-i18n.md | WCAG基础、SPA焦点管理、包容性组件、i18n陷阱 |
| @references/testing-and-quality.md | 测试策略、CI质量门、a11y检查、合同测试 |
| @references/tooling-and-delivery.md | 打包、环境、部署、可观测性、功能标志 |
快速架构决策树
项目需求?
├─ SEO关键 + 动态内容 → SSR(或SSR+流式)
├─ SEO关键 + 大部分静态 → SSG/ISR(或混合)
├─ 大部分需要认证 + 应用类UX → CSR SPA(或带预渲染外壳的混合)
├─ 混合(营销 + 应用) → 混合/岛屿(路由级策略)
│
团队大小?
├─ <5名开发者 → 模块化单体SPA
├─ 5-15名开发者 → 结构良好的SPA或基于服务
├─ >15名开发者,多个团队 → 考虑微前端
│
领域复杂性?
├─ 简单CRUD → 分层架构
├─ 复杂工作流 → 领域分区(DDD)
├─ 多个有界上下文 → 微前端
默认输出(应生成的内容)
根据用户请求,目标输出:
- 路由策略地图:小表路由 → CSR/SSR/SSG/ISR/RSC + 原因
- 模块边界草图:功能文件夹、共享库、接口合同
- 状态地图:本地/共享/全局/服务器/URL,加选定的工具模式
- 数据计划:缓存/失效、错误状态、乐观更新、分页
- 质量计划:测试层 + CI门 + 可访问性检查
- 性能计划:预算 + 测量 + 具体加载策略(分割点)
- 风险登记册:前5大风险 + 缓解措施(例如,水合成本、认证态势、团队耦合)
基本模式快速参考
组件模式
| 模式 | 使用时机 |
|---|---|
| 容器/展示型 | 分离数据与UI |
| 复合组件 | 构建可组合API(选择、菜单) |
| 钩子 | 共享有状态逻辑而无HOC |
| 提供者 | 避免全局数据的属性传递 |
状态管理
| 方法 | 使用时机 |
|---|---|
| useState/useReducer | 本地组件状态 |
| Context | 主题、认证、低频率全局状态 |
| Zustand/Jotai | 简单全局状态,最小样板 |
| Redux Toolkit | 复杂状态,时间旅行调试 |
| React Query/SWR | 服务器状态、缓存、后台刷新 |
| XState | 复杂流与显式状态机 |
性能基础
| 技术 | 影响 |
|---|---|
| 代码分割 | 减少初始包 |
| 懒加载 | 推迟非关键 |
| React.memo | 防止不必要的重新渲染 |
| useMemo/useCallback | 稳定引用 |
| 虚拟列表 | 处理大型数据集 |
架构特性(选择3-7个)
| 特性 | 要问的问题 |
|---|---|
| 可扩展性 | 多少并发用户?增长率? |
| 性能 | 可接受的TTI?LCP目标? |
| 可部署性 | 多久发布一次?独立部署? |
| 可测试性 | 多容易验证更改? |
| 可维护性 | 预期寿命? |
| 模块性 | 需求多久变化? |
要避免的反模式
| 反模式 | 问题 | 修复 |
|---|---|---|
| 属性传递 | 紧耦合 | 使用Context或状态管理 |
| 上帝组件 | 太多职责 | 按关注点拆分 |
| 过早优化 | 无证据的复杂性 | 先分析 |
| 共享可变状态 | 竞态条件、错误 | 不可变模式 |
| 单体包 | 慢初始加载 | 代码分割 |
| 过度获取 | 浪费带宽 | 使用GraphQL或BFF |
| 默认使用LocalStorage令牌 | XSS导致账户接管 | 偏好httpOnly cookies + CSP(见安全参考) |
| 服务器数据使用全局存储 | 缓存失效痛苦 | 使用React Query/SWR处理服务器状态 |
性能预算
预算必须根据您的用户/设备校准,但这些是“默认快速”应用的良好起点:
| 指标 | 目标 | 需要工作 |
|---|---|---|
| LCP | <2.5秒 | 2.5–4秒 |
| INP | <200毫秒 | 200–500毫秒 |
| CLS | <0.1 | 0.1–0.25 |
| TTFB | <800毫秒 | 800毫秒–1.8秒 |
| 路由JS(初始) | <170KB gzip | <300KB gzip |
来源
合成自:
- Learning JavaScript Design Patterns (Osmani, 2023)
- React in Depth (Barklund, 2024)
- SPA Design and Architecture (Scott)
- Single Page Web Applications (Mikowski & Powell)
- Building Micro-Frontends (Mezzalira)
- Micro Frontends in Action (Geers)
- Responsible JavaScript (Wagner)
- High Performance Browser Networking (Grigorik)
- Web Performance in Action (Wagner)
- Frontend Architecture for Design Systems (Godbolt)
- Fundamentals of Software Architecture (Richards & Ford)
- Software Architecture: The Hard Parts (Ford et al.)
- Patterns.dev