Web 平台五层职责与选型对比
最后核验:2026-06-30|适用范围:现代常青浏览器|目标:判断原生平台何时足够、何时引入框架
五层不是五套互斥技术
HTML、CSS、JavaScript、TypeScript 和 Web APIs 位于同一条交付链的不同层。框架通常组合这些能力,不会替代浏览器解析、层叠、语言求值或安全模型。
| 层 | 主要输入 | 主要输出 | 不负责什么 | 首要调试入口 |
|---|---|---|---|---|
| HTML | 响应码点流 | DOM、语义与默认交互 | 视觉布局、业务状态 | Network、Elements、Accessibility |
| CSS | DOM、样式规则、环境 | 计算样式、布局与像素 | 权限、业务真值 | Computed、Layout、Performance |
| JavaScript | 值、模块、事件 | 状态转换与命令 | DOM/Fetch 的宿主定义 | Sources、Performance、Memory |
| TypeScript | TS 源码与声明 | 诊断、JS、可选 .d.ts | 运行时数据验证 | tsc 诊断、trace |
| Web APIs | 浏览上下文与策略 | 网络、存储、DOM、后台计算 | 服务端授权、持久可靠后端 | Network、Application、Security |
按约束分配职责
需求先分解为稳定事实、短暂状态、视觉约束、异步副作用和信任边界,再分配技术:
- 可读内容与键盘基础版本进入 HTML。
- 空间与环境条件进入 CSS,业务条件不藏进选择器。
- 纯状态转换与模块协作进入 JavaScript。
- 模块内部关系与公开契约由 TypeScript 检查。
- 网络、URL、持久化、观察和并行计算使用对应 Web API。
- 服务器重新验证所有请求并执行权限控制。
这个顺序能让每层只承担自己能验证的保证。比如 TypeScript 可以保证 render(entries) 接收 TechnologyEntry[],但只有边界验证器能证明 JSON 确实满足该类型;CORS 可以决定页面能否读取跨源响应,但只有服务器授权能决定用户是否有权读取资源。
原生与框架决策表
原生/框架决策表不按团队偏好打分,它只判断约束是否已经超出局部页面能够清楚维护的范围。
| 约束 | 原生平台通常足够 | 考虑框架或元框架 | 需要先取得的证据 |
|---|---|---|---|
| 交互规模 | 少量页面、状态局部、事件路径短 | 大量复合组件、跨路由共享状态 | 状态图、重复实现位置 |
| 团队协作 | 单团队、清晰模块边界 | 多团队需要统一组件生命周期与规范 | 所有权冲突、集成成本 |
| 渲染策略 | 静态 HTML 或客户端增强 | SSR、流式渲染、部分水合有明确收益 | SEO、首屏与服务器指标 |
| 路由与数据 | URL + Fetch 可直接表达 | 嵌套路由、loader、缓存失效高度重复 | 导航竞态、错误边界清单 |
| 生态需求 | 标准 API 已覆盖 | 需要成熟组件、表单、国际化或平台适配生态 | 自建成本与维护周期 |
| 浏览器目标 | 现代常青浏览器 | 需统一大量兼容分支 | 真实用户浏览器范围 |
| 发布边界 | 一个应用或嵌入页 | 多包、设计系统、独立部署单元 | 版本和依赖图 |
只要“框架更熟”不是充分理由,但“原生更轻”也不是。框架的固定成本包括运行时、编译、升级与抽象调试;收益包括组件约定、声明式更新、成熟路由和生态。用真实约束比较两边的总成本。
三个约束示例
约束示例一:固定知识目录
41 条 JSON、一个页面、同步搜索、详情与四项对比。原生 HTML/CSS/TypeScript 足够:状态可放一个对象,搜索是一次数组过滤,URL 恢复由标准 API 完成。引入组件框架不会减少核心复杂度,反而增加构建与运行时层。
升级信号:条目视图在多个路由重复、详情出现独立数据加载与错误边界、团队开始共享复合组件。到那时再比较框架,现有领域函数和语义 HTML 仍可复用。
约束示例二:多团队运营后台
数十个路由、权限控制的导航、复杂表单、服务端分页、共享设计系统和独立团队交付。框架通常能用一致组件与路由生命周期降低协作成本,但权限仍由服务端执行,表格语义和浏览器性能仍需平台知识。
在选框架前先固定数据契约、错误语义和可访问验收,否则框架只会让不明确需求传播得更快。
约束示例三:内容站点加少量互动
文章占主体,只有搜索、主题和几个演示。优先服务端或静态生成 HTML,再按交互岛增强。完整单页应用会让无脚本阅读、缓存与首屏承担不必要成本。若内容预览、个性化和跨页面工作流后来成为核心,再重新评估水合范围。
不随框架消失的浏览器约束
| 约束 | 框架能帮助什么 | 框架不能替你保证什么 |
|---|---|---|
| HTML 解析与语义 | 提供组件模板与开发期警告 | 合法内容模型、最终可访问名称 |
| CSS 层叠与布局 | 隔离命名、生成样式 | 计算值、溢出、渲染成本 |
| 事件循环 | 批量更新、调度任务 | 消除长任务或微任务饥饿 |
| 网络 | 封装 loader、缓存和重试 | HTTP 语义、幂等、安全授权 |
| 类型 | 生成路由或接口类型 | 验证不可信运行时输入 |
| 存储 | 提供适配层 | 用户清理、配额、同源与隐私分区 |
调试时应能绕过框架名称回到平台证据:最终 DOM 是什么、哪条 CSS 赢、哪个 task 阻塞、请求状态是什么、输入在哪个边界被验证。
最小决策流程
决策记录至少包含:目标浏览器、路由与状态规模、渲染位置、无障碍要求、性能预算、团队所有权、测试入口、迁移与回退路径。缺少这些信息时,技术偏好无法被审查。
贯穿示例为什么选择原生平台
贯穿示例选择原生平台和 TypeScript 6.0,原因是需求能被一个语义文档、一个样式表、三个领域模块和一个协调入口完整覆盖。41 条数据同步搜索最简单;Worker 只作为显式压力演示;主题使用 localStorage,分享状态使用 URL,外部数据在唯一入口验证。
示例没有加入组件基类、依赖注入容器、通用 store、客户端路由、CSS-in-JS、构建器和测试框架,因为当前需求尚不需要这些能力。进入前端框架阶段后,再以相同功能实现 React、Vue、Angular 和 Svelte,框架差异才有可比较的对照。
现有内容是否足以支撑需求
| 文章 | 重点 | 难点 | 需要防止的严重故障 | 演进判断 |
|---|---|---|---|---|
| HTML | 解析、语义、表单 | 源文本到 DOM 与可访问性树 | 阻塞脚本、非法内容模型、失焦、自定义控件缺行为 | Living Standard + 功能级 Baseline |
| CSS | 层叠、布局、查询 | 包含块、格式化上下文与渲染阶段 | 整页溢出、层叠层迁移、布局型动画 | 按模块和目标浏览器采用 |
| JavaScript | 对象、集合、模块、异步 | 绑定、迭代协议、任务与可达性 | 循环依赖、微任务饥饿、陈旧异步结果、内存保留 | ECMAScript 年度快照 + 运行时支持 |
| TypeScript | 类型关系与可信边界 | 高阶推断、模块解析、声明输出 | 用断言接收不可信数据、升级后声明不兼容 | 当前稳定版 + 独立迁移 CI |
| Web APIs | 请求、存储、并发、权限 | 生命周期、事务、取消、恢复 | 重复写、存储升级阻塞、跨源误判、唯一副本丢失 | 标准、Baseline、权限与隐私策略 |
基础平台没有统一 major 发布,因此“不适用的重大重构”不能用空泛版本史填充。这里记录会改变输入、处理过程、输出或失败模式的规范与实现演进;框架级重构和安全公告留到前端框架阶段讨论。
验收问题
- 能否为一个需求指出它属于哪一层,以及为什么不属于相邻层?
- 能否举例说明 TypeScript、CORS 和 CSP 各自不能保证什么?
- 能否用状态规模、渲染策略或团队协作证据支持框架选择?
- 能否在框架应用中仍用浏览器工具定位 DOM、层叠、任务和请求问题?
- 能否删除当前方案里没有约束支撑的抽象?
进一步阅读:HTML、CSS、JavaScript、TypeScript、Browser / Web APIs 与专栏总结。