vue.js的设计与实现(权衡的的艺术-命令式和声明式)

devtools/2024/9/25 17:15:00/

权衡的的艺术

  • 什么是命令式和声明式呢?
  • 性能与可维护性的权衡
    • 那么,问题又来了,为什么vue.js不选择性能更好的命令式,而选择声明式呢?
  • 虚拟DOM的性能到底如何
  • 总结

什么是命令式和声明式呢?

我们来看一下jQuery,他是典型的命令式框架,命令是框架的一大特点就是注重过程

$('#app').text('hello word').on('click',()=>{alert('ok')})

我们可以看到上面这一段代码,做的事情是:获取到id为app的元素,把他的文本内容更改为hello word,并添加了一个点击事件,点击后弹出ok提示

我们再看看声明式的写法(以vue来举例)

<div @click='()=>{alert("ok")}'>hello word</div>

看以上代码,往往声明式的框架关注的是结果。关于这个结果如何实现的,我们并不需要关系,vue.js会帮我们实现。换句话说:vue.js帮我们封装了过程。
因此,我们不难猜出,vue.js内部一定是命令式的,而暴露出来给用户的却更加声明式

性能与可维护性的权衡

在这里我们先抛出一个结论:声明式代码的性能不优于命令式代码的性能

为什么会得出这样的结论呢?很简单我们假设一下,我们要把上面的div的内容要改成 ‘hello vue3’有没有比一下代码性能更好的呢?

div.textContent = 'hello vue3'

答案是没有 为什么呢?

我们现在来思考一下,如果是声明式框架会怎么样,如以下代码

<!-- 之前: -->
<div @click='()=>{alert("ok")}'>hello word</div>
<!-- 之后 -->
<div @click='()=>{alert("ok")}'>hello vue3</div>

这个是他的描述结果,要从之前的word改成vue3,对于框架而言,如果需要实现最优的性能,那一定是找到前后的差异并只更新变化的地方,但最优的更新代码仍然是:

div.textContent = 'hello vue3'

我们把A定义为:直接修改的性能消耗,B定义为:找出差异的性能消耗
那么:

命令式代码的更新性能消耗:A
声明式代码的更新性能消耗:B+A

我们可以看到,声明式代码会比命令式代码多出找出差异部分的性能消耗,最理想的情况就是 B为0(找出差异的性能消耗为0)是,命令式代码和声明式代码的性能消耗相同,但是无法做到超越。毕竟框架本身就是封装了命令式代码才实现了面向用户的声明式

这里就符合我们最开始得到的解困:声明式代码的性能不优于命令式代码的性能

那么,问题又来了,为什么vue.js不选择性能更好的命令式,而选择声明式呢?

问题就在于:声明式代码的可维护性更好,我们通过以上的代码,我们可以明确的感受到:命令式代码,我们需要去维护整个过程,而声明式代码,我们只需要展示结果就可以,看上去更加的直观,至于做事的过程,我们并不需要关系,因为vue.js已经帮我们封装好了。而框架设计者要做的就是把B(找出差异的能量消耗)降低到最小,也就是在保持可维护性的同时让性能损失最小

虚拟DOM的性能到底如何

我们在上面提到了 声明式代码的性能消耗 为 A+B(直接修改的性能 + 找出差异的性能)
如果我们最小化B,那我们声明式代码就无限趋近于命令式代码,这里我们就需要说到vue.js虚拟DOM

虚拟DOM就是为了最小化找出找出差异最小化出现的

具体的虚拟dom的diff算法 我们在后面再说。其实我们都知道 涉及dom层面的计算远比JavaScript层面的计算差,我们这边就来对比一下虚拟dom和innerHTML的在创建页面时候的性能

虚拟dominnerHTML
纯JavaScript层面的计算创建JavaScript对象(VNode)渲染HTML字符串
DOM层面的计算新建所有的DOM元素新建所有的DOM元素

可以看到在创建页面的时候无论是纯JavaScript层面的计算和dom层面的计算,两者的差距不大。
我们再看看在更新页面的时候

虚拟dominnerHTML
纯JavaScript层面的计算创建新的JavaScript对象 + Diff渲染HTML字符串
DOM层面的计算做必要的dom更新销毁所有旧的dom元素,新建所有新的dom元素

我们可以看到,在更新页面的时候,在纯JavaScript层面的计算要比创建页面的时候多了一个diff的性能消耗。在dom层面的计算,我们可以看到虚拟dom只会做必要的dom更新,但是innerHTML来说,需要全量的更新,这时候虚拟dom的优势就体现出来。

