











学习计算机科学就是在学习计算机历史
我们常把互联网比作冰山,在冰山之下,数以万计的交换机 / 服务器 / 数据库在轰隆作响
而对于屏幕前的用户,某个拿着手机坐在地铁里的人,或者坐在办公桌前盯着显示器的白领而言,只有屏幕上的像素点是真实的
如果那个”commit”按钮点下去没有反应;如果那个列表滑动起来一卡一卡;如果那个页面在加载时白屏
那么,无论后端的架构多么优雅,算法多么精准,对于用户来说,这就是一个 垃圾软件
在很长一段时间里,前端被戏称为切图仔
在软件开发的鄙视链中,前端曾经往往处于底端
后端工程师认为前端只是写写 HTML 标签、描描样式,不需要懂内存管理,不需要懂并发控制,甚至不需要懂真正的编程语言。
然而,这三十年的历史证明了这种偏见的荒谬。前端开发正在经历计算机科学史上最剧烈,最残酷的演变。我们从最初仅仅是为了展示一篇物理论文,演变到现在要在浏览器这个沙盒里运行 Photoshop、3D 游戏、甚至是 IDE
本篇 blog 要讲的,不是 API 的流水账,而是这三十年来前端的「三国演义」
观前提醒:本文是以我的个人视角叙述,难免有误,还请各位谅解 / 多多指出错误。
要理解前端这三十年为什么这么闹腾,为什么框架层出不穷,为什么工具链复杂到让人头秃,我们必须回到原点,去审视 Web 诞生的初衷
WWW 在 1990 年诞生时,Tim Berners-Lee 爵士的设计目标非常纯粹:为了让科学家们方便地共享文档
请记住文档这两个字。这是前端所有痛苦和复杂的根源,也是我认为的原罪
随着商业化的爆发,人类越来越想要更多。我们要的不再是一张静态的纸,我们要的是一个 App
这就好比要求你在 Microsoft Word 里开发一个 Minecraft
前端这三十年在做的事情,本质上就是:
利用一系列原本为静态文档设计的简陋技术,通过各种奇技淫巧,强行构建出媲美原生操作系统软件的动态应用
前端的演进史,就是一部与浏览器的对抗史。我们在对抗浏览器的限制,对抗网络的延迟,对抗设备的碎片化
在读本 Blog 时,你会发现一个非常有趣的现象:技术的轮回
人类绕了一圈,似乎回到了原点?
不
当年的静态,是因为我们做不到动态
现在的静态,是因为我们掌握了动态之后,为了极致体验而做出的主动选择
在 2000 年,只要会写 <table> 布局和 <font> 标签,你就是前端(那时候其实叫网页设计师)
在 2010 年,只要你会用 jQuery 的 $('#id').click(),你就是前端 现在,你需要会 Ts,即时编译,HTTP/3,服务端容器化等等
前端的边界在无限扩张。
向上,我们在侵蚀后端的领地推出 Serverless(尽管现在不尽人意)
向下,我们在通过 WebAssembly 调用 C++/Rust 的能力
向外,我们在通过 React Native / Flutter 构建原生 App
但无论技术栈如何变迁,有一点我希望阅读本文的前端开发者记住:
我们是离用户最近的人
一切的起点,并不宏大。没有风险投资,没有 IPO,甚至没有想改变世界
1989 年,蒂姆·伯纳斯-李(Tim Berners-Lee)在 CERN 工作时,面临着一个非常具体的痛点:物理学家们的论文和数据太难找了。它们分散在不同的计算机上,格式各异,如果你想引用别人的研究,只能手动去查
于是,他提出了一个构想:World Wide Web
为了实现这个构想,他拿出了三块拼图,这三块拼图至今仍是互联网的基石:
1990 年圣诞节,他在那台 NeXT 电脑上写出了世界上第一个浏览器和第一个服务器
那时的网页长什么样?
Only text 只有白纸黑字和蓝色的超链接。图片还需要弹出一个新窗口才能看
这时候的前端开发,和写 word 没什么区别。你只需要掌握 <h1>、<p>、<a> 这几个标签就够了。这是一个Read-Only的时代
随着 Mosaic 浏览器的发布(第一个广泛流行的图形化浏览器),图片终于可以和文字混排了。商业公司开始入驻互联网,设计师们带着平面设计的思维来了
炸了
设计师说:我要在这个角落放个 Logo,在大标题下面分三栏排版,右边还要有一个 Guide
工程师看着简陋的 HTML 说:把哥们当日本人整呢
当时的 HTML 只有文档流。没有 Float,没有 Position,更没有 Flexbox
怎么办?聪明或者说被逼无奈的开发者们发现了一个漏洞:HTML 里有一个用来展示数据的标签<table>,也就是表格
如果你把边框设为 0 (border="0"),表格线不就看不见了吗?
如果你在表格里套表格,不就可以切分出复杂的版块了吗?
于是,表格布局时代开始了
<table> 把它们拼回去<img src="spacer.gif" width="10" height="1">这是前端工程史上第一次大规模的为了目的不择手段。虽然代码语义极差,维护极其困难(改一个字可能导致整个表格崩塌),但它让网页第一次有了设计感
1995 年,Netscape 正处于第一次浏览器大战的风口浪尖。他们面临一个巨大的压力:让网页动起来
当时的痛点非常低级:表单验证
那是拨号上网的年代,网速慢得令人发指。用户在网页上填完一个长长的注册表单,点击提交,数据传到服务器,服务器发现用户名为空,再把页面传回来告诉用户报错。这一来一回,可能要几十秒甚至一分钟。用户直接炸了
网景觉得,必须有一种脚本语言,能直接在浏览器里检查表单,不需要经过服务器
这个任务交给了 Brendan Eich
这门语言最初叫 Mocha,后来改名 LiveScript,最后在发布前夕,为了营销,改名为 JavaScript
这就是后来无数人吐槽 JS 的根源:
null 和 undefined 同时存在,甚至 typeof null === 'object' 这种著名的 Bug 被保留至今[] + [] = "")它被设计为一个玩具语言,仅仅用来做一些鼠标滑过图片变色、弹出 alert 对话框、检查输入框不为空的小把戏
当时的专业程序员 (比如写 Java 的) 对 JavaScript 是嗤之以鼻的。他们认为这不是编程,这是脚本片段
但潘多拉盒子已经打开了
哪怕它再简陋,它赋予了浏览器逻辑计算的能力
有了逻辑,网页就不再只是文档,它开始向 app 进化
那时的前端,就在这一堆乱七八糟的表格标签、透明图片占位符、以及几行简陋的脚本验证代码中,跌跌撞撞地开启了 Web 的商业化时代
而就在不远的前方,一个名叫 Microsoft 的巨头马上就要睡醒了
1996 年,Netscape Navigator 占据了近 80% 的市场份额。那时的浏览器是收费软件(或者说是共享软件),它是通往互联网的唯一大门
但比尔·盖茨醒了。他发出了那封著名的《互联网浪潮》备忘录,微软这艘航母开始全速掉头
微软采用了经典的Embrace, Extend, Extinguish战略:
<layer> 标签和 <blink>(闪烁文本,我认为是史上最烦人的标签)<iframe > 和 <marquee>(滚动字幕)document.layers 操作元素,微软用 document.allif (document.all) { ... } else { ... }。这就是浏览器嗅探代码的鼻祖1998 年,网景惨败,被 AOL 收购。但在临死前,他们做出了一个改变历史的决定:开源(噔 噔 咚)
他们把 Netscape 混乱的代码全部扔给了社区,成立了 Mozilla。这颗种子在地下埋藏了许多年,终长成名为 Firefox 的大树
2001 年 8 月,Windows XP 发布,随之而来的是 Internet Explorer 6.0
我们需要客观地评价这位昔日的王者。在 2026 年回看 IE6,它是落后、各种 Bug、不安全的代名词。但在 2001 年,IE6 是当时世界上最先进的浏览器,没有之一(毕竟不能拿现在的眼光审视过去)
ActiveXObject("Microsoft.XMLHTTP") 正是随 IE5/6 引入的IE6 迅速占据了 95% 的市场份额。微软赢了,于是他们解散了浏览器团队(笑死)
Web 的时间停止了
从 2001 年到 2006 年,整整五年,浏览器技术没有任何实质性的进步。这五年我称为Web 的黑暗中世纪
对于前端(这时候开始有专职的前端了),这五年是与 Bug 搏斗的五年:
width 是内容宽度,IE6 说 width 是包含边框的宽度。于是我们学会了 CSS Hack:_width: 200px;(只有 IE6 认识下划线开头的属性)AlphaImageLoader) 或者继续用 GIFdisplay: inline我们不再是构建者,而是修东西的。前端开发的门槛变成了一门玄学,你必须背诵几十个 IE6 的怪癖才能写出一个正常的页面
在 HTML/CSS 停滞不前、标准分裂的年代,人类对动态交互的渴望并没有消失。这种渴望在两个方向上找到了出口
DHTML (Dynamic HTML) 不是一个标准,而是一个营销词汇
它指的是:利用 JS 修改 CSS 属性,让静态的 HTML 动起来
那是特效的年代
大部分前端并不会写 JS,他们是脚本搬运工。他们去 DynamicDrive.com 这样的网站,复制一段几百行的 JS 代码,粘贴到网页里,然后改改参数。JS 在当时被视为一种装饰品,一种让网页看起来很酷(或者很杀马特)的玩具
既然 HTML 这么烂,不同浏览器渲染还不一致,那为什么不跳出浏览器呢?
Macromedia Flash(后被 Adobe 收购)横空出世
它实际上是一个浏览器里的虚拟机
在那个年代,最顶级的前端工程师其实是 Flash Developer。他们做出了开心农场,做出了视频网站(土豆 / 优酷的早期播放器),做出了极其华丽的企业官网
Flash 是 Web 2.0 真正的前奏
它证明了网页可以不仅仅是文档,而可以是游戏、电影和复杂的应用
但它是一个黑盒子。搜索引擎看不懂它,移动设备(后来的 iPhone)跑不动它
就在这看似无解的僵局中,Web 正在酝酿一场真正的革命
而在遥远的 CA,Google 正在悄悄重写 Gmail 的代码,准备用 IE6 那个被遗忘的 XMLHTTP 接口,给世界一点小小的震撼
2004 年愚人节,Google 发布了 Gmail。当时所有人以为这是个笑话,因为它提供了 1GB 的免费存储空间(当时主流邮箱只有 2MB)
但真正让极客们震惊的不是容量,而是体验
在此之前,网页交互的模式是同步的:
而在 Gmail 里,当你点击邮件标题时,网页没有刷新。列表保留在左边,邮件内容瞬间出现在右边。
这种体验太像原生 app 了,以至于很多人怀疑 Google 用了 Flash 或者 Java Applet
并没有 他们用的是纯正的、原生的、被微软遗忘在角落里的技术 XMLHTTP
从此,网页有了后台线程
它可以在你不注意的时候,悄悄去服务器拿数据。网页开始呼吸了
AJAX 中的 “X” 代表 XML。在当时,数据交换的标准格式确实是 XML
但是,在 JavaScript 里解析 XML 简直是灾难。你得写一堆 getElementsByTagName,代码冗长且慢
这时候,一位名叫 Douglas Crockford 的雅虎架构师站了出来
他发现 JavaScript 有一种原生的数据表示法——对象字面量
PRTCL // JAVASCRIPT
// XML
<user><name>Chongxi</name><age>23</age></user>
// JSON
{ "name": "Chongxi", "age": 23 }
Crockford 甚至没有发明它,他只是发现了它。他把这种格式命名为 JSON
eval(),虽然不安全)这是 Web 历史上最四两拨千斤的胜利
由于前端开发者的极力推崇,后端工程师发现生成 JSON 也比生成 XML 容易。于是,AJAX 里的 “X” 名存实亡,JSON 统治了世界
在 2006 年之前,调试 JS 的唯一工具是: alert('Here 1'); alert('Variable x is: ' + x);
开发者像瞎子一样摸索。如果代码出错了,IE 只会左下角报一个黄色感叹号,告诉你缺少对象,行号永远是不准的
2006 年 1 月,Joe Hewitt 发布了 Firefox 的插件 Firebug
console.log() 终于取代了 alert()Firebug 是前端工程化的第一块基石 它让前端开发从玄学瞎猜变成了科学观测
虽然有了 AJAX,有了 Firebug,但前端开发依然极其痛苦 痛点在于:碎片化
document.getElementByIdgetElementsByClassName。你得自己写循环去遍历 DOMaddEventListenerattachEventgetComputedStylecurrentStyle每个前端工程师的电脑里都有一个 utils.js,里面存着几百行用来处理兼容性的脏代码
2006 年 8 月,John Resig 在 BarCamp NYC 上发布了 jQuery
它的核心理念极其简单粗暴:把所有浏览器差异藏在 $ 符号后面
jQuery 发明了一种极具表现力的 API 风格——链式调用
以前的代码:
PRTCL // JAVASCRIPT
var div = document.getElementById('CEPATO');
div.style.color = 'red';
div.style.display = 'block';
div.onclick = function() { alert('clicked'); };
jQuery 的代码:
PRTCL // JAVASCRIPT
$('#CEPATO').css('color', 'red').show().click(function() {
alert('clicked');
});
div > ul.list li:first-child)。这在当时是黑科技$('.item').hide() 会自动隐藏页面上所有的 .item,不需要写 for 循环jQuery 迅速成为了事实标准。甚至微软后来都在 Visual Studio 里内置了 jQuery 的智能提示
jQuery 的另一个伟大之处在于它的插件机制 ($.fn.extend)
这开启了前端最早的组件化雏形
无数不懂 JS 原理的切图仔,靠着下载 jQuery 插件 + 改 CSS,就能拼凑出一个交互丰富的网站
jQuery 极大地降低了前端门槛,但也埋下了祸根: 大量的面条代码和滥用的 DOM 操作,导致页面性能越来越差
随着 AJAX 和 jQuery 的普及,网页里的 JS 代码量指数级增长
从几百行,变成了几千行,甚至几万行…然后
浏览器跑不动了
当时的 JS 引擎都是解释执行的:读一行,跑一行。效率极低
Web 应用想取代桌面软件,最大的瓶颈就是慢
2008 年 9 月,Google 发布了一本漫画书,介绍了一款新浏览器:Chrome
与之同来的,是一个全新的 JS 引擎:V8
V8 做了一件惊天动地的事:JIT
它不解释代码,它是把 JavaScript 直接编译成机器码运行
V8 的出现改变了一切
与此同时,Apple 开源的 WebKit 内核(源自 KHTML)开始崛起。Safari 和早期的 Chrome 都使用了 WebKit
它是移动互联网的基石。第一代 iPhone 发布时,乔布斯不支持 Flash,只支持 Web 标准
这意味着,即将到来的移动 Web 浪潮,将是 WebKit 的天下…吗?
至此,前端已经拥有了:
万事俱备
但随着代码量的膨胀,我们即将迎来一场巨大的危机
我们有了枪炮,但还缺乏战术。我们写得出炫酷的特效,但维护不了庞大的系统
接下来咱就要讲工程化与架构革命,Node.js 登场,前端终于要开始像正经的软件工程师那样思考了
如果说前二十年,前端还是在浏览器这个沙盒里带着镣铐跳舞,那么从 2010 年开始,前端工程师通过一次惊天动地泣鬼神的越狱,彻底改变了游戏规则
2009 年的 JSConf EU 大会上,一个名叫 Ryan Dahl 的年轻人做了一场演示
他做了一件看似违背祖宗的事情:他把 Google Chrome 里的 V8 引擎抠了出来,给它装上了文件系统和网络模块,让它跑在了服务器上
这就好比把法拉利的引擎拆下来,装在了一台拖拉机上
这个项目叫 Node.js
起初,大家以为它是后端技术的革命(非阻塞 I/O,高并发)
但很快,前端工程师们发现了一个惊天秘密:补兑,既然服务器能跑 JS,那是不是意味着,我们可以用 JS 来写…
在此之前,如果你想压缩一个 JS 文件,你得用 Java 写的 YUI Compressor
如果你想预处理 CSS,你得用 Ruby 写的 Sass
前端开发者的工具链掌握在别人手里
Node.js 的出现,让前端拥有了造轮子的权利
2010 年,Isaac Z. Schlueter 发布了 npm
在这之前,如果我们想用 jQuery,得去官网下载 jquery.js,放到项目文件夹里,然后在 HTML 里写 <script src="jquery.js">。如果 jQuery 依赖了别的库,你根本不知道,直到报错
npm 改变了一切: npm install jquery
这不仅是一个下载工具,它引入了语义化版本控制 和 依赖树
前端代码不再是散落在各处的碎片,而是变成了一个有组织、可复用的模块体系
既然有了 Node.js ( 运行时 ) 和 npm ( 包管理 ),前端工程师开始编写自动化脚本
PRTCL // JAVASCRIPT
src('src/*.js')
.pipe(babel())
.pipe(uglify())
.pipe(dest('dist/'));
这是前端工程化的开端
我们不再手动刷新浏览器,不再手动压缩图片
前端开发从手工进化到了流水线
2010 年 4 月,Steve Jobs 发表了著名的公开信Thoughts on Flash
他列举了 Flash 的六大罪状(耗电、触摸屏支持差、封闭等),并宣布 iPhone/iPad 将永远不支持 Flash
这一刻,Web 的命运被改写了
移动互联网的大门轰然打开,而唯一的通行证是 HTML5
于是,所有的企业都需要开发移动版网页
但手机的 CPU 和网络比电脑差得多,屏幕也小得多
简单的 jQuery 特效在手机上卡顿无比。我们需要更高效、更像原生 App 的网页
随着需求越来越复杂(比如做一个网页版的 Excel 或 Trello),前端代码量突破了 10 万行
jQuery 的弊端彻底暴露:它把状态藏在了 DOM 里
想象一下,你要做一个购物车
span.total-price 里读出文本,转换成数字,加 1,再写回 span这种面多加水,水多加面的代码,错综复杂,被称为意大利面条代码
一旦项目变大,维护它简直是地狱
为了解决这个问题,前端开始向后端偷师,引入了经典的软件架构模式:MVC
核心思想是:数据(Model)是源头,视图(View)只是数据的投影
Backbone 非常轻量。它给了你 Model、Collection、View 三个基类
change 事件2009 年发布,2012 年爆火。AngularJS 带来了两个震撼世界的概念:
双向数据绑定:
PRTCL // HTML
<input ng-model="username">
<h1>Hello, {{ username }}</h1>
你在输入框里打字,下面的 <h1> 里的文字实时跟着变
不需要写任何 JS 事件监听代码 这在当时简直是魔法
依赖注入: 你想要用 $http 服务?只需要在函数参数里写上它,Angular 就自动给你送进来
AngularJS 让 HTML 变成了一种模版语言。它让开发效率提升了 10 倍
一时间,全世界都在用 Angular 重写项目。前端工程师觉得自己终于是在开发软件,而不是在写脚本了
在 Node.js 和框架爆发的同时,还有一个基础问题没解决:JavaScript 语言本身没有模块系统(直到 ES6)
我怎么在一个 JS 文件里引用另一个 JS 文件? <script> 标签不仅丑,而且依赖顺序很难管理(jquery.js 必须在 plugin.js 之前)
于是,民间标准诞生了:
require/module.exports)。是同步加载的,适合服务器,不适合浏览器(网络请求要等)define(['dep1'], function(dep1) { ... })。它是浏览器端的霸主这不仅是技术之争,也是社区话语权之争
至此,我们完成了工业化的初步积累
但是,AngularJS 的双向绑定在大规模应用中出现了严重的性能问题
而 FaceBook 的工程师们,正在为一个叫做 Instagram 的应用头疼。他们觉得 MVC 模式在前端也是错的
他们提出了一个更激进的想法:如果视图只是一个函数呢?
2013 年,当 Facebook 的工程师 Jordan Walke 开源 React 时,整个社区的反应是愤怒的
甚至有人说:这是把我们过去十年的努力全毁了
Why? 因为 JSX
在过去,最佳实践是关注点分离:HTML 归 HTML(模版),JS 归 JS(逻辑)
React 却说:不,我们要把 HTML 写在 JS 里
React 的核心洞察是:UI 渲染逻辑(事件处理、状态变化)和 UI 展示逻辑(DOM 结构)本质上是紧密耦合的。硬把它们分在不同文件里,只是物理分离,而不是逻辑分离
JSX 不是模版,它是 JavaScript 的语法糖。这意味着你拥有一门图灵完备语言的所有能力(变量、if/else、循环、函数)来描述界面,而不是只能用蹩脚的模版语法(ng-repeat, v-if)
这是一场思维革命:我们不再编写页面,我们在编写组件
React 被骂得最惨的时候,是它的性能拯救了它。 当时 Facebook 遇到了一个难题:在极其复杂的 Feed 流里,如何高效更新消息?
如果是 jQuery,你要手动找哪个 DOM 变了;如果是 Angular 1,它会疯狂地进行脏检查(Dirty Checking),导致页面卡顿
React 提出了 Virtual DOM:
这是数学的胜利
React 甚至不需要知道浏览器的存在。它把渲染抽象成了一个函数:UI = f(State)
只要状态变了,UI 就自动变。开发者再也不用碰 document.getElementById 了。手动操作 DOM 成为历史
React 只解决了 View,那数据怎么办?
Facebook 提出了 Flux 架构,后来 Dan Abramov 把它简化为 Redux
Redux 是极其繁琐的:Action, Reducer, Store, Dispatch。改一个字段要写四个文件
为什么我们要这么折磨自己?
因为在大型应用里,可预测性比便捷性更重要
Redux 治好了 MVC 时代的状态管理混乱症,虽然代价是大量的样板代码
就在 React 试图用函数式编程教育世界的时候,一个 Google 的前员工尤雨溪在想:有没有一种办法,既能有 Angular 的模版便利性,又有 React 的虚拟 DOM 性能?
2014-2015 年,Vue.js 开始爆发
它的核心哲学是渐进式
Vue 没有强迫你学会 JSX,它保留了 HTML 模版。这让无数从 HTML/CSS/jQuery 时代过来的开发者感到了温暖。在大中华区,Vue 成为了绝对的统治
叠甲:用「大中华区」表述单纯是因为个人习惯,不喜勿喷
Vue 2.0 最迷人的地方在于它的响应式系统 它利用了 ES5 的 Object.defineProperty(Getters/Setters)
data 时,Vue 会遍历它的所有属性,把它们变成 Getter/Setter这比 Angular 1 的脏检查高效,比 React 的手动 setState 自动化。它是魔法,但对于大多数开发者来说,这是一种幸福的魔法
在这个时期,前端工程师最痛恨的文件大概是 webpack.config.js
随着 SPA 的普及,一个项目可能有几百个 JS 文件、几十个 CSS 文件、几百张图片
Webpack 站出来说:在我眼里,Everything is a module
import './style.css'),图片也是模块(import img from './logo.png')Webpack 极其强大,也极其复杂。它甚至催生了一个新工种 Webpack 配置工程师
但也正是 Webpack,让前端终于有了工业级的构建流水线。我们终于可以做 Tree Shaking(摇树优化,用于去掉没用的代码),做按需加载
2015 年 6 月,ES6 (ECMAScript 2015) 正式发布
这是 JavaScript 诞生以来最大的更新:class, module, arrow function, promise, const/let
JS 终于像一门正经语言了
但是,浏览器(尤其是万恶的 IE)不支持啊
Babel(原名 6to5)出现了
它是一个编译器。它把 ES6 代码读进去,转换成等价的 ES5 代码吐出来
这意味着:前端开发者不再受限于用户的浏览器版本
我们可以使用 2026 年的语法标准写代码,通过 Babel 跑在 2010 年的浏览器上
这是前端自信心的极大提升:我们掌控了语言的发展权
到了 2018 年左右,随着项目规模突破百万行代码,弱类型的 JS 成了最大的隐患
“Cannot read property ‘x’ of undefined” 是所有线上事故的罪魁祸首
Microsoft 的 TypeScript 终于熬出头了
起初,大家嫌弃写类型麻烦(把 Ts 写成anyScript 但当你在重构一个 5 年前的老组件,IDE 精准地告诉你哪里报错时,你会跪下来感谢 TypeScript
无 Ts,不前端逐渐成为了行业共识
至此,现代前端的四大支柱确立了:
我们建立了一座宏伟的巴别塔
但是,这座塔越来越重了node_modules 文件夹变成了黑洞(没那么轻)。一次 npm install 要 5 分钟,一次 npm run build 要 3 分钟(没那么快)
SPA 的首屏加载越来越慢,SEO 依然是痛点
历史的钟摆,即将再次摆动
为了追求极致的速度,我们将开始反思:我们是不是把太多东西塞进浏览器了?
在 2016-2019 年,如果你不做 SPA,你都不好意思说自己是前端
但是,当全世界都用 React 写网页时,问题暴露了:
CSR的神话破灭了
Vercel(Next.js 背后的公司)站了出来
他们的思路很简单:既然浏览器渲染慢,那我们回服务器渲染不就行了?
这听起来很像 1998 年的 PHP/JSP,但区别在于:前后端是一套代码(全是 JS/TS)。前端工程师拿回了渲染的主导权,同时兼顾了性能
对于博客、文档、营销页,内容几百年不换一次,为什么要每次请求都算一遍?
Gatsby 和 Next.js 推广了 SSG
.html我们绕了一圈,回到了 Web 1.0 的静态文件模式,但生产这些文件的,是 Web 4.0 的自动化流水线
SSR 和 SSG 带来了一个新问题:“注水
当服务器返回 HTML 时,网页看起来画好了,按钮也在那儿
用户急不可耐地去点按钮:没反应
为什么?因为 JS 还没下载完,事件监听器还没挂载上去。
这段时间被称为恐怖谷。用户以为它是活的,其实它是死的
这是现代前端最大的痛点:为了让用户早点看到内容,我们不仅发了 HTML,还得再发一份一模一样的 JS 去激活它。数据发了两遍
2021 年,Astro 提出了一个灵魂拷问:
我的 blog 文章是静态的,为什么我要加载 React 库来渲染它?
Astro 的方案是 0 JS
这是对 React 全家桶的反叛。它标志着前端开始追求细粒度的加载。我们不再把一头大象塞进冰箱,我们只放进去几根香蕉
这也是我个人是非常喜欢 Astro 的原因之一
现在的后端,不再仅仅只是机房里的一台服务器,而是遍布全球的 Edge Functions
Vercel / Cloudflare Workers 允许前端工程师写一段 JS 代码,部署到全球 200 个城市
用户的请求会被路由到离他最近的节点,那里有一个微型的 V8 环境在等他
前端工程师的边界,已经拓展到了网络的最边缘
2020 年,尤雨溪(又是他)发布了 Vite
当时 Webpack 的痛点是:启动一个大项目开发服务器,需要等 30 秒甚至 1 分钟。因为 Webpack 要把所有文件打包一遍
Vite:现在的浏览器已经支持 import 了,为什么还要打包?
Vite 的底层使用了 esbuild(用 Go 写的)
Next.js 的底层使用了 SWC / Turbopack(用 Rust 写的)
前端工具链正在经历一场降维打击。
这标志着前端基建的门槛被极大地拔高了。以前你会写 JS 就能造轮子,现在你得懂 Rust 和内存管理
在样式领域,一场审美审丑的战争结束了 Tailwind CSS 赢了
它看起来很像 1999 年的内联样式:<div class="flex items-center justify-between p-4 bg-blue-500">
很多人第一次看觉得丑爆了
但用久了就感觉爆赞了:
container-inner-wrapper 这种名字了它改变了前端写样式的肌肉记忆
React 推出了 RSC
你可以在 React 组件里直接写 SQL 查询数据库:
PRTCL // JAVASCRIPT
// This runs on Server
async function UserList() {
const users = await db.query('SELECT * FROM users');
return <div>{users.map(u => <p>{u.name}</p>)}</div>;
}
前后端的界限彻底模糊了(但这也导致了更逆天的问题出现
前端工程师不再是切图仔,也不再是 API 消费者
我们正在变成产品工程师。我们一个人就能构建一个完整的、高性能的应用
23 年,ChatGPT 等各家 LLM 来了。 写一个居中布局?写一个正则验证?写一个复杂的 Reducer?
AI 一秒钟就生成
前端开发的门槛到底是变低了还是变高了?
回顾这三十年:
从 1990 年的 <table> 布局,到 2025 年的 Rust 编译器驱动的 Edge SSR
历史不是简单的圆圈,而是螺旋上升的塔
我们回到了服务器,但我们带回了组件化、声明式编程和极致的工程化体系
Web 依然年轻
只要人类还需要通过屏幕与数字世界交互,前端工程师的使命就永远不会结束
至此,我们过了一遍属于前端的三国演义
我们从从蒂姆·伯纳斯-李的草稿纸开始,一直讲到现在
这就是无数开发者与浏览器搏斗、妥协、并最终驯服它的过程
同时我们也明白了
为什么要学这么多乱七八糟的工具?
因为我们是在一堆原本用来擦屁股的纸上,通过几十年的叠 Buff,硬生生盖出了一座摩天大楼
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。