加入收藏 | 设为首页 | 会员中心 | 我要投稿 核心网 (https://www.hxwgxz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 建站 > 正文

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

发布时间:2019-08-05 13:41:47 所属栏目:建站 来源:qiangdada
导读:特别说明 这是一个由simviso团队对 JSConf.Asia 中关于前端框架设计取舍相关话题进行翻译的文档,内容并非直译,其中有一些是笔者自身的思考。而分享者正是 Vue.js 的作者 @尤雨溪,Vue 仓库地址:github.com/vuejs/vue 让我们一起来了解下在当前框架三足

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

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

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

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

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

所以我们可以充分利用这两点。

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

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

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

但我会谈下 3.0 对这点所做的事,让它可以更快。

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

因此,当你感觉自己受到模板约束时,这会为你提供一条出路。

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

因此,很多用户虽然可以使用渲染函数,但他们可能从未使用过它。

现在让我们把它放到我们通过文件做的事情上,将 Vue 的模板编译成 VDOM,其运行速度比普通的 VDOM 要快。

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

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

所以,如果我们研究这个模板可以看出它是个非常简单的例子。

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

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

现在,这会创建一个动态节点结构,因为该节点可能存在或可能不存在。

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

但是如果我们尝试将其拆分,会看到 v-if 将模板拆分为两个嵌套块。

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

我们来思考一下,如果将 v-if 本身看作一个节点,外部块则会有一个静态节点内容、节点结构。

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

同理,对于每个 v-for 迭代我们也可以将其看成一个静态块。

因此,如果你有更多像 v-if 、内嵌 v-for 的写法,你只是在进一步将代码拆分成嵌套块。

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

所以,我们最终得到一种我称之为 Block Tree(区块树)的东西,这只是一种玩法。

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

但 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 节点,每次迭代都会动态绑定一些类或者文本。

(编辑:核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读