「2019 JSConf.Asia - 尤雨溪」在框架设计中寻求平衡

特别说明

这是一个由 simviso 团队对 JSConf.Asia 中关于 前端框架设计取舍 相关话题进行翻译的文档,内容并不是直译,其中有一些是笔者自身的思考。而分享者正是 Vue.js 的做者 @尤雨溪,Vue 仓库地址:github.com/vuejs/vue前端

让咱们一块儿来了解下在当前框架三足鼎立的局势下,如何直接透过框架自己了解到更多有关框架设计中的的权衡,以及 Vue 是如何进行取舍的。vue

视频地址:node

视频翻译版权归 simviso 全部react

前端公众号git

1、前言

你们好,很高兴来到这里。你今天过得怎么样? OKgithub

我很确定你已经看过不少讲座了,也知道今天此次课程,但愿此次不会太无聊,可是仍是要给那些不认识个人人简单地介绍一下我本身。算法

个人名字叫 Evan You,个人推特帐号是 Youyuxi,个人中文名字就是 Youyuxi。从2016年开始我就是一个独立的开源开发者。vuex

也就是说我如今已经独立开源三年了,主要从事 Vue.js。npm

大家中有多少人在真正的使用它?数组

很好

它从 2013 年开始做为个人一个业余项目 ,我从 2016 年开始全职维护它。在多年的框架设计工做中,我学到了不少东西,这也给了我不少关于内部设计的观点。人们在构建正确的框架时作出的一些权衡决策。

大家中有多少人还记得 2013年 的那段时间,那时可能天天都会有一个新的 JavaScript 框架出现,NBC 有一个相似 40,50个框架的列表,这些框架都在构建相同的东西,Vue 差很少是从它们的时代开始的,当时我只是在研究一些现有的解决方案,并试图找出若是我构建这样的东西,我会怎么作。

但很明显,我对应该作什么的想法随着时间的推移而发生了很大变化。

但今天我将讨论其中的一些发现,特别是前端框架设计。

2、框架取舍

我敢打赌,不少人都在使用框架,即便你不使用 Vue,也可能使用 React、Angular 或其余框架。

很难想象,在没有这样工具的状况下就去构建一个复杂的前端应用程序。

固然,你仍然能够使用普通的 JavaScript 去作这些事,只是那样将花费咱们更多的时间。

我猜当大多数人在面对这些框架的时候,会疲于对这些框架进行比较。

每当媒体给我推送关于框架比较的文章时,好比《2019最好用的7个新框架》,我一般会说:“咦~”

这不是由于说:“啊,我写了 Vue,我想让人用它,我不想听到有人说它的坏话”

而是由于大多数时候,这些文章只关注 github 的 star 数,npm下载量,stackoverflow 问题统计等这些能够随时随地经过 Google 查找到的内容。

可是,这些统计数据在某种程度上仍是有用的,好比对于市场营销来讲。

可是若是你尝试去作一个技术决策,而且尝试去和市面上已经成熟的技术去竞争的话,那么这些数字在某个阈值上的相关性会愈来愈小。

好比,咱们在生产环境使用的东西,你知道的大部分可能都过了 10000 个 star 了。

但这个门槛真的那么重要吗?一个库到底有几千 star?

这并不重要,相反你应该更关心的是一些内部技术决策,好比致使这些框架的延迟发布的真实缘由是什么。

因此在咱们深刻研究以前,咱们先退一步思考下全部的这些框架的共同目标,咱们都在努力实现的同一目标。全部框架的做者们都在朝着“让大家尽可能能更高效地构建 Web 应用程序”这一目标而努力,那么为何咱们还要有这些不一样比较的竞争的想法呢,这究竟是好仍是坏呢?

因此为何咱们有这么多不一样的框架,并且每一个框架都有不少的追随者呢?

就像 React 和 Angular 各自都有超过 50 万的用户。

我认为不能单纯的以一个好与坏来评价一个框架。

人们每每会问一些问题,好比哪一个框架更好,请别再问这个了。

由于咱们很难简单地去评定一个框架要优于另外一个框架。

