框架设计概览
权衡
命令式和声明式
命令式可以实现最高的代码运行效率,例如jq和原生js均为命令式编程
声明式可以实现相对友好的开发效率和运行效率,例如vue、react采用声明式
性能与可维护性的权衡
- 声明式可以较好的平衡代码性能和可维护性,因为其按照原生html的方式编写代码,只需要声明需要做的事情,实现过程由框架代劳;在编程方便的基础上兼顾了较好的性能
虚拟DOM的性能
比命令式低,但是相对来说也很高。它通过把声明式的模版代码转化为渲染函数的方式实现,每一个渲染函数即为一个组件。它的基本开销为
js计算开销(比如比对变化的位置)+命令式开销+dom渲染开销,由于js计算开销比dom渲染开销通常快一个数量级,因此虚拟dom拥有较好性能。并且虚拟dom可以实现多端渲染,可以高效率开发多端应用命令式性能开销为
命令式开销+dom渲染开销,比虚拟dom要快,但是不好维护综上虚拟dom实现方案优势明显
运行时和编译时
可以认为react是运行时框架,其
JSX只是Babel做语义转换,不会分析模版语义,本质上JSX就是jsvue可以认为是编译时+运行时框架,它有编译器,可以把模版编译为渲染函数,同时会做编译优化,比如静态提升,patchFlag等优化,运行时可以通过编译优化做快速diff。生产环境的打包产物中一般不包含编译器,除非浏览器需要解析模版文件
静态提升:把静态的渲染内容提升到渲染函数外面,每次渲染函数重新执行的时候,直接复用,避免比较,提升性能
patchFlag:针对绑定动态属性的节点,标记其中的动态属性,使得其中可能存在的静态属性不用比对
总结
使用虚拟DOM实现的编译时+运行时框架,可以视为最优解。它既容易维护,也兼顾了性能,还能在编译时做各种优化,整体来说是一个好选择。
框架设计的核心要素
- 对开发者友好
- 产出对应产物
- 框架代码体积要控制
- 要有特性开关,防止某些用户只需要部分功能
- 渐进式升级
- tree-shaking
- 错误处理,良好的框架内报错和用户自定义错误处理
- ts支持
vue3的设计思路
声明式描述UI
- 使用模版语法描述UI,属性和事件绑定编码风格和原生html统一,最大限度降低学习成本和提升可维护性。使用响应式数据使得用户不用关心实现细节
编译器
- 模版转换为渲染函数(虚拟DOM),通过渲染函数实现组件化和高性能响应式更新
- 在编译过程中,做静态提升、patchFlag等优化,进一步提升响应式diff速度
渲染器
- 递归的把虚拟DOM渲染为普通DOM
- 通过diff算法找出变更点,精准更新