Vue与React不是真正的响应式编程,Svelte才是正宗

这个题目可能有点夸张,但不管怎样 Svelte 和它的理念就是这样的。如果你还没听说过 Svelte 的话就去了解一下吧——你会见证一场革命的,它将取得空前的成就(没有给 Svelte 团队增加压力的意思)。

本文不是 Svelte 的入门教程。Svelte 团队已经做了一份很棒的交互式手把手入门教程,能帮助你轻松迈入响应式编程的天地。

Svelte 教程地址: https://svelte.dev/tutorial/basics

先来份免责声明吧:我不是编程高手,我也没有无所不知。我只是非常热衷于每天出现的创新事物,喜欢随时随地谈论它们而已——这也是这篇文章的来历。请客观对待我说的每一句话,如果我哪里跑了火车也请告诉我吧。

那好,我们这就开始正题吧!

首先,谈谈 React

讨论为什么我认为 Svelte 有如此革命性的突破之前,咱们先来看看之前 Dan 发布的这条推文,研究一下它背后的含义:

React不是真正的响应式编程,Svelte才是

另一个免责声明:本文可没有批判 React 的意思。我只是拿 React 来举个例子说明问题,因为大多数读者迟早都会用到它的。提 React 只是因为它是跟 Svelte 对比的最佳例子罢了。

Dan 上面那句话究竟是什么意思?这对我们现在写代码的方式有什么影响?要回答这个问题,我先简单介绍一下 React 的工作机制吧。

当你呈现一个 React 应用时,React 会在所谓虚拟 DOM 中保留 DOM 的副本。虚拟 DOM 充当你的 React 代码与浏览器绘制到 DOM 的内容之间的中间层。

然后当你的数据出现变动时(可能因为你调用了 this.setState,useState),React 会做一些工作来确定如何在屏幕上重新绘制 UI。

它会对比虚拟 DOM 与真实的 DOM,以确定数据更新导致了哪些更改。然后它会仅重新绘制与虚拟 DOM 中的新副本不匹配的 DOM 部分,这样就无需在每次数据更新时重新绘制整个 DOM 了。

这就显著提升了性能,因为更新虚拟 DOM 比更新真实 DOM 要节省很多资源,而 React 只更新真实 DOM 中需要改变的部分。有一篇文章很好地解释了这一过程:
https://medium.com/@gethylgeorge/how-virtual-dom-and-diffing-works-in-react-6fc805f9f84e

但你可能会发现这个实现有点问题。如果你没有告诉 React 你的数据已经改变了(比如说调用 this.setState 或 Hooks 之类),那么虚拟 DOM 就不会有变化,React 也不会随之响应(Duang!搞砸了!)。

这就是 Dan 所说的,React 并不是完全的响应式设计的意思。React 需要你手动跟踪应用数据,并在数据变化时告诉 React,这也意味着你得做更多工作。

好了,现在该谈 Svelte 了

Svelte 是一种构建 UI 的全新途径,它速度极快、效率极高,是真正的响应式设计,还不需要虚拟 DOM;用 Svelte 写的代码比其它任何框架或库都更加简洁。

说得这么好听,可你肯定会问它和其它一大堆 JavaScript 库和框架究竟有什么区别呢?我来逐一说明吧,

真正的响应式设计

Svelte 既不是库也不是框架;相反,Svelte 是一个编译器,它吃进你的代码并吐出与你的 DOM 直接交互的原生 JavaScript,不需要中间层。

等等,什么?编译器?是的——编译器。这个思路太强悍了,我都不知道为什么以前没人想得到呢?为什么这个主意这么棒,听我细细道来吧。

引一句 Rich Harris 在 YGLF 2019 大会上的讲话:

Svelte 3.0 将响应设计从组件 API 移到了编程语言中。

这说的是啥?别急,我们已经看到 React 和大多数其他前端框架,要求你在更新其虚拟 DOM 之前,使用 API 来告诉它数据已更改(再次通过调用 this.setState 或 useState)。

在 React 以及大多数 UI 框架和库中,调用 this.setState 意味着你的应用的响应能力是与特定的 API 绑定的,没有 API 它就没法知道数据什么时候变动了。

Svelte 采取了另一种方法解决这个问题。

