Redian新闻
>
备受 Vue、Angular 和 React 青睐的 Signals 演进史

备受 Vue、Angular 和 React 青睐的 Signals 演进史

公众号新闻

作者 | Ryan Carniato
译者 | 张卫滨
策划 | 丁晓昀

最近,在前端领域,围绕着“Signals”这个词,有一些热烈的讨论。不管是 Preact 还是 Angular,似乎都在讨论该话题。

但它们并不是什么新东西。如果我们将其追溯到上个世纪 60 年代的研究,那么这就更算不上新鲜的事物了。它的基础采用了与第一个电子表格 和硬件描述语言(如 Verilog 和 VHDL)相同的模型。

即便是在 JavaScript 中,从声明式 JavaScript 框架诞生开始,我们就拥有这种理念了。随着时间的推移,它们有了不同的名字,并且在这些年里不断流行了起来。现在,它又重新出现了,这是一个很好的时机,我们可以对它是什么以及为何需要它进行更多的介绍。

免责声明:我是 SolidJS 的作者。本文从我的角度介绍了演进的过程。尽管文中没有提及,但是 Elm SignalsEmber 的计算属性Meteor 都是很值得称道的。

如果你还不清楚 Signals 是什么以及它是如何运行的,请参阅我的这篇对细粒度反应性(Fine-Grained Reactivity)的介绍。

起初的蛮荒时代

有时候,我们会惊讶地发现,很多参与者在完全相同的时间形成了类似的方案。在声明式 JavaScript 框架的起步阶段,有三个方案在三个月内陆续发布,它们分别是 Knockout.js(2010 年 7 月)、Backbone.js(2010 年 10 月)和 Angular.js(2010 年 10 月)。

Angular 的脏值检查、Backbone 的模型驱动重渲染以及 Knockout 的细粒度更新,虽然它们彼此间有些差异,但是最终都成为了我们今天管理 state 和更新 DOM 的基础。

Knockout.js 对本文的主题特别重要,因为它们的细粒度更新是建立在所谓的“Signals”的基础之上的。他们最初引入了两个概念,分别为 observable(状态)和 computed(副作用),但是在接下来的几年中,他们在前端语言中引入了第三个概念 pureComputed(衍生状态)。

const count = ko.observable(0);

const doubleCount = ko.pureComputed(() => count() * 2);

// 每当 doubleCount 更新时,打印日志记录ko.computed(() => console.log(doubleCount()))
狂野时代

在这个时代,服务器端开发的 MVC 和过去几年从 jQuery 中学到的模式进行了融合,形成了新的模式。其中,最常见的一个模式叫做数据绑定,Angular.js 和 Knockout.js 都具有该模式,不过实现方式略有不同。

数据绑定的概念是,state(状态)应该被关联(attached)到 view tree(视图树)的一个特定部分上。借助这种方式,能够实现的一种强大功能叫做双向绑定。所以,我们可以让状态更新 DOM,反过来,DOM 事件会自动更新状态,所有的这一切均是以一种简单的声明方式实现的。

但是,滥用这种力量最终会作茧自缚。我们构建应用的时候,对其缺乏足够深入的了解。在 Angular 中,如果不知道什么内容发生变化,就会对整个树进行脏值检查,而向上传播会导致它多次发生。在 Knockout 中,很难跟踪变化的路径,因为你会在 DOM 上走来走去,出现循环也是司空见惯的。

