在选择框架时,不要过度思考,因为最终它们都将成为同质的技术,只是外在形式有所不同。
在今年的 dotJS 大会上,谷歌的 Angular 负责人 Minko Gechev 在演讲中表示:在去年,Angular 和 React 本质上是同一种框架。
在 JavaScript 世界里,这一观点显得颇为激进。毕竟,Angular 使用的是类和模板,而 React 使用的是函数和 JSX。但在核心层面,它们都旨在提供相似的功能和解决相同的问题。
Gechev 说:“前端框架的大部分职责是保持模型与视图的同步,在这一点上,Angular 和 React 显示出了设计上的相似之处。”
Gechev 被谷歌指派去做一项他认为可能是 Web 开发领域的创新之举:融合两个框架,也就是 Angular 和 Wiz。他解释了这种融合对于 Web 开发者和框架的未来发展来说意味着什么。
Minko Gechev 列出了一些常见的框架抽象
他在演讲中说:“融合两个不同的框架是我此前未曾听闻的尝试”。这段演讲已于 7 月份在 YouTube 上发布。“这个过程让我深入理解了 Web 框架的构成,并发现不同框架之间有很多相似之处。我看到了它们在相似理念上的融合,随着时间的推移,它们的实现方式也很相似。”
React 和 Angular 在保持组件树与 UI 同步方面有着惊人的相似之处,他说。
他说:“这通常被称为响应性,或者说是状态随时间的传播。这是去年 Angular 和 React 在理念上非常接近的地方。”
对于二者,开发者都必须指明状态已发生变化。在 React 中,这是通过 hooks 完成的,在 Angular 中,这是通过 zone.js 完成的,他说。框架会自动从上到下遍历组件树,找到所有差异,并将它们应用到 DOM 上,他继续说。
他例举了另一个例子:一个应用程序组件使用了另外两个组件——用户资料和购物车。个人资料组件显示用户名,购物车组件遍历购物车中的物品,并显示每个物品的数量。
购物车的代码
他说:“在运行应用程序时,框架将构建一个组件树。如果我们更新购物车的状态,比如将第一个物品的数量改为 1,Angular 和 React 都将执行变更检测和调和操作,采用的算法非常相似。它们将遍历组件树,从根节点开始,然后逐步前往用户资料组件。”
Gechev 还拿出了基准测试来展示两者的相似性。
Angular 和 React 的基准测试
他说:“Angular 和 React 在行交换方面表现不佳,但在局部更新方面,这两个框架都展现出了良好的性能。”
他补充说,实际应用中的情况可能会有所差异。在某些情况下,可能有成百上千个组件持续处于活跃状态。
他说:“如果我们必须逐一检查组件树,识别出差异并将其反映在视图中,这将耗费大量的时间。所以 Angular 决定优化它的响应性机制。”
Angular 引入了一种基于编译器的静态依赖追踪机制。Angular 16 加入了 Signals,一种响应性原语,可以自动跟踪它们被使用的位置。当变量发生变化时,Signals 能够使依赖于该变量的计算失效。
Ember、Solid、Vue、Svelte 等框架也有类似的功能。
他说:“可以看到,所有这些框架现在都在同一个响应性原语上走向融合。”
用例融合
一直以来,Wiz 框架被应用于与 Angular 截然不同的场景,它更类似于 Astro 和 Qwik,Gechev 说。
“它一直是那些对性能要求极高的消费者应用的首选——例如谷歌搜索或 YouTube。而另一方面,Angular 历来更多地服务于企业级客户,例如 谷歌云、谷歌 Analytics 等。然而,随着时间的推移,我们注意到这些框架的要求,它们也开始融合。”
Gechev 说,Signals 成为了融合讨论的起点,因为 Wiz 团队在看到 Angular 中的 Signals 后也想要在 Wiz 中引入,而 Angular 团队则想要 Wiz 的可恢复性特性,这是 Wiz 在 10 年前引入的概念,Qwik 随后采纳了。
正是在这个时候,Gechev 被指派去融合这两个框架。
他说:“在浏览 Wiz 团队的 谷歌 Chat 聊天记录时,我发现他们一直在与 YouTube 合作,将平台的 UI 从传统的虚拟 DOM 实现重新变为基于 Signals 的实现。同时,Angular 团队正在将 Signals 作为框架的一部分。所以我们决定携手合作。”
这导致移动版 YouTube 使用集成了 Angular Signals 的 Wiz 框架,在性能上实现了显著提升,他说。例如,在智能电视平台上,他们看到了高达 35% 的性能提升。
现在有一个将 Signals 添加到 JavaScript 中 的提案。目前处于第一阶段(TC39),参考实现使用的是 Angular Signals,因为它已被证明可以在多个框架中工作。
其他领域的融合可能性
尽管如此,融合并不是一项简单的任务,他提醒说,这可能需要在框架中进行大量的修改。稳定性也是一个必须考虑的重要因素,他补充说。但是让他对成功完成这项任务充满信心的是,到目前为止,Wiz/Angular 的融合在谷歌内部测试中并没有导致任何故障。
他说:“每次我们在 Angular 中做出一些修改,都会发起一个 PR,我们将 PR 中的代码与谷歌内部的单体仓库进行同步,这个仓库中大约有 4500 个 Angular 应用,其中一些应用有数百万行代码。我们会对所有受影响的应用执行测试,确保没有引入任何问题,没有破坏现有的功能。这意味着对我们需要经历很多痛苦的过程,我们需要调试这些测试,理解以前从未见过的代码。但这也确实保证了无与伦比的向后兼容性。”
他预测,事件重放和细粒度代码加载也将有可能融合。事件重放是谷歌用于弥合用户在观察其 Web 应用程序的结构和实际与之互动时所感受到的交互性差异的一种方法。目前,团队正在努力更新一个叫作 JS Action 或 Event Dispatch 的库,然后将其移入 Angular 代码库中。
Gechev 说:“这与谷歌搜索中的事件重放代码相同,可以在 https://github.com/angular/angular 上找到。我们已在 Angular 开发者预览版中添加了支持。你可以通过使用客户端水合技术,并指定启用事件重放特性来启用它。这为我们提供了另一个提升性能的可能性。”
“现在,我们可以通过减少 JavaScript 的加载量来缩短下载和执行时间,这已经通过恢复性功能或部分高级的水合技术实现,其中我们隐式指定了处理特定用户交互所需的最小代码量。”
引入可延迟视图
这种方法允许应用程序仅下载响应特定用户交互所需的最小代码量,而不是一次性下载整个应用程序,Gechev 解释说。在 Angular 中,我们不能以相同的隐式方式实现这一点,因为这样可能会破坏很多现有的应用程序,而且它并不符合开发者目前使用 Angular 的开发范式。
可延迟视图代码
为了弥合这一差距,他们引入了可延迟视图,允许开发者在应用程序中创建交互性或水合岛屿。
他说:“使用可延迟视图,你可以将 UI 的一部分包装在一个块中,并指定你希望这个块仅在满足特定条件时才被水合。这是使用服务器端渲染时才有的语义。”
当客户端向服务器发送请求时,它会提前提供应用程序的标记,开发者将使用这些不同的块创建不同的交互性岛屿,他说。
移动端的可延迟视图
因此,如果用户交互是水合触发器,当用户在与左侧导航栏发生交互时,它可以从服务器下载特定于该部分的 JavaScript 代码并进行水合,无需下载其他部分。
他说:“我们可以下载处理这个特定用户交互所需的最小 JavaScript 代码量。我们还可以重放事件,确保不会丢失任何点击动作。”
Angular 的影响
这引出了一个关键问题:这对 Angular 和 Web 开发者来说意味着什么?
Gechev 说:“这将如何体现在 Web 开发者中的工作中?实际上,这是一个循序渐进的改进过程。在这个过程中,我们将寻求开源已被行业认可并确立为最佳实践的原语。”
他承认,有些人可能认为融合的差异太大。例如,React 没有依赖注入,而 Angular 没有上下文 API。但在根本上,它们都是为了达到相同的目的。
他说:“对于二者来说,我们都希望根据组件的使用上下文将数据注入到组件中。在 Angular 中,我们使用依赖注入来实现。在 React 中,我们使用上下文 API 来实现。它们服务于相同的目的,只是实现方式略有差异。它们的数据结构也非常相似。”
开发者的收获
Chrome 首席工程师 Addy Osmani 在 2024 年的谷歌 I/O 开发者大会上分享一个表格,从 Web 开发者的角度看每个框架中可用的功能。Gechev 对这个表格做了一些修改,以反映他自己的观点,即各个框架正在融合相同的功能。
表格列出了 JavaScript 框架之间的抽象
Gechev 说:“这对 Web 开发者意味着什么?现在你是如何选择框架的?在选择框架时,不要过度思考,因为最终它们都将成为同质的技术,只是外在形式有所不同。”
话虽如此,他还是列出了一些在选择技术时可能会被忽视的建议。他建议 Web 开发者在选择框架或技术时要考虑它们的稳定性和可靠性。
他说:“我们要确保选择的是一个稳定的解决方案,因为它将一直伴你随行。拥有一个丰富、包容且为你提供支持的生态系统也非常重要,这应该是你真正乐于使用的技术。”
原文链接:
https://thenewstack.io/google-angular-lead-sees-convergence-in-javascript-frameworks/