它从运行代码的方式中获取了 Observable 的灵感。 它不是从上到下运行代码,而是以拓扑顺序运行它。 查看下面的代码片段,我们将了解以拓扑顺序运行它的含义。

复制代码

 
 

1. (() => {

 

2. const square => number => number * number;

 

3.

 

4. const secondNumber = square(firstNumber);

 

5. const firstNumber = 42;

 

6.

 

7. console.log(secondNumber);

 

8. })();

现在如果你按从上到下的顺序运行这几行代码的话就会在第 4 行遇到错误,因为 secondNumber 依赖 firstNumber,而这时候 firstNumber 尚未初始化。

如果以拓扑顺序运行这段代码则不会出现任何错误。为啥呢?编译器并不会按从上到下的顺序运行这段代码;相反,它会查看所有变量并生成依赖图(比如说 A 依赖 B 才能工作之类)。

这算是对编译器如何以拓扑顺序编译代码的简化解释了。

复制代码

 
 

1. 这个新变量'square'是否依赖其它变量?

 

- 它没有,所以我会初始化它

 

2. 这个新变量'secondNumber'是否依赖其它变量?

 

- 它依赖'square'和'firstNumber'。我已初始化'square',但我还没有初始化'firstNumber',马上就会做。

 

3. 好的,我已初始化'firstNumber'。现在我可以使用'square'和'firstNumber'初始化'secondNumber'了

 

- 我是否拥有运行此 console.log 语句所需的所有变量?

 

- 是的,所以我会运行它了。

乍看上去代码好像是从上到下的运行顺序,但仔细观察就会发现它的确是跳着执行的。

跑到第 4 行时,编译器发现它没有 firstNumber,因此会暂停执行并查看代码,找出它是不是在别的地方定义了。一看,原来它是在第 5 行定义的,所以编译器会先运行第 5 行,然后返回第 4 行继续执行。

如果语句 A 依赖于语句 B,则语句 B 会先运行,运行顺序与声明的顺序无关。

那么这和 Svelte 实现真正的响应式设计又有什么关系?具体来说,你可以在 JavaScript 中用标识符标记一个语句,如下所示::foo=bar。它会在foo=bar语句中添加一个名为:foo=bar。它会在foo=bar语句中添加一个名为 的标识符(如果之前未定义 foo,则严格模式下会出错)。

所以在这种情况下,当 Svelte 看到任何带有 $: 前缀的语句时,它就知道左边的变量要从右边的变量中获取值。我们现在有了一种方法可以将一个变量的值绑定到另一个变量。

响应!这意味着我们现在正在使用 JavaScript 的 API 核心部分来实现真正的响应设计,无需摆弄像 this.setState 这样的第三方 API。

实践中是这个样子:

复制代码

 
 

1. // vanilla js

 

2. let foo = 10;

 

3. let bar = foo + 10; // bar is now 20

 

4. foo = bar // bar is still 20 (no reactivity)

 

5. bar = foo + 10 // now bar becomes 30

  
 

6. // svelte js

 

7. let foo = 10;

 

8. $: bar = foo + 10; // bar is now 20

 

9. foo = 15 // bar is now 25 because it is bound to the value of foo

请注意,在上面的代码中我们不需要将 bar 重新分配给 foo 的新值——比如直接通过 bar = foo + 10;或者通过调用像 this.setState({ bar = foo + 10 }); 这样的 API 方法,现在都用不着了。它会自动为我们处理好的。

这意味着当你将 foo 更改为等于 15 时,bar 会自动更新为 25,并且你不必调用 API 来为你更新它。Svelte 已经知道了。

上面的 Svelte 代码的编译版本如下所示:

复制代码

 
 

1. ... omitted for brevity ...

 

2. function instance($$self, $$props, $$invalidate) {

 

3. let foo = 10; // bar is now 20

 

4. $$invalidate('foo', foo = 15) // bar is now 25 because it is bound to the value of foo

 

5. let bar;

 

6. $$self.$$.update = ($$dirty = { foo: 1 }) => {

 

7. if ($$dirty.foo) { $$invalidate('bar', bar = foo + 19); }

 

8. };

 

9. return { bar };

 

10. }

 

11. ... omitted for brevity ...

好好花点时间研究一下上面这段代码吧,慢慢来,不要着急。