咱们都知道软件设计在于取舍,事实上咱们如今的前端框架设计有太多的地方须要进行取舍,尤为是在 Web 中。

由于 Web 是一个充满多样化元素的平台。

咱们能够在 Web 上构建各类有趣的事情,不管是最简单的页面仍是到你所天天使用的复杂程序。

所以,为了适应全部这些状况,框架制定者必须在多方面进行取舍。

今天我会将其中的一些拿出来聊聊,但愿能对你在这块的见解有所帮助。可是因为时间缘由,我确定不能很是深刻的去讲解每种状况。

因此,我只会专一其中的一部分。

第一:职责范围。从本质说是指这个框架能够为你作多少事情。

第二:渲染机制。当你在使用一个框架的时候,你会如何表达你的视图层,框架如何处理代码?它是如何将实际渲染东西展现到页面上的?

第三:状态机制。可变和不可变,脏检查和依赖追踪,响应式和类响应式。实际上,我没有时间去深刻研究这个,这个或许能够在下次分享中好好谈论下。

3、职责范围

此次,我深刻探讨下职责范围。看看一个框架能为咱们作什么事情。

咱们将它一分为二,从大家的角度来看,这个框架或库能作一些特有的小事情,从咱们的角度来看,咱们会有不少总体性的考量,拿框架来讲,我会尽可能提供尽量多的特性。

一、React & Angular

举一些你们可能比较熟悉的表明性的例子,React 接近于原生库,Angular 则提供更多抽象概念。

不多有人会去说清楚原理,这个库(React)专一于提供一个很是基础的 UI 模型,它专一于提供更底层的原生实现,基于此你能够构建出一套属于本身的抽象。

有意缩小职责范围(设计理念),这也是React整个生态系统很是活跃的缘由所在,React的社区环境就像个商城(系统),围绕着 React 的核心模型自底向上创建起来的一整套生态系统。

另一方面,像 Angular 以及其余的一些框架,如 Ember、 aralia 这种,则更像是大教堂吧。

它们则是自上而下进行设计的,在设计过程当中,用户可能会遇到的问题都被考虑在内。

例如大家在平常开发中会常常遇到的表单验证,动画效果等等。

为了让框架能够给咱们提供一个解决方案,在这个框架设计之初,咱们就要以自上而下的方式来对它进行设计,即咱们须要去思考如何将全部事情放到一块儿去工做。

有意扩大职责范围(设计理念),这个设计理念就是当你尝试解决一个问题时,你在框架内就能找到解决方案。

咱们把这称之为大小职责范围(这里指两种设计理念),而这也没有好坏之说。

我想再次强调下。

二、Small Scope

优势

小的职责范围(设计理念)它的好处在于,刚开始的时候须要理解的概念不多。

并且它具备更好的灵活性。因为框架、库只提供了部分底层的原生实现,因此当你须要一个组件类的话,它得有一些 Props,而后你能够经过 Props 来传递数据,返回 VDOM 节点。

最重要的是,你能够构建任意复杂的系统。

React 有一个很是活跃的生态系统,咱们能看到它拥有一些很是灵活的工具,而后,咱们能够基于它们发挥出更大的创造力,而这些很棒的想法都来自 React,React 社区。

另外,有意缩小职责范围,也可让团队拥有更小的维护层面,以便他们能够专一于他们认为重要的事情。

这样团队能够专一于探索一些比较有创意的点子,这也是为何 React 能够花这么多时间来作 concurrent mode、suspense、React Hooks 以及在过去几周或几个月内一直在创造的全部的这些有趣的东西。

实际上他们在这些事情的开发上已经花了好几年了,只不过由于它们的粒度比较小,正是由于这样他们才能更加专一于这个事情上。

缺点

固然,小范围的设计也是有一些明显的缺点的。

首先第一点,当你想用一个简单的概念去解决一个原本就很复杂的问题的时候你须要作更多的钻研工做。

我特别喜欢 Steele 这个家伙在一场演讲中说的一句话:“培养一种语言”。在演讲期间,他给本身制定了一条规则,他在演讲期间必须使用单音节词,若是你想用任何相似于多音节词的话,他必须先用单音节词来定义它。

