框架设计概览

权衡

命令式和声明式

  • 命令式可以实现最高的代码运行效率,例如jq和原生js均为命令式编程

  • 声明式可以实现相对友好的开发效率和运行效率,例如vue、react采用声明式

性能与可维护性的权衡

  • 声明式可以较好的平衡代码性能和可维护性,因为其按照原生html的方式编写代码,只需要声明需要做的事情,实现过程由框架代劳;在编程方便的基础上兼顾了较好的性能

虚拟DOM的性能

  • 比命令式低,但是相对来说也很高。它通过把声明式的模版代码转化为渲染函数的方式实现,每一个渲染函数即为一个组件。它的基本开销为js计算开销(比如比对变化的位置)+命令式开销+dom渲染开销,由于js计算开销比dom渲染开销通常快一个数量级,因此虚拟dom拥有较好性能。并且虚拟dom可以实现多端渲染,可以高效率开发多端应用

  • 命令式性能开销为命令式开销+dom渲染开销,比虚拟dom要快,但是不好维护

  • 综上虚拟dom实现方案优势明显

运行时和编译时

  • 可以认为react是运行时框架,其JSX只是Babel做语义转换,不会分析模版语义,本质上JSX就是js

  • vue可以认为是编译时+运行时框架,它有编译器,可以把模版编译为渲染函数,同时会做编译优化,比如静态提升,patchFlag等优化,运行时可以通过编译优化做快速diff。生产环境的打包产物中一般不包含编译器,除非浏览器需要解析模版文件

    • 静态提升:把静态的渲染内容提升到渲染函数外面,每次渲染函数重新执行的时候,直接复用,避免比较,提升性能

    • patchFlag:针对绑定动态属性的节点,标记其中的动态属性,使得其中可能存在的静态属性不用比对

总结

使用虚拟DOM实现的编译时+运行时框架,可以视为最优解。它既容易维护,也兼顾了性能,还能在编译时做各种优化,整体来说是一个好选择。

框架设计的核心要素

  • 对开发者友好
  • 产出对应产物
  • 框架代码体积要控制
  • 要有特性开关,防止某些用户只需要部分功能
  • 渐进式升级
  • tree-shaking
  • 错误处理,良好的框架内报错和用户自定义错误处理
  • ts支持

vue3的设计思路

声明式描述UI

  • 使用模版语法描述UI,属性和事件绑定编码风格和原生html统一,最大限度降低学习成本和提升可维护性。使用响应式数据使得用户不用关心实现细节

编译器

  • 模版转换为渲染函数(虚拟DOM),通过渲染函数实现组件化和高性能响应式更新
  • 在编译过程中,做静态提升、patchFlag等优化,进一步提升响应式diff速度

渲染器

  • 递归的把虚拟DOM渲染为普通DOM
  • 通过diff算法找出变更点,精准更新