看到在 bar 被定义之前 foo 是如何更新的了吗? 那是因为编译器正在以拓扑顺序,而非严格的自上而下的顺序在解析 Svelte 代码。

Svelte 会自己响应数据变化。它用不着你操心更改的内容和时间;它自己就会知道。

注意:在第 4 行里,bar 的值到下一个 Event Loop 之前都不会更新的,这样一切都会干净又整洁。

这样你就不必在数据发生变化时手动更新状态了。你可以专注于你的代码逻辑,而 Svelte 可以帮助你将 UI 与最新状态协调好。

简洁

前面我不是说 Svelte 可以用更少的代码来完成更多工作吗?事实确实如此。下面我拿 React 中一个简单的组件和 Svelte 中的对应组件举个例子,你自己看:

React不是真正的响应式编程,Svelte才是

17 行对 29 行代码,这俩应用的功能完全相同,看看我们在 React.js 中编写了很多的代码吧——这我还没开始用 Angular 呢。

React不是真正的响应式编程,Svelte才是

Svelte 代码除了更简洁耐看外也更容易理解,因为它的活动部件比 React 代码少。我们不需要事件处理程序来更新输入元素的值——只需绑定值即可。

回想你刚刚开始学习网页开发的时候。哪边的代码会让你更难理解?左边的还是右边的?

虽然这看起来没那么重要,但当你开始构建更大、更复杂的应用时,很快就会发现不用写那么多代码是多么有用。我曾花了好几个小时试图理解同事编写的大型 React 组件是如何工作的。

我确实相信 Svelte 的简化 API 能使我们更快地阅读和理解代码,从而提高整体工作效率。

性能

好了,现在我们已经知道 Svelte 是真正的响应式设计,可以让你用更少的投入做更多的事情。那么它的性能如何?完全用 Svelte 编写的应用能有很好的用户体验吗?

React 之所以如此强大,其原因之一在于它使用虚拟 DOM 来更新应用程序的 UI,一次只更新一部分,无需在每次更改内容时重新构建整个 DOM(这非常消耗资源)。

但这种方法的缺点是,如果组件的数据发生变化,React 将重新渲染该组件及其所有子组件,哪怕子组件不需要重新渲染也得这么干。这就是为什么 React 会有 shouldComponentUpdate、useMemo、React.PureComponent 一类的 API。

只要使用虚拟 DOM 在状态更改时渲染 UI,这个问题就没法解决。

Svelte 不使用虚拟 DOM,那么它如何解决重新绘制 DOM 以匹配应用程序状态的问题呢?这里我再次引用 Rich Harris 在 YGLF 上的精彩演讲:

框架不是用于组织代码的工具。它们是组织你思想的工具。

Rich 认为框架可以在构建步骤中运行,从而让代码在运行时无需中间层。这也就是为什么 Svelte 是编译器而非框架的原因。

这就是为什么 Svelte 速度飞快的原因。Svelte 将你的代码编译为一个直接与 DOM 交互的高效底层代码。但 Svelte 是如何解决数据更改时重新绘制整个 DOM 的问题呢?

像 React 这样的框架需要你调用 API 方法,在数据发生变化时告诉它;但使用 Svelte 时,只需使用赋值运算符 = 就足够了。

如果状态变量——比如说 foo ——使用 = 运算符更新,则 Svelte 将仅更新依赖 foo 的其它变量,如前所示。这让 Svelte 可以仅绘制 DOM 的一部分内容,这些部分以某种方式从 foo 中获取它们的值。

我将省略实际的实现方式,因为这篇文章已经足够长了。你可以看看 Rich Harris 自己的解释:
https://www.youtube.com/watch?v=AdNJ3fydeao

结语

Svelte 3.0 是最近软件开发业的福音之一。有些人可能会说这是夸大其词,但我不这么认为。Svelte 背后的理念及其实现将使我们能向浏览器发送更少的 JS 模版,却做更多的事情。

反过来,这会带来性能更强、更轻量的应用程序,并生成更易阅读的代码。那么现在,Svelte 将很快取代 React、Angular 或其它流行前端框架吗?

现在我可以说答案是否定的。与它们相比 Svelte 相对年轻,所以它需要时间来成长、成熟,并解决一些我们可能还没发现的问题。

