Vuejs设计与实现-权衡的艺术
声明式与命令式
命令式语法
命令式语法 让用户通过命令的方式去绘制页面。
通过原生DOM(除开innerHtml)来绘制界面就是典型的命令式语法。你需要一个个创建DOM节点,并维护DOM节点的更新和删除。当页面比较复杂时,通过原生DOM绘制页面往往需要大量的代码,且很多代码其实做的功能是重复的。
声明式语法
声明式语法 只需要让用户描述一下绘制的结果,绘制的任务交给框架来执行。
通过Vue.js或者React来绘制界面就是典型的声明式语法。在编写页面的时候,用户无需关注这个页面是如何生成的,只需要关注生成了什么样的页面就行。
声明式语法的好处
- 简化了开发者的工作。开发者只需要关心结果,不需要关心过程。
- 减少了重复的操作,更容易维护。其实页面的绘制过程基本上都是增加节点、删除节点、移动节点和修改节点样式,但是命令式语法下用户得一个个手动操作这些节点。
- 留下了改进空间。由于绘制的任务交给框架去执行了,框架就可以对绘制过程进行性能优化,但开发者声明的模板是不需要改动的。
- 让专业的人,做专业的事情。DOM操作不当可能会带来强制重排重绘等副作用,将这些操作交由框架来统一完成可减少这些副作用。
声明式语法的性能
声明式语法的性能不优于命令式语法的性能。
在页面展示时,声明式语法最终仍需要转换成命令式语法(DOM操作),这种转换是需要时间的。
- 命令式:操作DOM的时间
- 声明式:找出差异的时间+操作DOM时间
Vue选择声明式语法
尽管性能上声明式语法比命令式语法差一些,但声明式语法更容易维护,所以Vue选择声明式语法+找出差异的时间最小化。
虚拟DOM
介绍
前面指出,Vuejs要将找出差异的时间最小化,而虚拟 DOM,就是为了最小化找出差异的性能消耗而出现的。
但是,从上面的内容可以看出,虚拟DOM更新页面的性能从理论上来说不优于命令式语法的性能。但这是理论上的,因为写出性能最优的命令式语法是很困难的,就算写出,投入产出比也不高。
虚拟DOM希望让页面能够有不错的性能,也能让用户通过声明式编程方便写代码。
innerHTML与虚拟DOM
先上一个结论,DOM层面的操作比纯JavaScript的操作要慢的多。(详见书上的跑分对比图片)
两种方案的对比:
| innerHTML方案 | 虚拟DOM方案 | |
|---|---|---|
| 创建DOM | 拼接字符串的 JavaScript 计算+innerHTML的 DOM 计算 | 创建 JavaScript 对象的计算量 + 创建真实 DOM 的计算量 |
| 更新DOM的影响因素 | 与模板大小有关 | 与模板大小有关 |
| 更新DOM | 拼接字符串的 JavaScript 计算+销毁 DOM+创建新DOM | 创建 JavaScript 对象的计算量 + Diff的计算量 + 更新 DOM 的计算量 |
| 更新DOM的影响因素 | 与模板大小有关 | 与数据变化量有关 |
创建DOM时,二者的性能似乎是差不多的。但是更新时,虚拟DOM只跟数据变化量有关,跟模板的大小无关;innerHTML跟模板有关,模板越大,更新的时间越长。
三种方案的对比
| innerHTML | 虚拟DOM | 原生 | |
|---|---|---|---|
| 心智负担 | 中等 | 小 | 大 |
| 可维护性 | 强 | 弱 | |
| 性能 | 差 | 不错 | 强 |
运行时和编译时
- 纯运行时框架:不能分析用户输入的内容,也不能提供额外的支持(如TSX)简化声明式语法
- 纯编译时框架(Svelte):可以直接编译成原生DOM代码,理论上性能更优,但有损灵活性,用户的内容必须要编译才能使用。
- 运行时+编译时框架:分析用户提供的内容、简化声明式语法、虚拟DOM的性能还不错
参考
- 从年会看声明式编程(Declarative Programming):https://zhuanlan.zhihu.com/p/26085755
- Vuejs设计与实现
- 标题: Vuejs设计与实现-权衡的艺术
- 作者: ObjectKaz
- 创建于: 2022-07-20 03:11:41
- 更新于: 2022-08-16 15:02:45
- 链接: https://www.objectkaz.cn/cc3ace8068dc.html
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。