尤雨溪说这本书是从高层的设计角度来探讨框架需要关注的问题,从而帮助读者更好地理解一些具体的实现为何要做出这样的选择。
第一篇 框架设计概览
第一章 权衡的艺术
从范式上来看,视图层框架通常分为命令式和声明式。
命令式框架的一大特点就是关注过程,jQuery就是典型的命令式框架。
声明式框架更加关注结果,结合Vue来说,
Vue.js已经帮我们封装好了过程。
换句话说,
Vue.js的内部实现一定是命令式的,而暴露给用户的却更加声明式。
那么,命令式和声明式的优缺点体现在哪儿呢?
在框架设计方面,体现在性能与可维护性之间的权衡。对于框架来说,为了实现最优的更新性能,它需 要找到前后的差异并只更新变化的地方。
所以,**声明式代码的更新性能消耗 = 找出差异的性能消耗 + 直接修改的性能消耗(命令式代码的性能消耗)。**
从这个公式,可以得到一个结论,只要声明式框架最大限度地减少找出差异的性能消耗,就能使得性能无限接近与声明式代码的性能。由此,所谓的虚拟DOM应运而生,它就是为了最小化找出差异这一步的性能消耗而出现的。
虚拟DOM创建页面的过程分为两步:
第一步是创建JavaScript对象,这个对象可以理解为真实DOM的描述。
第二步是递归地遍历虚拟DOM树并创建真实DOM。
那么,**虚拟DOM创建页面的性能 = 创建JavaScript对象的计算量 + 创建真实DOM的计算量。**
而虚拟DOM更新页面的性能呢?
虚拟DOM更新页面,需要重新创建JavaScript对象(虚拟DOM树),然后比较新旧虚拟DOM,找到变化的元素并更新它。
所以,当更新页面时,虚拟DOM只需要更新变化的元素,而原生DOM则需要全量更新。
并且原生DOM操作需要手动创建、删除、修改大量的DOM元素,心智负担最大,可维护性也极差,但是性能最高。
当设计一个框架时,我们有三种选择:纯运行时的、运行时+编译时的、纯编译时的。
纯运行时的框架:它提供一个Render函数,用户为该函数提供一个树型结构的数据对象,然后Render函数会根据该对象递归地将数据渲染成DOM元素。
运行时+编译时的框架:它提供一个Comoiler函数,作用是把HTML字符串编译成树型结构的数据对象,以便交给Render函数渲染。
纯编译时框架:只需要一个Compiler函数把HTML字符串直接编译成命令式代码。
Vue.js3就是一个运行时+编译时的框架,通过虚拟DOM等手段,进一步提升更新性能。