name: modern-web-app-architecture description: “适用于使用JavaScript/TypeScript设计和构建现代Web应用程序(SPA/SSR/SSG/ISR/RSC):架构权衡、状态/数据模式、性能、测试、交付和团队扩展。”
现代Web应用架构(SPA/SSR/SSG/RSC)
概述
为设计和构建现代Web应用程序(包括SPA和混合渲染应用)提供全面指导。此技能强调权衡、明确边界和生产就绪实践(性能、可访问性、安全性、测试、交付)。
核心原则: 架构中的一切都是权衡。没有“正确”答案,只有针对您特定上下文的最佳组合。
操作模式(如何使用此技能)
激活时,按以下顺序工作:
- 澄清上下文(最多5-10个问题) → 用户、路由、SEO、交互性、数据、身份验证、团队、约束。
- 为每个路由选择渲染策略(不是“整个应用一个策略”)。
- 定义边界 → 功能/域模块、共享库、所有权和稳定接口。
- 规划状态+数据 → 本地/共享/全局/服务器/URL状态、缓存策略、失效、乐观更新。
- 规划非功能性 → 性能预算+测量、可访问性计划、安全态势、可观察性。
- 生成工件 → 带有明确权衡的简短建议,以及具体下一步步骤(文件夹结构、ADR、检查清单)。
如果用户无法回答问题,陈述合理假设并继续(不要阻塞)。
何时使用
- 启动新的SPA或Web应用
- 选择渲染策略(CSR、SSR、SSG、ISR、RSC)
- 实施状态管理
- 优化核心Web指标(LCP/INP/CLS)
- 扩展为多个前端团队
- 做出架构权衡决策
- 从传统前端迁移到现代前端
快速发现性问题(首先询问)
- 前3个用户旅程及其目标延迟是什么(例如,“搜索 → 产品 → 结账”)?
- 是否有任何路由需要SEO?哪些是公开的,哪些在身份验证后?
- 数据形态是什么:主要是CRUD、实时、离线优先、重表单、大型表格/图表?
- 约束是什么:浏览器支持、包限制、上市时间、合规性(SOC2/HIPAA/PCI)?
- 团队拓扑是什么:多少开发者/团队、发布节奏、所有权边界?
- 您的首选技术栈是什么(React/Vue/Angular/vanilla),是否接受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焦点管理、包容性组件、国际化陷阱 |
| @references/testing-and-quality.md | 测试策略、CI质量门、可访问性检查、合同测试 |
| @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(选择器、菜单) |
| 钩子 | 共享有状态逻辑,无需高阶组件 |
| 提供者 | 避免全局数据的属性传递 |
状态管理
| 方法 | 使用时机 |
|---|---|
| useState/useReducer | 本地组件状态 |
| Context | 主题、身份验证、低频率全局状态 |
| Zustand/Jotai | 简单全局状态,最小样板代码 |
| Redux Toolkit | 复杂状态、时间旅行调试 |
| React Query/SWR | 服务器状态、缓存、后台刷新 |
| XState | 具有明确状态机的复杂流程 |
性能要点
| 技术 | 影响 |
|---|---|
| 代码分割 | 减少初始包大小 |
| 延迟加载 | 推迟非关键内容 |
| React.memo | 防止不必要的重新渲染 |
| useMemo/useCallback | 稳定引用 |
| 虚拟列表 | 处理大型数据集 |
架构特性(选择3-7个)
| 特性 | 需问问题 |
|---|---|
| 可扩展性 | 多少并发用户?增长率? |
| 性能 | 可接受的TTI?LCP目标? |
| 可部署性 | 发布频率如何?独立部署? |
| 可测试性 | 验证变更的容易程度? |
| 可维护性 | 预期寿命? |
| 模块性 | 需求变更频率? |
需避免的反模式
| 反模式 | 问题 | 修复 |
|---|---|---|
| 属性传递 | 紧耦合 | 上下文或状态管理 |
| 上帝组件 | 职责过多 | 按关注点拆分 |
| 过早优化 | 无证据的复杂性 | 先性能分析 |
| 共享可变状态 | 竞态条件、错误 | 不可变模式 |
| 单体包 | 慢初始加载 | 代码分割 |
| 过度获取 | 浪费带宽 | GraphQL或BFF |
| 默认使用LocalStorage令牌 | XSS导致账户接管 | 优先httpOnly cookies + CSP(见安全参考) |
| 用于服务器数据的全局存储 | 缓存失效困难 | 使用React Query/SWR处理服务器状态 |
性能预算
预算必须根据您的用户/设备校准,但这些是“默认快速”应用的良好起点:
| 指标 | 目标 | 需改进 |
|---|---|---|
| LCP | <2.5s | 2.5–4s |
| INP | <200ms | 200–500ms |
| CLS | <0.1 | 0.1–0.25 |
| TTFB | <800ms | 800ms–1.8s |
| 路由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