他只有很是有限的、很是原始的一些东西,去构建一些复杂的想法。

因此你能够想象一下那次演讲是怎么回事。

在他每次想要说出本身喜欢的一句话以前,他都要翻出一些幻灯片而后找出一堆单词,而后继续。这有点像用很是低级的原始语言去构建一个很是复杂的生产级别的应用程序。

你必须构建大量的抽象概念,以便在此过程当中提升本身的效率。

正由于如此,模式天然会随着时间的推移而出现。

当咱们说 React 是真的容易上手的时候,咱们是否有些忽略了你或多或少须要学习 Redux 的事实。在你认为本身是一名真正的 React 开发人员以前,你必须先去了解 HOC 高阶组件、render props。而后如今,你又要去学习 Hooks 以及在 JS 中使用 CSS 的各类方式。

尽管这些模式随着时间的推移而出现,但它们却变成了半须要的状态。若是你不了解这些,你真的能够称本身是一名 React 开发人员吗?

而这些东西每每没有官方文档。若是你去 React 官方网站,它是不会告诉你某个 CSS 和 JS 的解决方案的,你必须本身去研究并学习它。

这就是为何使用者真的须要有自主学习能力的缘由所在。

现现在,生态系统发展太快可能会致使碎片化和使用者的不断流失。我相信早期 Flux 思想的追随者,会发现天天都有一个新的 Flux 方案具体实现,而后每一个 Flux 的具体实现都会对应新的 CSS/JS 的实现。

这样很好,同时好处就是总会有新的想法出现。一样,咱们也在努力寻找最佳方案。

可是,这对于那些只想跟在后面去使用的人来讲是很差的,你会不断的有FOMO思想(Fear of Missing Out,惧怕错过),老是怕错过下个最好的东西。

三、Large Scope

咱们已经说完了小职责范围(设计理念)的缺点。如今让咱们来谈谈大职责范围的一些优势。

优势

最明显的优势是能够经过构建抽象概念来解决最多见的问题。

若是你只是想作一些开发,我只须要一个路由、一些动画以及一个 HTTP 客户端来获取一些数据。

像 Angular 这样的框架则提供了全部你须要的东西,来实现这一目标。

事实就是你没必要处处查资料,你只要照着它的文档去用框架,你就能够搞定这些事。

集中式的设计确保了它自己与其生态系统的一致性。

当你遇到一个具体问题的时候,你没必要去找一些不一样的解决方案,你只须要看看框架它让你作什么,最大的可能就是它(框架)对此已经有解决方案。因此你压根没必要去挖掘所谓的10种不一样的解决方案,而后找出对你案例最佳的那一个。

缺点

如今来讲下缺点,这样的缺点就是会有一个更高的学习门槛。

为了将一个像素放到屏幕中,你必须跳过一些步骤才能作到,这对于初学者来讲是一个很大的障碍。对于那些不适应的人,我这里不说那些适应的人哈,若是你没有相似使用 Java 或者 C# 等语言经验的话,而是仅仅只学过 HTML/CSS 以及 JavaScript 的话,当你看到 Angular 文档的时候,你可能会以为有点难以想象。

对我来讲也是如此。

而后,若是内置的解决方案是不适合当前用例的话,它则会变得不灵活。有时候你可能以为我只是想用另一种方式来作,可是我却没方法来将其替换。

最后,一个职责范围大且成型的框架会使得引入一些底层新想法的成本更高,由于太多的地方都要保持其一致性。

而后当你想尝试用一个底层想法的时候,它会影响到你项目中的每一个组件(牵一发而动全身)。

因此要作这种 “改变”,就变成了一件很困难的事情。而若是你在 React 的生态系统中说,我引入 Hooks 会让 Redux 更加冗余,那么朋友,这并非一个真正的问题,由于 React 它的核心团队实际上并不会负责这些解决方案。

就是这样,okay。

四、渐进式框架 Vue

这正是 Vue 所处的位置。但在咱们深刻了解 Vue 如今正在作的事情以前,我想强调的是,我并非说 Vue 比这两个框架都好。

