前端框架进化史

本内容是对 You'll Never Manually Update the DOM Again // Here's Why 内容的翻译与整理。

你再也不需要手工更新DOM, 以下是原因

现代 JavaScript 框架,如 React、Vue、Svelte、Solid、Quick,以及本周推出的其他 786 个框架,都试图做一些不同的事情。

React 为我们提供了虚拟 DOM 中的组件。Vue 使响应式编程感觉自然。Svelte 抛弃了运行时,所有内容都在编译时处理。Solid 跟踪细粒度更新,而 Quick 则尝试暂停和恢复整个应用程序。但在它们所有炫酷的语法糖和闪亮特性背后,它们都围绕着一个奇妙的技巧展开,那就是响应式 UI 更新

那么,什么是响应式 UI 更新呢?这意味着你不再需要一步步地告诉浏览器如何更改 UI,而是声明基于某些状态 UI 应该是什么样子。框架会以最有效的方式来实现这一点,这说起来很不错,因为在 2000 年代初期,JavaScript 框架尚未存在的 VanillaJS 时代,你必须手动完成所有事情:

如果想更新 UI,你得找到元素,改变它的文本内容,可能添加一个类,可能删除一个,甚至可能重绘整个区块,只为显示一项新内容。如果状态在两个地方发生变化,你必须更新两个地方,你会遇到奇怪的闪烁或过时的 UI,或者那个拒绝更新的 div,直到你刷新页面,而它仍然只在你哭了一会儿之后才会更新。

我不知道这是否是个必要条件,但这确实是过程的一部分。因此,要构建任何体面的东西,你必须查询 DOM 中的元素。你必须在某处手动跟踪应用状态。你必须编写命令式代码,以反映每个状态变化在 UI 中的体现。你必须在播放林肯公园和穿着工装短裤的同时,调试 Internet Explorer 6。你必须完成所有这些,尤其是最后一点,否则它将不同步,显示过时的数据,而你甚至不会知道,直到用户给你发邮件,或者产品经理在午夜时分通过 Slack 给你发了截图和带有消极攻击性的"嗯?"。不过,当时 Slack 甚至还不存在。所以,我们迫切需要更好的方法。这里的"我们"并不是指我,我当时才 10 岁。

然后,jQuery 出现了。我们所需要的英雄,终于来了。突然间,你可以这样写一行代码,这意味着不再需要使用 document.getElementById,也不再有跨浏览器的头痛,不再在 Netscape 中哭泣。jQuery 给了我们力量,给了我们简单。短暂的时间内,我们认为它是未来,它确实感觉像未来。但问题是,它仍然是命令式的。你仍然需要控制何时更新,在哪里更新,所有的负担依旧,只是以更简单的形式呈现。你的状态可能会变化,如果你忘记在某处调用 jQuery 更新函数,那么你的 UI 又会不同步。老实说,曾经干净的 JavaScript 代码库现在变成了一片意大利面森林,充满了 .Hide、.show, .addClass、.removeClass 和偶尔的存在危机。

因此,jQuery 让你能够更快更轻松地操控 DOM,但 Angular 1.0 想:如果你根本不需要考虑 DOM 呢?他们的解决方案,无论你是否喜欢,就是"算了,让我们随时监视一切。"Angular 的脏检查意味着框架会在每次发生事件时检查页面上的每一个变量,看看是否有变化。听着,这对我们制作的数千个待办应用来说是个好主意,但在构建真正动态的网站时就没那么好了,因为应用变得很慢,可以想象,非常慢。它确实检查了所有内容。开发人员们开始意识到,我们不仅需要一种注意变化的方法,我们还需要对变化做出反应的方式,就像你需要对 2025 年 AI 编写越来越多代码的变化做出反应一样。

(这段为软广) 因为现在我们不仅要对 UI 问题做出反应,还要对安全问题做出反应。这就是我与 Sneak 合作的原因,Sneak 是一个开发者安全平台,帮助开发人员发现、修复和跟踪代码中的漏洞。为什么你应该关注 2025 年 5 月 28 日举行的 Sneak Launch。那是一个免费的虚拟活动,讨论 AI 如何改变应用开发,以及这对安全意味着什么。你将听到如何处理新兴的 AI 威胁。因此,不仅是你的代码由 AI 编写,或者其他人用 AI 编写的代码,还有人利用 AI 来扩展 AI 生成代码的安全性。调整你的工作流程,以适应这一切,构建一个稳固的应用安全治理。无论你是使用 React 构建,还是发布 LLM 功能,或者只是让 AI 自动补全一半的代码库,风险都是真实的。风险一直存在,但现在比以往任何时候都更为严重。这次活动有两场会议,一场在上午 10 点,另一场在下午 6 点。所以没有借口,无论你的工作时间表或时区如何。只需点击描述中的链接注册 Sneak Launch 2025。再次强调,活动将于 5 月 28 日举行,免费并且面向开发人员。重大变化即将来临,确保你为此做好准备。