我们在更新页面的时候 加上性能因素

虚拟dominnerHTML
纯JavaScript层面的计算创建新的JavaScript对象 + Diff渲染HTML字符串
DOM层面的计算做必要的dom更新销毁所有旧的dom元素,新建所有新的dom元素
性能因素与数据的变化量相关于模板的大小相关

这张表格的的意思是:虚拟dom的性能因素是diff,在innerHTML的性能问题主要是销毁所有的旧元素,在新建所有新的dom元素,如果模板越大,在dom层面的性能消耗也越大
我们粗略的终结一下 innerHTML、虚拟dom 以及原生 JavaScript(指createElement等方法)在更新页面时的性能


性能差 ——> 性能高

innerHTML(模板)虚拟dom原生JavaScript
心智负担中等心智负担低心智负担高
性能差可维护性高,性能不错可维护性差,性能高

总结

  • 我们先讨论了命令式和声明式的差异,其中命令式更加关注过程,而声明式更加关注结果。命令式在理论上时可以做到性能极致的优化,但是用户需要承受极大的心智负担;而声明式能够有效的减少用户的心智负担,但是性能上有一定的牺牲,框架设计者要想办法尽量的使其性能的损耗最小化
  • 接着我们讨论了虚拟dom的性能,并给出了一个公式,声明式的更新性能消耗 = 找出差异的性能消耗 + 直接修改的性能消耗,虚拟dom的意义就在于找到差异的性能最小化。

http://www.ppmy.cn/devtools/98675.html

相关文章

MyBatis核心机制

实现MyBatis核心机制环境搭建 1.核心框架示意图 2.模块搭建 1.创建maven项目 2.引入依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSc…

C++ 内嵌 python 解释器

AI 提供 #include <Python.h> #include <map> #include <string>int main() {// 初始化 Python 解释器Py_Initialize();// 创建一个 C std::mapstd::map<std::string, int> myMap {{"apple", 3},{"banana", 5},{"orange&quo…

Linux系统性能调优指南-定期维护

目录 定期维护 日志管理 示例 磁盘维护 示例 示例代码 日志管理示例 磁盘维护示例 定期维护 定期维护对于保持Linux系统的稳定性和性能至关重要。这包括日志管理以及磁盘维护等方面。下面详细介绍这些方面的配置和优化方法。 日志管理 日志文件随着时间的积累可能会占用大量的磁…

Lumos学习王佩丰Excel第十二讲:Match与Index

一、函数语法 1、vlookup的局限 举个栗子&#xff0c;VLOOKUP不能做到从右推左&#xff1a; 由此看来&#xff0c;使用vlookup函数&#xff0c;表格范围要遵循从左到右的顺序&#xff0c;左为自变量&#xff0c;右为因变量&#xff1b;而要解决这种场景的弊端&#xff0c;可以…

【Qwen2微调实战】LLaMA-Factory框架对Qwen2-7B模型的微调实践

系列篇章&#x1f4a5; No.文章1【Qwen部署实战】探索Qwen-7B-Chat&#xff1a;阿里云大型语言模型的对话实践2【Qwen2部署实战】Qwen2初体验&#xff1a;用Transformers打造智能聊天机器人3【Qwen2部署实战】探索Qwen2-7B&#xff1a;通过FastApi框架实现API的部署与调用4【Q…

【数据分析】数据的离中趋势之一 - 极差、分位距、平均差

一、极差 未分组或单项分组的数据&#xff1a;极差最大值 - 最小值已分组数据&#xff1a;极差最大组的上限 - 最下组的下限实际应用中&#xff0c;极差可用于检查产品质量的稳定性和进行质量控制。正常生产条件下&#xff0c;极差在一定范围内波动&#xff0c;如出现不正常情…

nodemon学习(一)简介、安装、配置、使用

nodemon用来监视node.js应用程序中的任何更改并自动重启服务,非常适合用在开发环境中。以前&#xff0c;我们开发一个node后端服务时&#xff0c;每次更改文件&#xff0c;均需重启一下&#xff0c;服务才能生效。这使我们的开发效率降低了很多。nodemon的出现&#xff0c;可以…

招聘|头部云厂商招 PG 核心骨干 DBA【上海】

我们的招聘专区又回来了&#xff01;&#x1f3c3; Bytebase 作为先进的数据库 DevOps 团队协同工具 &#x1f527;&#xff0c;用户群里汇聚了 &#x1f497; 业界优秀的 DBA&#xff0c;SRE&#xff0c;运维的同学们 &#x1f31f;。 上周用户群里有小伙伴发招聘信息 &…