前端到底发生了什么?
沿着前端二十年的真实问题,理解 jQuery、组件框架、构建工具、SSR、Islands 与 AI 编程为何依次出现。
原文: What Happened to the Frontend While You Weren’t Watching ↗
作者: David Poblador i Garcia
本文为中文翻译与摘编,依据 CC BY-SA 4.0 ↗ 许可发布。
The Descent — What Happened to the Frontend While You Weren’t Watching
你上一次写前端时,它可能还只是一个
<button>和一次 FTP 上传。花二十分钟,看看你移开视线后,Web 世界究竟发生了什么。
核心观点
Every tool is scar tissue over a real wound. Follow the wounds, and the map draws itself.
每一种工具都是真实伤口上长出的疤痕。沿着这些伤口追溯,前端技术的地图就会自行浮现。
现代前端的复杂性并非凭空产生。每一层工具都解决了上一层真实存在的问题,同时又制造了新的问题:
- 原生 DOM 操作繁琐且浏览器行为不一致,于是有了 jQuery。
- 手动同步数据与界面容易出错,于是有了声明式 UI 和组件框架。
- JSX、模块化与旧浏览器兼容需要转换,于是有了构建步骤。
- 构建越来越慢、配置越来越复杂,于是工具开始用 Go 和 Rust 重写。
- 纯客户端应用首屏慢、SEO 差,于是渲染回到了服务器。
- 大型应用难维护、重复造组件,于是 TypeScript、组件库和一整套工程工具成为标配。
- 部署仍然麻烦,于是 Git push、预览环境、Serverless 和 Edge 成为新基础设施。
- 工具链复杂到人不想手写了,于是 AI 开始替人生成前端代码。
文章最后的反转是:走过二十年、穿过四十四米厚的工具层后,2026 年的前沿方向又回到了“服务器输出 HTML、尽量少发 JavaScript、依赖 Web 平台本身”。
2006–2010:jQuery——不刷新整个页面
“I just want to change the page without reloading the whole thing.”
“我只想修改页面的一部分,而不是重新加载整页。”
浏览器已经能通过 XMLHttpRequest 异步取数,但原生 DOM API 繁琐,而且不同浏览器之间差异巨大。jQuery 抹平了兼容性问题,让 AJAX 真正普及。
然而,当数据同时存在于 JavaScript 变量和屏幕上时,开发者就成了人工同步器:价格变化后,需要自己更新购物车总价、角标、按钮和摘要。漏掉任何一处,界面就会欺骗用户。
作者将这种不断手动操作 DOM 的方式称为后续一切技术试图弥补的“原罪”。
2010–2015:组件框架——让界面跟着数据变化
“Stop making me sync the screen to my data by hand.”
“别再让我手动同步屏幕和数据了。”
解决方案是声明式 UI:不再告诉浏览器“找到角标并修改文字”,而是描述“在这份数据下,界面应该是什么样子”,由框架计算具体更新步骤。
组件成为前端的基本构造单元:一个组件封装自己的结构、行为和局部状态,并像积木一样组合。
- React:组件、JSX、Virtual DOM。
- Vue:降低使用门槛。
- Angular:企业级结构与 TypeScript。
- Svelte:在编译阶段消除框架运行时。
- Solid:保留 JSX,但用细粒度更新替代 Virtual DOM。
- Signal:让值知道谁依赖它,只更新真正受影响的部分,逐渐成为各框架汇合的方向。
一个原本独立存在的 <button>,从此拥有 state、props 和父组件树,并依赖框架运行时;接下来,它还需要构建步骤才能被浏览器理解。
另一条从未消失的路线是 htmx、Alpine.js 和 Hotwire:它们认为真正的问题是前端离开了服务器,主张让服务器直接发送 HTML。
2012–2018:构建步骤——为什么不能再直接打开文件
“Why can’t I just open the file anymore?”
“为什么我不能直接打开这个文件了?”
构建步骤来自两项现实需求:
- JavaScript 长期缺乏统一的模块系统,社区先后出现 CommonJS 与 ES Modules。
- 开发者想使用 JSX 和旧浏览器不支持的新语法。
于是出现了完整的翻译和打包链:
- Babel:把新语法和 JSX 转译成旧浏览器可运行的 JavaScript。
- webpack / bundler:把大量模块拼接成少数文件,减少旧 HTTP 协议下昂贵的请求数。
- minification:移除不必要字符,减小体积。
- tree shaking:删除没有使用的代码。
- code splitting:按需拆分产物。
- source maps:让开发者仍能调试原始代码。
代价则是 node_modules:一个空白项目也可能带来几十万个文件。一个 22 字节的按钮,最终可能藏在 2 MB 的 bundle 和一份没人敢碰的配置文件之后。
2018–2024:工具军备竞赛——把一切用 Rust 或 Go 重写
“Fine, there’s a build. Just make it stop taking ninety seconds.”
“好吧,构建就构建,但别再让它花九十秒。”
构建本身变成了新的痛点。webpack 配置像代代相传的黑魔法,JavaScript 编写的工具速度也不够快。解决办法是用编译型语言重写基础工具:
- esbuild(Go):将打包速度提高一个数量级。
- SWC(Rust):在大型框架中替代 Babel。
- Vite:开发阶段利用浏览器原生模块与 esbuild,实现快速启动和 HMR;生产阶段再进行优化构建。
- Rolldown、Turbopack、Rspack、Oxc:继续整合并加速工具链。
- pnpm、Bun、Deno:包管理与运行时也加入速度竞赛。
这一阶段最具代表性的话是:“我们用 Rust 重写了它,现在快了 50 倍。”
2014–2026:服务器回归——为了解决白屏与 SEO
“My beautiful app shows a blank white screen and Google can’t see it.”
“我漂亮的应用只显示一片白屏,而且 Google 什么也看不到。”
纯客户端 SPA 往往只从服务器收到一个空 <div> 和大量 JavaScript。用户必须等待脚本下载、解析和执行后才能看到页面;搜索引擎看到的也可能只是空壳。
解决办法竟然是重新在服务器上生成 HTML——也就是 2008 年已经在做的事:
- SSR:每次请求都在服务器生成 HTML。
- SSG:部署时预生成静态 HTML。
- ISR:在 SSG 基础上定期或按需刷新。
- Next.js、Astro、SvelteKit、Nuxt、Remix / React Router:负责协调服务端渲染、路由、数据和构建的元框架。
Hydration tax
服务器输出 HTML 又带来了 hydration:
- 服务器先运行组件并生成可见的 HTML。
- 页面看起来已经完成,但按钮还没有事件处理器,只是 UI 的“照片”。
- 浏览器下载 JavaScript,再运行一遍应用,把静态 HTML “唤醒”。
Hydration is paying for the meal twice: once to cook it on the server, once to cook the identical meal in the browser to prove it’s edible.
Hydration 就像为同一顿饭付两次钱:服务器先做一遍,浏览器又把同一顿饭做一遍,只为了证明它可以吃。
之后流行的技术,大多是在设法减少 hydration:
- Islands(Astro):页面大部分保持静态,只激活少量交互岛屿。
- Resumability(Qwik):跳过传统 hydration,直接恢复运行状态。
- React Server Components:组件仅在服务器执行,不向浏览器发送对应 JavaScript;只把交互叶节点标记为客户端组件。
2015–2026:成熟应用的附加层
“This codebase is unmaintainable and I keep rebuilding the same dropdown.”
“这个代码库已经无法维护,而我还在反复重写同一个下拉菜单。”
随着应用规模增长,安全重构和复用 UI 成为新的核心问题。
- TypeScript:给 JavaScript 增加类型系统,提前捕获一整类错误并改善编辑器体验。作者认为,这是离开旧前端后最值得关注的变化。
- Tailwind CSS:用 utility classes 直接组合样式;看似回到内联样式,却成为许多团队高效交付 UI 的方式。
- 现代 CSS:原生支持变量、嵌套、容器查询、
:has()等能力,替代了不少旧工具。 - shadcn/ui + Radix:组件不再只是安装进来的黑盒依赖,而是复制到仓库、由项目自己拥有的源码。
- TanStack Query、Zustand、Zod:分别处理服务端数据、少量客户端状态和数据校验。
- Vitest、Playwright:覆盖单元测试与端到端测试。
此时的按钮确实更好了:默认无障碍、支持主题、类型安全。但为了渲染一个 “Buy”,背后站着整个生态系统。
2015–2026:Git push 成为新的 FTP
“Okay. How do I just put it on the internet?”
“好吧,我怎样才能把它放到互联网上?”
这是文章认为毫无争议地优于 2008 年的一层:把 Git 仓库连接到 Vercel、Netlify 或 Cloudflare 后,每次 push 都会自动构建和部署;每个 Pull Request 还能获得独立的在线预览地址。
- Serverless functions:不用管理服务器,也能运行后端代码。
- Edge:代码运行在靠近用户的全球数据中心,而不是唯一的中心机房。
- React Native / Expo:把 Web 技能延伸到原生移动应用。
- Tauri / Electron:把 Web 技能延伸到桌面应用。
作者的概括:Git push 就是新的 FTP,而且它确实更好。
2023–2026:机器人开始写前端
“Honestly, can the machine just write the React for me?”
“说真的,能不能让机器直接替我写 React?”
v0、Lovable、Bolt 可以从自然语言生成可运行的前端;Cursor、Claude Code、Copilot 等工具则直接在代码库中生成和修改代码。Vibe coding 让后端或系统工程师也能在短时间内做出可信的前端。
但生成出来的代码默认使用前面八层技术。真正的风险不是 AI 不会写,而是开发者并不理解它悄悄替自己做出的所有技术选择。
走到基岩:前沿又回到了 HTML
You dug forty-four meters and hit your own front porch.
你向下挖了四十四米,最后却挖到了自家门廊。
2026 年令人兴奋的方向是:
- 在服务器生成 HTML。
- 向浏览器发送尽可能少的 JavaScript。
- 尽量使用 Web 平台原生能力,而不是与它对抗。
- 从 CDN 提供快速、以 HTML 为主的页面。
Astro、Islands、Server Components、htmx 看似来自不同流派,却都指向同一个方向。行业绕了一个巨大的圆,又回到了类似当年 FTP 上传的静态页面,只是带回了二十年间积累的工程能力。
You don’t have to relearn the whole cathedral. You have to learn which 20% is load-bearing, and recognize the other 80% as a buffet you can walk past.
你不必重新学会整座大教堂。你只需要知道哪 20% 是承重结构,并意识到另外 80% 只是可以径直走过的自助餐。
作者给出的 2026 工具包
内容站、博客、营销页面
- Astro:默认几乎不发送 JavaScript。
- Tailwind 或现代原生 CSS。
- Vercel、Netlify 或 Cloudflare:通过 Git push 部署。
- 更轻的选择仍然完全有效:htmx + 熟悉的后端,或手写 HTML + CDN。
登录后使用的产品型应用
- React + Next.js:资料和生态最丰富。
- TypeScript + Tailwind + shadcn/ui:类型、样式与组件。
- TanStack Query + 少量 Zustand:服务端与客户端状态。
- Zod:验证所有外部数据。
底层工具
- Vite,或框架自带 CLI。
- pnpm 或 Bun。
- Prettier + ESLint,或用 Biome 同时承担两者。
- Vitest + Playwright。
- 用 Git push 部署,最好永远不需要亲自打开 webpack 配置。
概念速查
| 概念 | 全称 | 含义 |
|---|---|---|
| SPA | Single Page Application | 只有一个 HTML 外壳,由 JavaScript 构建和切换界面,不执行整页刷新。 |
| SSR | Server-Side Rendering | 每次请求由服务器生成 HTML,再由浏览器 hydration。 |
| SSG | Static Site Generation | 部署时预先生成所有 HTML,之后作为静态文件提供。 |
| RSC | React Server Components | 只在服务器运行、不会向浏览器发送对应 JavaScript 的组件。 |
| Hydration | — | 在浏览器中重新运行 JavaScript,让服务端生成的 HTML 具有交互能力。 |
| Islands | — | 页面大部分静态,只为少数交互“岛屿”发送 JavaScript。 |
| HMR | Hot Module Replacement | 保存文件后立即看到变化,不进行完整刷新。 |
| ESM / CJS | ES Modules / CommonJS | 现代 import 标准与 Node.js 旧式 require 模块系统。 |
| JSX | — | 写在 JavaScript 中、外观类似 HTML 的语法,需要转译,不是真正的 HTML。 |
| CWV | Core Web Vitals | Google 衡量绘制、响应速度和布局偏移等体验的性能指标。 |
| Edge | — | 代码运行在靠近用户的众多 CDN 节点,而不是单一数据中心。 |
我的摘录总结
这篇文章最有价值的不是工具清单,而是它提供了一条判断技术复杂性是否合理的线索:先找伤口,再看疤痕。
面对任何新框架或新工具,可以先问:
- 它具体解决了哪个真实问题?
- 这个问题在我的项目中是否真的存在?
- 它为此引入了什么新的复杂性?
- 原生平台是否已经补上了过去缺失的能力?
- 我需要的是承重的 20%,还是正在从自助餐里拿走不必要的 80%?
原文链接:https://davidpoblador.com/deep-dives/what-happened-to-the-frontend/ ↗
原文发布于 2026-06-29,采用 CC BY-SA 4.0 ↗ 许可。