就像 React 诞生后改变了软件开发产业一样,Svelte 也有可能改变我们对框架的看法,以及我们开发新事物时的思路。

英文原文: https://blog.logrocket.com/truly-reactive-programming-with-svelte-3-0-321b49b75969

攀升 商睿P23 23.8英寸办公台式一体机电脑(六核i5-9400 8G 480GSSD 双频WiFi 无线键鼠 3年上门)商用家用

戴尔(DELL)R740 2U机架式服务器主机 银牌4110*2/16G*8/2TSAS*3/H730P-2G/750W双电/导轨 三年质保

戴尔(DELL)Hard Drive 服务器专用硬盘 2TB 7.2K SAS 3.5英寸

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/49546.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql是怎样运行的 从根儿 百度云_读书笔记-MySQL 是怎样运行的:从根儿上理解 MySQL...

mysqld_safe mysqld_safe是一个启动脚本,它会间接的调用mysqld,而且还顺便启动了另外一个监控进程,这个监控进程在服务器进程挂了的时候,可以帮助重启 它。另外,使用mysqld_safe启动服务器程序时,它会将服务…

MariaDB: 谁是更为正宗的MYSQL

随着Oracle买下Sun,MySQL也落入了关系型数据库王者之手。而早在2009年,考虑到Oracle的名声以及其入手之后闭源的可能性,MySQL之父的Michael便先行一步,以他女儿Maria的名字开始了MySQL的另外一个衍生版本:MariaDB。 Mi…

区块链入门教程

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。 区块链(blockchain)是眼下的大热门,新闻媒体大量报道,宣称它将创造未来。 可是&#xf…

真的会谢,ChatGpt能不能靠谱点

我想让GPT帮我生成一个可以实现一根绳子抖动的效果。 一直沟通: 然后它给我生成了一段还是达不到效果的代码,并且代码还不全! 本来我想要这种:TweenMax结合elastic-progress的弹性进度条动画 但是ChatGPT给我的代码最后效果是&a…

本科计算机论文致谢词,有关本科毕业的论文致谢词范文

有关本科毕业的论文致谢词范文 本科毕业论文致谢范例一 时间如梭,转眼毕业在即。回想在大学求学的四年,心中充满无限感激和留恋之情。感谢母校为我们提供的良好学习环境,使我们能够在此专心学习,陶冶情操。谨向我的论文指导老师王副教授致以最诚挚的谢意!王老师不仅在学业上…

计算机专业毕业设计致谢,那些笑哭的毕业论文致谢

原标题:那些笑哭的毕业论文致谢 相比正文的废话连篇,冗长乏味,致谢完全可以成为论文的弹幕,专供吐槽。咱们的致谢不用非得把七大姑、八大姨都拉出来感谢一番,像下面这些言语上既诙谐又大胆的致谢言辞,小编就…

html实训报告致谢,毕业论文致谢信(精选10篇)

毕业论文致谢信(精选10篇) 大学生活将要谢下帷幕,我们都知道毕业前要通过毕业论文,毕业论文是一种有准备、有计划的检验大学学习成果的形式,那么优秀的毕业论文是什么样的呢?下面是小编为大家收集的毕业论文致谢信(精选10篇),供大家参考借鉴,希望可以帮助到有需要的朋友。…

html项目的致谢词,毕业论文致谢词范文200字(精选10篇)

毕业论文致谢词范文200字(精选10篇) 导语:大学三年学习时光已经接近尾声,在此我想对我的母校,我的父母、亲人们,我的老师和同学们表达我由衷的谢意。下面是小编整理的毕业论文致谢词范文200字,欢迎参考借鉴! 毕业论文致谢词1 首先感谢学校为作者提供了深造的机会,在四年…

中科院博士论文致谢感人,如果让AI来写又会是怎样

今天,达摩院发布全球最大规模的 中文文本预训练语言模型——PLUG PLUG的参数规模达270亿 它集语言理解与生成能力于一身 在小说创作、诗歌生成、 智能问答等领域表现突出 还以80.614分刷新了CLUE分类榜单纪录 排名仅次于“人类”组 今天阿云也挑了几部经典作品…

matlab论文致谢,2020大学毕业论文致谢信