由于处于中间位置不必定就是最好的。若是 NG 和 React 在某个功能的封装程度上差别很大,Vue 要作的就是去缩小差别,而后你会发现实际上 Vue 并无作到最佳。

因此,这就好像咱们稍微推迟去寻求咱们所认为的最佳平衡点。而每个选择都会适用于不一样人群的须要。

它并不像一件东西同样,能够适用于全部人。

因此我所说的 Vue 在职责范围这个问题的处理方式上,你可能知道咱们都叫 Vue 是一个渐进式框架。

优势

职责范围渐进意味着框架使用分层设计,它容许以渐进的方式选择特性。也就是说,若是你不须要路由,若是你不须要状态管理,甚至若是你不须要构建步骤。你能够使用没有任何特性的 Vue,你只须要将 vuejs 拉到你的页面中,而后你就能够当即开始作一些事情。

对于初学者来说,一个须要翻越的学习障碍,就是刚开始学习时就要求你从屏幕中获取一个像素并移除它。

因此,低的学习门槛对咱们来真的很重要,这也是 Vue 的一个使命:容许更多的人参与 Web 开发,容许人们学习它(Vue)并专一于开发,而不是让你学习一堆在你当前开发可能不须要的概念。

可是对于当前的这些问题,咱们仍然有经过文档去提供解决方案。当你的用例变得更复杂的时候,当你要构建更复杂的东西的时候,这时你意识到本身须要一个路由。而后你就开始翻阅文档,你会发现,okay,我确实能够使用路由去作这个。

但与此同时,路由它又并非必需的。而且,若是你愿意的话,你本身也能实现一个路由,由于你能看到 Vue 的路由是如何构建的,而且它的核心实现是很是干净的, 因此若是你愿意的话,是能够用本身的方式去构建一个的。

缺点

它并不完美,由于做为中间者,咱们须要去权衡二者的利弊。

因此首先,尽管咱们会采用新增模块(集成 router、vuex 等),但咱们仍然须要负责维护它们(router、vuex 等)

因此,咱们分享了大职责范围下统一维护面的问题,咱们要想从根本上改变一些东西,咱们必须确保整个生态系统的一致性。

这个维护负担几乎与大职责范围相同,同时也由于咱们提供了这些预置的解决方案。

咱们的生态系统可能不会像小职责范围那样多样化。由于小职责范围喜欢把问题抛给社区。而在咱们的案例中,不少用户很满意咱们的解决方案,同时本身也不用再花费时间去找答案。

这就是职责范围的问题,但愿你如今已经有所了解了,我认为这就是 React、Vue 和 Angular 之间最根本的区别。

这是它的准肯定位,也定义了咱们不一样的用户群。

不少时候,咱们都是在有意决定所扩展的领域。做为框架设计者,咱们知道咱们正在驾驭不一样的领域。这是件好事,由于在整个阶段,不一样的开发人员须要不一样的解决方案,以及拥有覆盖整个主要框架的规范,确保每一个人都获得他们想要的。

4、渲染机制

OK,如今咱们来谈谈渲染机制。

也就是说你该如何经过框架来表现本身的UI结构以及该框架是如何进行渲染的。

首先,从操做层面来说它真的很复杂,它不只仅是一件事,它包含了不少层面。

简单点来说,能够将它当作 JSX 与 Templates,即动态渲染函数和基于静态字符串的复杂的 Vue 表达式。而后就是表现力和原生性能,以及运行时调度和提早优化。

有些人对此会有很强烈的意见,但我我的认为他们本质上是很类似的,他们只是对同一个底层理念的不一样策略表达。

能够说更多的是技术上的权衡。

一方面,固然是 JSX React 以及全部使用 VDOM 的 react-like 库,好比 pre-act、 stencil, infernal 等。

另外一方面,则是基于模板的解决方案。我稍后会讨论 Vue,但更具表明性的基于模板的解决方案有 Svelte,还有就是 ember。

能够看到,那个 logo 其实是 glimmer.js 的 logo,也就是说,glimmer 是 Ember 里的渲染引擎,一样也是 Angular 的渲染引擎。

