第一篇:框架设计概览
第1章:权衡的艺术
命令式:通过原生JS的DOM操作api的方式来编写渲染页面的方式,侧重于过程中的细节;
声明式:不关注过程中的细节,只关注结果,以标签形式来编写代码然后再编译渲染页面;
性能对比:
首次渲染页面时,命令式、声明式和innerHTML模板式相差不太多;
更新页面时,命令式>声明式>innerHTML模板式;
易维护性对比:
声明式>innerHTML模板式>命令式;
虚拟DOM:树形结构对象,通过Render渲染函数将树形结构对象递归地渲染成DOM元素;就是为了在更新页面时最小化性能找出差异而出现的(diff算法)。
由于没有操作真实的DOM树,只是原生JS层的操作,所以性能相对于真实的DOM操作要高好多个量级;
但是比原生js命令式DOM操作多了一个找出差异的步奏,所以不可能比原生js命令式DOM操作的性能更高。
纯运行时:通过Render渲染函数将树形结构对象递归地运行为命令式代码、渲染成DOM元素的过程;
缺点:没有编译过程,没法分析用户提供的内容。
编译时+运行时(运行时编译):先用Compiler编译函数将类HTML标签字符串编译成树形结构对象,然后通过Render渲染函数将树形结构对象递归地渲染成DOM元素的过程;
注意点:运行时才编译,这回产生一定的性能开销。因此我们在构建的时候就执行Compiler程序将用户提供的内容编译好,,等到运行时就不用编译了,这对性能非常友好。
优点:在编译时可以分析用户提供的内容,看看那些内容未来可能会变化,哪些内容永远不会变化,这样我们就可以在编译的时候提取这些信息,然后将其传递给Render函数,Render函数得到这些信息后,就可以进一步优化了。
纯编译时:用Compiler编译函数将类HTML标签字符串直接编译成命令式代码,渲染成DOM元素的过程。
优点:由于不需要运行时, 性能会更好。
缺点:灵活性差,即用户提供的内容必须编译后才能用。
第2章:框架设计的核心要素
提升用户的开发体验:
完善的信息提示机制;
控制框架代码体积:
通过环境常量(通过构建工具的插件来设置)来控制打包时,是否将提示信息的代码1打包在内,在生产环境代码包尽可能少的代码量,减少依赖包的体积;同时生产环境还能拥有较完善的提示信息机制。
框架要做到良好的Tree-Shaking:此机制需要ESM支持。
对于调用不到的功能模块代码1,在打包的时候自动跳过,不加入生产环境代码包里,减少代码包的体积。
对于被调用到、但不会产生实际功能、也不会产生副作用的代码1,Tree-Shaking是无法识别的;
/*#_PURE_*/ 注释符号:非副作用代码注释符号,可以执行Tree-Shaking,不将其打包进代码包;
框架应该输出怎样的构建产物:打包时,框架本身的代码输出类型,不是项目业务代码打包后的代码包。
以环境类型分类:
有用于开发环境的框架代码包:vue.global.js;
有用于生产环境的框架代码包:vue.global.prod.js;
以使用场景分类:{output:{format:"iife"}},通过此配置指定模块形式。
iife:可以通过<script>标签直接引入框架使用,vue.global.js也是这个形式。
esm:可以通过<script type="module">标签直接引入vue.esm-browser.js格式框架使用;vue.runtime.esm-bundler.js是专门给rollup.js或者webpack等打包工具使用的。
cjs:服务端渲染时使用的格式。
特性开关:
控制部分特定代码在特定环境中是否执行的控制开关。
用户使用webpack.DefinePlugin插件设置预定义常量的值来实现。
错误处理:
有一个完善错误处理机制;
良好的TypeScript类型支持:
TypeScript给变量添加更严谨的类型限制,是项目代码跟便于维护,使框架更加适应大型项目;
第3章:Vue.js的设计思路
声明式地描述UI:
用模板来声明式地描述UI,其实也就是用HTML元素标签描述UI,优点是可读性强,缺点是灵活性差;
用树结构层级JavaScript对象来声明式地描述UI,其实也就是虚拟DOM对象,优点是灵活性强,可读性较差;
Vue.js3同时支持这两种声明式地描述UI的方式。
初识渲染器:
渲染器就是将虚拟DOM对象通过递归调用渲染函数成原生DOM操作api,最终渲染出来。这是创建节点的大体思路,但是渲染器的精髓是更新节点阶段。
组件的本质:是一组DOM元素的封装,是一个具有树结构的虚拟DOM对象,将这个对象挂载到父级节点中。
可以通过函数的方式返回组件的虚拟DOM对象,也可以通过对象的方式返回组件的虚拟DOM对象。
模板的工作原理:
模板(标签)通过编译器将模板编译成虚拟DOM,然后再通过渲染器将虚拟DOM渲染成真实DOM。
Vue.js是各个模块组成的有机整体:各个模块之间是相互联系的。
编译器会分析识别变量,并做上标记,传递给虚拟DOM,渲染器会根据这些标记做进一步的优化。