当 React 出现的时候,我们已经准备好逃离这一切了,对我个人来说,是 Jing Chen 的演讲(https://www.infoq.cn/011cd979-858c-4f92-b699-16d988ec1521),让我稳住了阵脚。

自由时刻

接下来,就是对 React 的采用。有些人依然喜欢反应式模型,因为 React 对状态管理没有自己的偏好,所以完全可以将两者结合起来。

Mobservable(2015)就是这样的方案。但是,相对于与 React 的集成,它还带来了一些新的内容。它强调一致性和顺畅(glitch-free)的传播。也就是说,对于任何给定的变更,系统的每个部分仅运行一次,而且以适当的顺序同步运行。

为了实现这一点,它使用了一种推 - 拉(push-pull)混合的系统来替换先前方案中基于推送的反应性。变更的通知会被推送出去,但是衍生状态的执行会推迟到读取它的地方。

为了更好地理解 Mobservable 的原始方式,请参阅 Michel Westrate 的“Becoming Fully Reactive: An in Depth Explanation of Mobservable”一文。

虽然在很大程度上,这个细节会被 React 重新渲染读取变更的组件所掩盖,但是,这是使系统实现可调试和一致性的关键步骤。在接下来的几年里,随着算法的不断完善,我们会看到一种趋势,那就是更多基于拉取的语义。

征服泄露的观察者

细粒度反应性是四人组(Gang of Four)观察者模式的变种。虽然观察者模式是一个强大的同步模式,但是它也有一个典型的问题。一个 Signal 会保持对所有订阅者的强引用,所以长期存活的 Signal 会保留所有的订阅,除非进行手动处置。

这种记录方式在大量使用时会变得很复杂,尤其是在涉及嵌套的时候。在处理分支逻辑和树的时候嵌套很常见的,就像在构建 UI 视图时的那样。

有一个鲜为人知的库,叫做 S.js(2013)提供了答案。S 是独立于其他大多数解决方案而开发的,它更直接地以数字电路作为模型,所有的状态变化都在时钟周期内进行。S 将其状态基元称为“Signals”。尽管它不是第一个使用该名字的,但它是我们今天使用该术语的起源。

更为重要的是,它引入了反应式所有权的概念。所有者会收集所有的子反应式作用域,并在所有者处置(disposal)自身或重新执行时,管理子反应式作用域的处置。反应式图会从一个根所有者开始,然后每个节点均作为它所拥有的后代。这个所有者模式不仅对处置过程很有用处,而且在反应式图中,建立了一种提供者 / 消费者(Provider/Consumer)上下文的机制。

调    度

Vue(2014)也为我们今天的发展做出了巨大的贡献。除了在优化一致一致性方面与 MobX 的节奏保持一致之外,Vue 从一开始就将细粒度反应性作为其核心。

虽然 Vue 和 React 都使用了虚拟 DOM,但是 Vue 的反应性得到了最好的支持,这意味着它是与框架一起研发的,首先是作为内部机制,为其 Options API 提供支持,在过去的几年中,它成为了 Composition API(2020)的前沿和核心。

Vue 将推送 / 拉取向前推进了一步,能够调度任务何时会完成。默认情况下,Vue 会收集所有的变更,但是下一个微任务在处理作用(effect)队列之前不会处理它们。

然而,这种调度也可以用来做其他的事情,比如 keep-alive 和 Suspense。甚至像并发渲染这样的功能也可以用这种方式来实现,从而充分体现了如何同时利用基于推送和拉取的方式能够达成的最佳效果。

编    译

在 2019 年,Svelte 3 向我们展示了利用编译器能够完成多少事情。实际上,他们将反应性完全编译掉了。在这过程中,也会有一些权衡,Svelte 向我们展示了编译器如何抹平人类工程学方面的欠缺。这将会成为一种趋势。

反应式语言(如状态、衍生状态、作用)不仅向我们描述了用户界面等同步系统所需的所有内容,而且它是可分析的。我们可以精确地知道都发生了哪些变更以及它们发生在什么地方。可追溯性的潜力是很深远的。

来自 Preact 团队的 Marvin Hagemeister 在 Twitter 这样说到,“我认为这是基于 Signals 的方式优于钩子(hook)的主要原因之一。它能够使我们添加更多的调试洞察力,这是钩子所无法实现的,比如准确地显示一个状态发生变更的原因。”

如果能够在编译时知道这一切,我们就可以交付更少的 JavaScript 代码。对于代码的加载,我们会有更高的自由度。这就是 Qwik 和 Marko 的可恢复性的基础。

面向未来的 Signals

Angular 团队的成员 Pawel Kozlowski 则 认为:

“Signals 是新的 VDOM。

人们对它的兴趣正在爆发:很多人正在尝试一些新东西。这将使我们能够探索该领域,尝试不同的策略,对其增进了解和优化。

虽然现在不知道最终结果是什么,但是这种集体探索是很好的!”

鉴于这项技术已经非常古老,说还有很多东西需要探索,这可能会令人感到惊讶。但是,这里的原因在于,它是一种对解决方案进行建模的方式,而不是一种具体的方案。它所提供的是一种描述状态同步的语言,与要让它执行的副作用完全无关。

因此,它能够被 Vue、Solid、Preact、Qwik 和 Angular 采用似乎并不足为奇。我们已经看到它进入了 Rust 的 Leptos 和 Sycamore,表明 DOM 上的 WASM 不一定会慢。React 甚至考虑在底层使用它。

来自 React 核心团队的 Andrew Clark 表示:

“我们可能会在 React 中添加一个类似 Signals 的基元,但我并不认为这是一个编写 UI 代码的好方法。它对性能来说是很好的。但我更喜欢 React 的模式,在这种模式下,你每次都会假装重新创建所有的内容。我们的计划是使用一个编译器来实现与之相当的性能”。

也许这是一种合适的方式,因为 React 的虚拟 DOM 始终只是一个实现细节。

Signals 和反应性语言似乎是一个交汇点。但是,这在 JavaScript 诞生之初却并不那么明显。也许这是因为 JavaScript 并不是最好的语言。我甚至可以说,长期以来,我们在前端框架设计中感受到的很多痛苦都是语言本身的问题。

无论这一切的结局如何,到目前为止,都是一次相当不错的旅程。有这么多人关注 Signals,我迫不及待地想知道我们的下一步会是什么。

原文链接:

https://dev.to/this-is-learning/the-evolution-of-signals-in-javascript-8ob

相关阅读:

手写一个 react,看透 react 运行机制 (https://xie.infoq.cn/article/958fbe57ff88cdba990d99739 )

看透 react 源码之感受 react 的进化 (https://xie.infoq.cn/article/3e10ee935ffd1b23b1ecd8842 )

2023 重学 Angular(https://xie.infoq.cn/article/7baec545b8202471064494a69 )

初识 VUE 响应式原理 (https://xie.infoq.cn/article/118bc90c00b5b7b4faf3cd774 )

声明:本文为 InfoQ 翻译,未经许可禁止转载。

点击底部阅读原文访问 InfoQ 官网,获取更多精彩内容!

今日好文推荐

Databricks来搅局了:0门槛克隆ChatGPT,完全开源可随意修改商用

GPT-5根本不存在!OpenAI 表态;王小川讽刺李彦宏活在平行宇宙,百度肖阳回击;阿里、亚马逊等相继发布大模型产品|Q资讯

用C++写出比MySQL快800倍的数据库,ClickHouse创始人:融合数据库该“卷”的还是性能和速度

国产替代潮来了,这与京东云已“养成”的混合多云有什么关系?

微信扫码关注该文公众号作者

戳这里提交新闻线索和高质量文章给我们。
相关阅读
美国上流社会最青睐的大学Top 10!商界、政界大佬的子女都在这儿!Chinese Climbers Scale Everest, Tragedy and Daring Rescue Ensue深受中美申请人青睐的葡萄牙,有何规划优势?如何培养出被加州理工学院青睐的孩子?快来听听学生家长怎么说|成长教育之道系列访谈<三>坎坷的欧洲游(1)2023英国应届生就业报告出炉!最受雇主青睐的大学, 牛津没进前十……藤校青睐的文书是怎样练成的?你的文书致胜法宝来了!听说今年春天衣服口袋越多,越有型?刘文正之“去世”,太玄乎了!如何培养出被加州理工学院青睐的孩子?这位妈妈的做法值得借鉴!Agustín Hernández:中美洲建筑背景下的未来主义巨构悉尼首次购房者最青睐的区出炉,三大华人区上榜!这些区最火爆Bellevue 124th Avenue NE施工警报,禁止双向停车,施工影响和绕行路线都在这这一招会影响一个人的睡眠。。。。播放器技术演进与探索,Web开播系统的技术演进,大屏终端音视频播放,音视频效果插件开放平台建设微软宣布5.26再裁员, 影响Redmond、Bellevue、Issaquah 多少员工?景美和Big Picture两校搬迁尘埃落定!抓紧时机为Bellevue综合规划和Wilburton愿景实施发表意见!西雅图看房日记|东雅图Bellevue 4房学区房(Newport Hills)华尔街最青睐的20所美国大学!不得不说,宾大真是赢麻了!"𝙇𝙚𝙖𝙙 𝙏𝙝𝙚 𝘾𝙝𝙖𝙧𝙜𝙚"广告#创译挑战前端工作两年,应该把精力放在 Vue 上还是 JS、React、工程化上?| 极客时间就在今晚|如何培养出被加州理工学院青睐的孩子?快来听听学生家长怎么说!从石器时代到成为“神”,一文讲透eBPF技术发展演进史lāo dao?láo dao!IDG资本再度加持,POCT厂商科瑞达生物缘何备受青睐?无缝切换?从Vue到ReactMIT青睐的学生,都是什么样?今年被录取的四个学生牛在哪?美国入境档案--闵嗣鹤1947年纽约可怕!深受美国华人青睐的邮轮游出事!厕所发现摄像头 多人“上镜”外交部发言人:中国是外资企业青睐的投资热土打造消息中台,华为终端云基于 Apache Pulsar 的演进实践西雅图看房日记|Bellevue Lake Hills自住房Hangzhou Plans Easing ‘Hukou’ Restrictions to Attract Talent研究称:备受名人青睐的这饮食法增加心脏病癌症风险中国重点大学演进史
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。