1.命令式和声明式
1.1:从范式上看,视图分为命令式和声明式。其中jQuery是典型的命令式框架。
命令式框架和声明式框架的区别:
命令式框架的一大特点就是关注过程;
声明式框架的特点关注结果,展示结果;
声明式的代码的性能并不优于命令式代码的性能;
推论:毕竟框架本身就封装了命令式代码才是实现了面向用户的声明式,这符合上面说的性能结论:声明式的代码的性能并不优于命令式代码的性能。
1.2:框架设计者在设计框架时要遵循的原则:在保持可维护性的同时让性能损失最小化
==声明式代码的更新性能消耗=找出差异的性能消耗+直接修改的性能消耗==
2.虚拟dom
2.1:什么是虚拟dom
如果我们能够最小化的找到差异的性能消耗 ,就可以让声明式代码的性能能无限接近命令式代码的性能。而所谓的虚拟dom就是为了最小化找出差异这一步性能消耗而出现的。(拓展:在vue.js3的设计思路一章中是这样描述虚拟dom的:==使用Js对象来描述UI的方式其实就是所谓的虚拟DOM==)
2.2innerHtml创建页面的性能
innerHtml创建页面的性能=HTML字符串拼接计算量+innerHtml的DOM计算量
2.3innerHTML和虚拟DOM的区别:
虚拟dom在页面更新的时候只会更新必要元素,innerHTML需要全量更新
影响虚拟dom的性能和innerHTML性能不一样
对于虚拟dom 来说,无论页面多大,都只会更新变化的内容,而对于innerHTML来说,页面越大,意味着更新消耗的性能越大。
compiler的程序的作用:把Html字符串编译成树型结构的数据对象。
3.总结
==原生js操作DOM的方法(如 document.creatElement),虚拟dom和innerHtml==三者操作页面的性能,不可以简单的下定论,这与==页面大小,变更部分的大小都有关系,除此之外与创建页面,更新页面也有关系==。并且经过一番权衡之后发现==虚拟dom==是个不错的选择。
二.框架设计的核心要素
1.框架中的Tree-Shaking
1.什么是Tree-Shaking?
Tree-Shaking指的是那些永远不会被执行的代码,也就排除了dead code(即:永远不会执行的代码)。并且无论是rollup.js还是webpack都支持Tree-Shaking.
2.实现Tree-Shaking的前提条件
想要实现Tree-Shaking必须满足一个条件,即:模块必须是ESM(即ES Moudle:是 JavaScript 官方的标准化模块系统,所有的主流浏览器都支持ESM),因为Tree-Shaking依赖ESM的静态结构。
拓展:
谷歌浏览器、360安全浏览器、微软edge浏览器、火狐浏览器、QQ浏览器 国内/世界五大浏览器名称
3.Tree-Shaking的工作流程
以Tree-Shaking在rollup.js的工作流程为例:
1)目录结构如下:

2)首先装rollup.js:
yarn add rollup -D
//或者 npm install rollup -D
3)下面是为input.js和utils.js编辑的内容
input.js:
//文件名:input.js
import {foo} from './utils.js'
foo()
utils.js:
//文件名:utils.js
export function foo(obj){
obj&&obj.foo
}
export function bar(obj){
obj&&obj.bar
}
虽然我们在utils.js中导入了foo函数和bar函数,然后通过import在input.js中导入了foo函数并执行,注意并没有导入bar函数,所以这个时候Tree-Shaking就会起作用,bar就会作为dead code被移除,在生成的bundle.js中不存在,具体如下:
4)执行下方命令进行构建:
npx rollup input.js -f esm -o bundle.js
这个命令的意思是以input.js为入口文件输出ESM,输出的文件名为build.js.
bulid.js里的代码:
//文件名:build.js
function foo(obj){
obj&&obj.foo
}
foo();
三.vue.js3的设计思路
1.什么是渲染器,它的作用是什么?
渲染器的作用:将虚拟DOM通过渲染器转化成真实DOM
例如:
return h('h1',{onClick:handler})//虚拟Dom
//相当于js对象
/*
return {
tag:'h1',//标签名称
props:{onClick:handler}//标签属性
}
*/
//相当于页面中的
/*
<h1 onClick='handler'></h1>
*/
==补充:==
$\textcolor{red}{在ts文件中常见到的container代表的是:一个真实的DOM元素,作为挂载点,该渲染器会把虚拟DOM渲染到该挂载点下面;vnode:虚拟Dom元素;例如:render(vnode,container)函数,变量名可变}$
虚拟dom的作用:
虚拟dom除了能够描述真实的dom之外还能描述组件(注意:组件并不是真实的DOM元素)。
组件的实质:
组件是一组DOdeneM元素的封装,这组dom元素就职组件要渲染den'e
编译器的作用:
编译器的作用:将模板编译为渲染函数并添加到 标签块的组件对象 上,把虚拟的DOM转化成真实的DOM。
渲染器(编译器)的工作原理:递归的遍历虚拟DOM元素,并调用原生的DOMAPI来完成真实的DOM创建。
渲染器可以通过Diff算法找出变更点,并且只会更新需要的更新的内容。
什么是subtree?
渲染器在渲染组件时,会先获取组件姚渲染的内容,即执行组件的渲染函数并得到其返回值,我们称之为subtree,最后再递归地调用渲染器将subtree渲染出来即可。