因此,开发人员不仅想注意变化,他们还想对变化做出反应,于是你猜对了,React 出现了。React 的回答是重新渲染一切,但首先在内存中完成。每次发生变化时,React 都不是直接更新实际的 DOM,而是构建虚拟 DOM 的副本。虚拟 DOM 通过比较新旧副本来找出变化,并只更新必要的部分。这比脏检查有了巨大的改进,但仍然存在开销,因为你需要处理整个树。这就是其他框架的出现,想:如果我们也不这样做呢?例如 Svelte,Svelte 在编译时处理这一切。换句话说,他们在构建步骤中分析你的代码并将所有内容连接起来。它已经知道这个 H1 标签依赖于 name。所以当 name 改变时,Svelte 只更新那个 DOM 节点。没有虚拟 DOM,没有差异计算,仅仅是精确的编译 DOM 更新。但这有一个权衡,那就是你失去了一些灵活性,但换来了速度和简单性。

Vue 则采取了与这两者不同的方法。它不是使用信号或编译,而是将你的状态封装在代理中。因此,当你访问一个属性时,Vue 会跟踪它。当你更新它时,Vue 知道该重渲染什么。就像 Vue 在暗中监视你的变量,但以一种有帮助的方式。你得到了所需的响应性,但没有虚拟 DOM 差异计算的开销。仅基于实际使用的内容进行高效的 DOM 补丁。

而 Solid 也完全跳过虚拟 DOM,但采用了基于信号的方法。Solid 中的每个响应式状态都是一个信号。当信号变化时,只有依赖于它的 DOM 节点更新,别无其他,而我实际上非常喜欢这一点。这非常快,老实说相当优雅。你改变一个信号,就像是打开一个开关,只有灯光响应。

然后是 Quick,它想:如果我们在用户做出反应之前从未运行我们的应用程序呢?因为 Quick 在服务器上序列化你的应用程序,发送零 JavaScript,并且只有在用户与之交互时才恢复执行。它仍然是响应式的,但现在优化了水合性能和冷启动,这对于边缘渲染或需要瞬时感的大型应用来说是理想的。

那么,所有这些归根结底,为什么要使用响应式 UI 更新呢?因为所有这些框架,无论它们的方法有多不同,都在尝试解决同一个问题:保持 UI 与状态同步,并高效、可靠且具有装饰性地完成这一切。响应式 UI 更新是实现这一目标的基础。它消除了手动 DOM 同步,让你专注于 UI 应该是什么样子,而不必手动完成每一件事情。它可以从计数器扩展到完整的应用程序。它们都有不同的哲学和权衡,有些比其他的更快。

但每个现代 JavaScript 框架都是响应式的,因为手动处理实在太糟糕,我们再也不想回头。我希望你喜欢这个视频,并对一些 JavaScript 框架有了更深入的了解。我认为,理解我们在技术方面的来源,以及分解那些抽象层,确实有助于我们整体上成为更好的开发者。因此,如果你同意这一点,可以看看这两个视频中的一个,也许它们也能给你带来帮助。或者通过订阅频道等我的下一个视频。

相关推荐
EnCi Zheng16 小时前
M5-markconv自定义CSS样式指南 [特殊字符]
前端·css·python
kyriewen16 小时前
你的网页慢,用户不说直接走——前端性能监控教你“读心术”
前端·性能优化·监控
广州华水科技16 小时前
北斗GNSS变形监测在大坝安全监测中的应用与优势分析
前端
前端老石人16 小时前
前端开发中的 URL 完全指南
开发语言·前端·javascript·css·html
CAE虚拟与现实16 小时前
五一假期闲来无事,来个前段、后端的说明吧
前端·后端·vtk·three.js·前后端
Sarvartha17 小时前
三目运算符
linux·服务器·前端
晓晨的博客17 小时前
ROS1录制的bag包转换为ROS2格式
前端·chrome
Wect17 小时前
LeetCode 72. 编辑距离:动态规划经典题解
前端·算法·typescript
donecoding17 小时前
别再让 pnpm 跟着 nvm 跑了!独立安装终极指南
前端·node.js·前端工程化
不可能的是17 小时前
从 /simplify 指令深挖 Claude Code 多 Agent 协同机制
javascript