这些主要是基于模板的,它们将模板编译成相对较低级别的指令来进行内容渲染。

一、JSX / VDOM 优势

如今咱们来谈谈 JSX 和 VDOM 的一些优势。

咱们喜欢 JSX 或 VDOM 最重要的缘由就是它们具备 JavaScript 的完整表现力。

你无须在乎语法,你有一种可供你使用的语言,你就能够有完整的体验,你能够作任何你想作的事。

不只这样,你还能够在你的组件上构建任意复杂的逻辑。

它真的很强大、不作约束,也由于这个特色,不少人喜欢上了 React 。

它还容许你在渲染组件时将视图层视为数据。它会返回一些东西,返回节点表示当前状态的VDOM 节点,这个数据能够用于不少有意思的地方。

它对于咱们构建测试方案颇有用,你能够根据虚拟Dom获取快照,你能够将它渲染到须要替换的目标,也就是咱们一直在作的事情,好比将它渲染到终端、PDF、Canvas、WebGL,以及任何你能想到的你能够渲染的东西。

由于视图就是是数据,而你能够对数据作任何操做。

二、JSX / VDOM 缺点

目前,VDOM 自己成本真的很高。

想想,当咱们刚出来的时候,不少人都认为,这不是很慢吗?答案是 Yes,咱们很慢,但速度却足够快!

可是,仍然从纯粹的技术角度来看,你作了不少多余的工做。想一想这个简单的模板,它只须要更新其中单个消息绑定就能够完成大量的工做。

咱们必须遍历整个 VDOM 节点而且作 Diff,在这个过程当中,一直以递归的方式向下传递,直到你以某种方式更新它。

所以,标准 VDOM 不一样的代价是相对于视图的总大小,而不是可能改变的节点数量。

即便你只有一个节点,也可能会触发 这个VDOM 的 Diff 算法。

正是因为渲染函数的动态特性使得它难以优化。

关于动态性,个人意思是你能够写这样的代码。

你能够使用一个 for 循环来构建一个 children 数组,而后将它交给你的父节点,以及接下来进行你想要作的其余事情,也就是说你能够先建立一个父节点,而后经过往它的 children 中添加元素来进行改变。

你在使用 JavaScript 的时候,编译器不可能hold住全部可能发生的事情,由于 JavaScript 太过于动态化。

在这块咱们已经作了不少尝试,但从本质上来讲,咱们很难经过这种方式对其提供安全的优化。

由于它不是你简简单单作足够多的条件预断就能够的,你对用户意图作的预判越多,代码越容易优化,这对于Javascript来说实在太难了。

最后,React 对于这块的解决方案就是不把重心放在加快 VDOM 自己的速度,而是如何提升感知性能。

所以,React 引入了运行时调度并发时间切片的概念,可是这种运行时调度方案,整个 fiber,几乎和咱们管理本身的堆栈同样,好比进入和退出渲染,全部的东西都须要很长的运行时间。

这意味着不管你什么时候加载 React,都必须去加载那些用于处理复杂的运行时调度工做的全部必需代码。

这就像加载几个20、30KB 大小的 JavaScript 同样。

反过来,这也会让你的初始化加载受到一点影响。

三、模板编译优势

另外一方面,若是你是在模板中编译的渲染代码,一般它能够生成一个更加直接的渲染指令,而且具备更好的原生性能。缘由就是:根据定义,模板是一种很是有约束的语言,你只能以某种方式去编写模板。

例如,当你写出这样的代码的时候,咱们能够马上告诉你,这些 p 标签的顺序是不会变的,这个 id 是不会变的,这些 class 也不会变的,惟一会变的就是这个。

静态(编译)和很是严格的限制其实是容许编译器对你的意图作更多的预判,从而给它更多的空间去作执行优化。

咱们来看看 SVELTE 编译代码时会作什么。

其余全部内容都是静态的,只有 name 可能会发生改变,这个 p 是一个 update 函数,它惟一作的事情就是当 name 发生变动的时候对它(name)进行更新。

将 SVELTE 与 VDOM Diff 算法所作的事情相比较的话,它只有到达必定量级才会更快。

