Vue.js 设计与实现 - 权衡的艺术

文章基于对 Vue.js 核心团队成员的新书学习,外加个人理解,并未完全照搬书中代码和文字。推荐购买正版《Vue.js 设计与实现》进行深度学习。
命令式和声明式 命令式编程关注过程,典型的命令式编程库 jQuery:
// 获取 id 为 app 的 div 标签 $('#app') // 设置文本类容为 hello world .text('hello world') // 点击时,内容修改为 hello jquery .on('click', function () { this.innerText = 'hello jquery' })

命令式编程更符合普通思维方式,直接操作 DOM,性能也更好。
声明式编程关注结果,如 Vue:

声明式编程符合 UI = f(x) 的函数思想,数据驱动视图,UI 修改过程交给框架,开发者只需要关注变量,减少维护时的心智负担。
总结:声明式编程的可维护性更好,但性能低于命令式,Vue 要做的就是保持可维护性的同时尽量减少性能损失。
虚拟 DOM 的性能 Vue 在初次渲染视图时,会生成一个 VNode,更新时又会生一个新的 VNode,将新旧两个 VNode 进行对比,找到最小修改差异,让进行修改,所以:
声明式代码的更新性能消耗 = 找出差异的性能消耗 + 修改 DOM 的性能消耗
理论上,直接原生 JavaScript 操作 DOM 性能更好,但这对开发者能力有较高的要求。在使用 jQuery 的时期,往往存在很多 innerHTML 暴力操作。
初次渲染时的性能对比
虚拟 DOM 耗时 = 创建 JavaScript 对象(VNode) + 全量 DOM 渲染
innerHTML 耗时 = 拼接 JavaScript 字符串 + 全量 DOM 渲染
更新时的性能对比
虚拟 DOM 耗时 = 创建新 JavaScript 对象(VNode) + Diff + 部分 DOM 渲染
innerHTML 耗时 = 拼接 JavaScript 字符串 + 全量 DOM 渲染
小结
操作虚拟 DOM 和操作原生 DOM 谁的性能更好,不能简单下结论。因为这跟如何操作 DOM,何时操作 DOM,修改量多少都有关。
虚拟 DOM 是保证运行性能、代码可维护性、降低心智负担的综合选择。
运行时与编译时 纯运行时
手写 DOM 对象,运行时直接遍历对象进行渲染,但书写麻烦。
var vnode = { tag: 'div', children: [ { tag: 'span', children: 'hello ' }, { tag: 'span', children: 'vue' } ] } function render(vnode, parent) { const el = document.createElement(vnode.tag) const children = vnode.children if (typeof children === 'string') { el.innerHTML = vnode.children } if (Array.isArray(children) && children.length !== 0) { children.forEach(child => { render(child, el) }) } parent.appendChild(el) } render(vnode, document.body)

编译时 + 运行时
开发时写普通 HTML 模板:
hello vue

构建时通过 compiler 进行编译:
const htmlString = '...' const content = compile(htmlString)

运行时渲染:
render(content, document.body)

纯编译时
我们可以将模板编译成渲染函数或者 VNode,那同样也可以直接编译成原生 DOM 操作:
const htmlString = '...' const content = compile(htmlString)// 编译生成 const div = document.createElement('div') const hello = document.createElement('span') hello.innerHTML = 'hello ' div.appendChild(hello) // ...

小结
纯运行时以及编译时 + 运行时的方式都可以通过不同的渲染器实现跨平台渲染,灵活性高。
但是纯运行时书写麻烦,如果想做静态优化需要手动标记,而编译时 + 运行时可以交给 compiler 去做。
纯编译时 理论上能获得最好的性能,但灵活性相对较弱。
综上 【Vue.js 设计与实现 - 权衡的艺术】Vue 是一个编译时 + 运行时声明式 UI 框架,利用虚拟 DOM 进行更新渲染。保证其拥有良好的可维护性和灵活性,同时加上静态优化,尽可能接近原生的性能。

    推荐阅读