命令式和声明式
-
命令式框架:
- 关注过程
- 代码描述"做事的过程"
- 例如 jQuery:
$('#app') .text('hello world') .on('click', () => { alert('ok') })
-
声明式框架:
- 关注结果
- 提供"结果"描述,框架负责实现
- 例如 Vue.js:
<div @click="() => alert('ok')">hello world</div>
-
Vue.js 内部实现是命令式的,但暴露给用户的接口是声明式的
性能与可维护性的权衡
- 声明式代码的性能不优于命令式代码的性能
- 命令式代码可以做到极致的性能优化
- 声明式代码需要额外的性能消耗来找出差异
- 性能消耗对比:
- 命令式代码的更新性能消耗 = A
- 声明式代码的更新性能消耗 = B + A
(A为直接修改的性能消耗,B为找出差异的性能消耗)
- 声明式代码的可维护性更强
- 框架设计需要在可维护性和性能之间权衡
虚拟 DOM 的性能
-
虚拟 DOM 的目的是最小化找出差异的性能消耗
-
虚拟 DOM 理论上不可能比原生 JavaScript 操作 DOM 更高效
-
虚拟 DOM 的优势:
- 不需要手写极致优化的命令式代码
- 保证应用程序的性能下限
- 在声明式编码的同时尽量接近命令式代码的性能
-
innerHTML vs 虚拟 DOM:
- 创建页面:性能差异不大
- 更新页面:
- innerHTML 需要全量更新
- 虚拟 DOM 只更新必要的元素
- 页面越大,innerHTML 的性能消耗越大
- 虚拟 DOM 的性能消耗与页面大小关系不大
-
性能对比总结(innerHTML、虚拟 DOM、原生 JavaScript):
- 心智负担:原生 JavaScript > innerHTML > 虚拟 DOM
- 可维护性:虚拟 DOM > innerHTML > 原生 JavaScript
- 性能:原生 JavaScript > 虚拟 DOM > innerHTML(大量更新时)
运行时和编译时
-
框架设计的三种选择:
- 纯运行时
- 运行时 + 编译时
- 纯编译时
-
纯运行时框架:
- 直接执行,不需要编译
- 无法分析用户提供的内容
-
运行时 + 编译时框架:
- 既支持运行时,又支持编译时
- 可以分析用户内容并优化
- Vue.js 3 采用此方式,保持灵活性的同时进行优化
-
纯编译时框架:
- 直接编译成可执行的 JavaScript 代码
- 理论上性能最好,但缺乏灵活性
- 如 Svelte 框架
-
选择考虑因素:
- 性能
- 灵活性
- 可优化空间
Vue.js 3 采用运行时 + 编译时的架构,在保持灵活性的基础上通过编译手段分析用户内容,从而进一步提升性能。