因此说,根据策略的不一样,模板编译或者基于通用编译的方法也能够使 runtime baseline 更轻量,由于它不须要全部的复杂运行时调度来尝试让事情看起来更快,由于它自己已经很快了。

因此 SVELTE 能够产出一个很是轻量的输出,而不须要一个很重的 baseline runtime 来适应全部可能的 runtime 行为。

四、模板编译缺点

如今来看看模板编译的缺点。很显然,你会受限于模板语法,从而失去 JavaScript 的表达能力。

因此,当你想去构建一个真正复杂的组件的时候,你会想我要能够在模板里这样作多好,然而编译器对此并不支持。

很不走运,若是你选择完整的编译路线,那就没有退路,由于级别越低的编译输出,实际上你越难将你的自定义操做与它进行挂钩。

就比如 opa 编译器,你是没法深刻到汇编去看看为何会这样,就比如你没法使用 C 语言去调试你的汇编代码。

更轻量的 runtime、更轻量的 baseline runtime,也多是以每一个模板更详细的输出做为代价。由于当你试图去生成尽量高效的代码时,有时你必须直接在输出的时候编码更多信息。

例如,SVELTE 生成的代码实际上是以命令式的形式经过逐行插入建立了全部元素,而且它们有一个单独的函数进行更新操做。

相比之下,基于 VDOM,结果是你只须要一行,而这(一行)只是一个返回 VDOM 结构的表达式。

若是在运行时编译,则会产生运行时编译成本。

所以,对于生产用例来讲,最有可能的状况是你须要用户事先编译,这样对于构建步骤来讲是一个硬性要求,这是不可避免的,要么在运行中进行编译,要么在预构建中进行编译,其中涉及咱们如今或多或少习惯的全部node.js工具链。但若是你能避免的话,对于初学者来讲是件好事。

OK,所以,Vue 又一次夹在中间,我想再次强调,这不是说 Vue 是最好的。

可是,Vue 的渲染机制独特之处在于,若是你真的将模板结合到 VDOM 中,那么咱们能够同时拥有 VDOM 和模板编译。

因此咱们能够充分利用这两点。

咱们有作过性能测试:在编译步骤中产生的特别优化,咱们不作渲染功能,稍后我将详细介绍这一点。

在 vue2.x 版本,咱们实际上尚未充分利用这个机会,当前 vue 2.x 中的 VDOM 性能这块表现平平。

但我会谈下 3.0 对这点所作的事,让它能够更快。

还有表现力,你能够跳过模板层直接进入渲染函数,直接利用JavaScript来执行任意复杂的逻辑。

所以,当你感受本身受到模板约束时,这会为你提供一条出路。

缺点是,尽管咱们如今确实很快,咱们可能永远不会比 SVELTE 感受起来快。由于 SVELTE 的输出是最普通的 JavaScript。然而,为了兼容手写的渲染函数,Vue 仍然须要维护 VDOM,这样一来常量则必不可少。另外一方面,它也会产生分歧,即我到底应该使用哪种方式?

所以,不少用户虽然能够使用渲染函数,但他们可能从未使用过它。

如今让咱们把它放到咱们经过文件作的事情上,将 Vue 的模板编译成 VDOM,其运行速度比普通的 VDOM 要快。

这就是咱们刚才已经讨论过的,这个模板只有一个节点会改变。理想状态下咱们只需直接更新 message 字符串,节点结构是静态的,而且历来不会发生变化,只有一个动态节点。

因此,若是咱们研究这个模板能够看出它是个很是简单的例子。

当咱们有相似于 v-if 这样的东西时,它会变得有点复杂,咱们称之为 JSX 中的结构指令,它至关因而根据条件返回不一样结果判断的三元表达式。

如今,这会建立一个动态节点结构,由于该节点可能存在或可能不存在。

为了处理这种简单的 VDOM Diff 算法,假设节点列表已经改变,那么咱们须要对两个子数组进行 Diff 操做。

可是若是咱们尝试将其拆分,会看到 v-if 将模板拆分为两个嵌套块。