2020大学毕业论文致谢信 论文致谢词的作用主要是为了表示尊重所有合作者的劳动,它有利于促进形成相互帮助的社会风气。下面是小编为大家精心准备的2020大学毕业论文致谢信,仅供大家参考阅读! 2020大学毕业论文致谢信1 我选择了周老师的课题&a…

计算机专业毕业设计致谢,计算机毕业论文致谢范文3篇

计算机毕业论文致谢范文3篇 计算机是20世纪最先进的科学技术发明之一,对人类的生产活动和社会活动产生了极其重要的影响并以强大的生命力飞速发展它的应用领域从最初的军事科研应用扩展到社会的各个领域,已形成了规模巨大的计算机产业带动了全球范围的技…

毕业论文致谢到底要怎么写?

毕业论文论文的致谢怎么写? 这里的标题只是个问句,以下的文字并不会给出答案,毕竟,毕业论文的致谢是最难写的一部分。依我看来,毕业论文致谢,大抵分为两种,一种是中规中矩型,列一堆人…

计算机毕业论文致谢,计算机软件毕业论文致谢词

计算机软件毕业论文致谢词 致谢应以简短的文字对课题研究与论文撰写过程中间直接给予帮助的人员表示自己的谢意,这不仅是一种礼貌,也是对他人劳动的尊重,下面是小编搜集整理的计算机软件毕业论文致谢词,供大家阅读查看。 致谢一: 时间飞逝,大学的学习生活很快就要过去,在…

计算机科学与技术的论文致谢,毕业论文致谢200字(精选7篇)

毕业论文致谢200字(精选7篇) 充实的大学生活即将结束,同学们毕业前都要通过最后的毕业论文,毕业论文是一种比较重要的检验大学学习成果的形式,如何把毕业论文做到重点突出呢?以下是小编整理的毕业论文致谢200字(精选7篇),欢迎大家借鉴与参考,希望对大家有所帮助。 毕业论…

专科计算机毕业论文范文 致谢,专科毕业论文致谢范文(通用6篇)

专科毕业论文致谢范文(通用6篇) 导语:在这篇论文的写作过程中,我深感自己的水平还非常的欠缺。生命不息,学习不止,人生就是一个不断学习和完善的过程,敢问路在何方?下面和小编一起来看专科毕业论文致谢范文(通用6篇),希望有所帮助! 专科毕业论文致谢 篇1 大学三年学习时…

让 chatGPT-4 帮我设计一个分布式缓存系统,从尝试到被我逼疯!

ChatGPT狂飙160天,世界已经不是之前的样子。 新建了人工智能中文站https://ai.weoknow.com 每天给大家更新可用的国内可用chatGPT资源 比 ChatGPT 背后 GPT-3.5 更为强大的模型 GPT-4,已正式对外发布。在 OpenAI 官方发布的 GPT-4 Developer Livestream…

AI | 一秒生成专属动漫头像

随着人工智能的发展,想要把自己的照片变成动漫已经不是难题了,各种APP层出不穷,刷抖音应该经常看到一秒变身漫画少女的特效视频,这些都要归于人工智能。 随着国庆的到来,你的假期靓照可以动漫式的秀一波了。 今天就来…

Python使用AI photo2cartoon制作属于你的漫画头像

Python使用AI photo2cartoon制作属于你的漫画头像 1. 效果图2. 原理3. 源码参考 git clone https://github.com/minivision-ai/photo2cartoon.git cd ./photo2cartoon python test.py --photo_path images/photo_test.jpg --save_path images/cartoon_result.png1. 效果图 官方…

AI一分钟就能生成个性动漫头像?分享一个超好用的AI卡通头像生成器

你是否常常在社交媒体或短视频平台上看到一些精美的卡通风格头像,但是找遍全网都找不到完全相同的,其实这些动漫卡通风格的头像大多都是利用AI绘制的,不仅精美漂亮而且独一无二,不会与其他人的头像重复,所以今天就来给…

AI绘图第二弹!绘制专属动漫头像

上次推出AI绘图的文章后,热爱绘画的同志们,积极性很高!文章详情可以点击《最近非常火的AI绘图(附操作方法)》查看 这次,推荐一种绘制自己专属动漫头像的AI绘制方法! 这个AI绘制头像项目&#…