Vuejs设计与实现-权衡的艺术

ObjectKaz Lv4

声明式与命令式

命令式语法

命令式语法 让用户通过命令的方式去绘制页面。

通过原生DOM(除开innerHtml)来绘制界面就是典型的命令式语法。你需要一个个创建DOM节点,并维护DOM节点的更新和删除。当页面比较复杂时,通过原生DOM绘制页面往往需要大量的代码,且很多代码其实做的功能是重复的。

声明式语法

声明式语法 只需要让用户描述一下绘制的结果,绘制的任务交给框架来执行。

通过Vue.js或者React来绘制界面就是典型的声明式语法。在编写页面的时候,用户无需关注这个页面是如何生成的,只需要关注生成了什么样的页面就行。

声明式语法的好处

  1. 简化了开发者的工作。开发者只需要关心结果,不需要关心过程。
  2. 减少了重复的操作,更容易维护。其实页面的绘制过程基本上都是增加节点、删除节点、移动节点和修改节点样式,但是命令式语法下用户得一个个手动操作这些节点。
  3. 留下了改进空间。由于绘制的任务交给框架去执行了,框架就可以对绘制过程进行性能优化,但开发者声明的模板是不需要改动的。
  4. 让专业的人,做专业的事情。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的性能还不错

参考

  1. 从年会看声明式编程(Declarative Programming):https://zhuanlan.zhihu.com/p/26085755
  2. 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 进行许可。