咱们来思考一下,若是将 v-if 自己看做一个节点,外部块则会有一个静态节点内容、节点结构。

在 v-if 内部,它也是静态的。咱们有两个静态块,在每一个块内,你无需对节点顺序进行 Diff 操做,你惟一要作就是这个块内部进行数组的扁平化操做。

同理,对于每一个 v-for 迭代咱们也能够将其当作一个静态块。

所以,若是你有更多像 v-if 、内嵌 v-for 的写法,你只是在进一步将代码拆分红嵌套块。

因此,咱们最终获得一种我称之为 Block Tree(区块树)的东西,这只是一种玩法。

但 Block Tree 是一个嵌套块的块列表,由于每一个块中都有一个彻底静态的节点结构,全部没有必要使用递归到下层去对子列表进行 Diff 操做。

在每一个块中,你只有一个单一扁平化数组节点可能会发生改变,咱们还提供了其它组织上的提示。例如,若是一个节点只有一个动态 class 绑定,咱们有条捷径,即你只需直接设置 class,而后就能够继续执行,而没必要对 Props 进行 Diff 操做。

因此,对于同一模板的 Diff,vue2.x 版本和 vue3.x 版本的作法会有明显的区别。vue2.x 版本咱们须要作一个完整的 Diff 操做,vue3.x 版本咱们就只需经过使用一个单一扁平化数组(包含一个动态文本节点),而你惟一须要作的事情就是比较文本是否发生了改变。

对此,咱们作了一个简单的基准测试(benchmark), 作 1000 个 v-for 列表迭代,每一个块有 12 个 dom 节点,总共 12000 个 dom 节点,每次迭代都会动态绑定一些类或者文本。

而后咱们在页面上作了 4000 个动态绑定,而后对其更新。咱们作了 100 次运行,在目前 2.6 的版本,更新时间要 36ms,而在目前 3.0 的版本中,使用新的编译策略,只须要大概 5.4ms,比以前快了6倍多。

注意,(数据)仅限于这个基准测试。真实的应用中你可能会有一个不一样的数字,但或多或少,它都会更快,这是一个基准。

5、状态

而后,在状态机制这块,我可能没有时间去真正深刻研究这个问题,它可能会是另一个演讲的话题。

6、总结

可是仍是总结一下,当你试图去设计一个框架时,最佳平衡点在哪?

或许这个问题应该从新表述下。是否存在一个完美的平衡点?它又是不是一个单一的完美的平衡点,甚至是以 JS 开发人员做为一个总体的最佳平衡点?

由于像咱们全部人同样,都在努力去优化咱们正在构建的一些特定又不一样的东西。

好比说 SVELTE,它的优点在于当你构建一些小的东西时,它能够产出很是轻量级的代码。它也很是快,消耗内存也很是少,因此它甚至能够像嵌入式设备同样使用。

可是若是在你本身的使用场景中,你可能会有一个更复杂的实现,你会有更多的组件,你想要 JavaScript 的表现力,同时你也须要模板提供更多的性能,那么(这种场景下)你能够使用 Vue。若是你不是很在乎一些极端的性能,而后说我就是喜欢 React 的生态系统,那么你能够使用 React。

你也能够选择全部这些(框架)。我认为这样很好,框架领域能像一个多维空间,有多个不断变化的实体,就像把每一个框架都想象成一个试图寻求平衡点的实体。相信咱们老是会有不少人去努力找出什么是最佳的作事方式。

做为一个开发人员,你可能会在这些实体之间游移不定,而后你可能会被其中的一个吸引过去,有时你有可能只是在周围跳来跳去,而后试着去找出最适合你的一个。我认识这是件好事。

可是做为一个使用者,尝试在这个多维空间中找到正确方法是很是困难的。

可是若是你想正确的选择框架,难的就是你必须了解框架所作的一些内部权衡,你必须知道这个框架朝着哪一个方向发展,而且知道它与你构建的东西是否一致。

但愿经过此次演讲所阐述的话题可以帮助到你,即当你尝试在将来选择框架、或者当你告诉别人应该如何选择框架时,能给予你帮助。

谢谢。

相关文章
相关标签/搜索