大家也可以去我的博客看相关技术文章,欢迎大家,一同进步!!!!
vue3 源码分析,第一篇章权衡的艺术,基于vue设计与实现的第一章,命令式与声明式、性能与可维护、运行时和编译时相关内容
目录
声明式 vs 命令式
首先,vue
是一个关注视图层的框架,而视图层框架往往存在两种形态
- 声明式:比如
vue
- 命令式:比如
jquery
两种框架各有特点,基于特点也就有对应的优缺
命令式
我们来看下命令式框架的特点,以jquery为例
js
$("#app") // 获取div
.text("hello world") // 设置文本内容
.on("click", () => {
// 绑定点击事件
alert("clicked");
});
可以看到,命令式更加关注过程,需要你关注每一步的实现细节。 符合我们直觉的逻辑
声明式
而声明式的框架呢?
vue
<div @click="() => alert('ok')">hello world</div>
可以看到,同样的结果,我们是去描述这样一个想要的结果,而具体的实现细节被框架隐藏掉了
而vue作为声明式框架,方便我们开发,它内部也是命令式的实现,但是对外暴露式声明式的
性能 vs 可维护
那么,命令式和声明式的性能如何呢?
- 命令式的代码性能消耗: A
- 声明式的代码性能消耗: A + B
A为直接修改的性能开销,这个B是声明式,他们去找到差异所需要的性能开销
性能层面上,命令式更优
那为什么vue选择了声明式呢?答案是可维护性
- 首先大多数人没有办法达到理论上的命令式最近性能
- 可维护性也是重要的一环
补充:虚拟dom的出现,就是为了最小化找到差异的性能开销A,让其最小化而出现的,这也是vue他们在保证可维护性的前提下,最优性能的尝试
最后补充书中提到的三种更新视图方案的对比
方案 | 性能 | 可维护性 | 心智负担 |
---|---|---|---|
原生JavaScript计算 | 性能高 | 差 | 心智负担大 |
虚拟dom | 性能中等 | 可维护性高 | 心智负担小 |
innerHTML | 性能最差 | 可维护性中等 | 心智负担重等 |
虚拟 DOM,它是声明式的,因此心智负担小,可维护性 强,性能虽然比不上极致优化的原生 JavaScript,但是在保证心智负担 和可维护性的前提下相当不错。
运行时 vs 编译时
纯运行时
js
function render(obj, root) {
// ... 不用关心具体实现
}
存编译时
存编译时
js
// xxx html
<div>123</div>;
// 直接编译为命令时的代码
const div = document.createElement("div");
div.textContent = "123";
优劣
假如我们设计的框架是纯编译时的,那么它也可以分析用户提供的内容。由于不需要任何运行时, 而是直接编译成可执行的 JavaScript 代码,因此性能可能会更好,但是 这种做法有损灵活性,即用户提供的内容必须编译后才能用
- 存编译时的,必须编译后才能用,不够灵活
首先是纯运行时的框架。由于它没有编译的过程,因此我们没办法分析用户提供的内容,但是如果加入编译步骤,可能就大不一样 了,我们可以分析用户提供的内容,看看哪些内容未来可能会改变, 哪些内容永远不会改变,这样我们就可以在编译的时候提取这些信 息,然后将其传递给 Render 函数,Render 函数得到这些信息之 后,就可以做进一步的优化了
- 存运行时的,由于没有编译,无法去分析,优化困难
而vue3时编译+运行,后文会讲
- 把template转化为render函数,编译时
- 把render函数转化为vnode,渲染器渲染真实dom,运行时
总结
- 视图层框架往往有多种方式,vue选择的是声明式框架
- 声明式关乎结果的描述,内部隐藏命令式的实现,对外暴露声明式
- 声明式的框架性能弱于命令式,但是带来了更好的可维护性,和更小的心智负担
- 为了保证可维护性的前提下,虚拟dom的出现就是为了减小找到差异的那部分性能开销
- 存运行时,难以优化,而存编译时又不够灵活,vue3选择了编译+运行的方式