一大特点是:关注过程
一大特点是:关注结果
声明式代码的性能不优于命令式代码的性能
框架本身就是封装了命令式代码才实现了面向用户的声明式
声明式代码的可维护性强
为了使声明式的性能更接近命令式的性能,这就是虚拟DOM的作用
通过innerHTML创建页面的性能:HTML字符串拼接的计算量+innerHTML的DOM计算量
虚拟DOM创建页面的性能:创建JavaScript对象的计算量+创建真实DOM的计算量
innerHTML更新页面的时候:要重新构建HTML字符串,再重新设置DOM元素的innerHTML属性。其实就是要销毁所有旧的DOM元素,再全量的创建新的DOM元素。
虚拟DOM更新页面的时候:比较新旧虚拟DOM,找到变化的元素更新它
性能:原生JavaScript > 虚拟DOM > innerHTML(模板)
编写一个Render函数
提供一个树型结构的数据对象:
01 const obj = {
02 tag: 'div',
03 children: [
04 { tag: 'span', children: 'hello world' }
05 ]
06 }
Render函数:
01 function Render(obj, root) {
02 const el = document.createElement(obj.tag)
03 if (typeof obj.children === 'string') {
04 const text = document.createTextNode(obj.children)
05 el.appendChild(text)
06 } else if (obj.children) {
07 // 数组,递归调用 Render,使用 el 作为 root 参数
08 obj.children.forEach((child) => Render(child, el))
09 }
10
11 // 将元素添加到 root
12 root.appendChild(el)
13 }
使用:
01 const obj = {
02 tag: 'div',
03 children: [
04 { tag: 'span', children: 'hello world' }
05 ]
06 }
07 // 渲染到 body 下
08 Render(obj, document.body)
编写Compiler的程序,作用是把HTML字符串编译成树型结构的数据对象
使用:
01 const html = `
02
03 hello world
04
05 `
06 // 调用 Compiler 编译得到树型结构的数据对象
07 const obj = Compiler(html)
08 // 再调用 Render 进行渲染
09 Render(obj, document.body)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wBZ0pbQQ-1686448242740)(C:\Users\virtue\AppData\Roaming\Typora\typora-user-images\image-20230213173530302.png)]
这个时候只需要Compiler函数就可以了,只通过编译器编译就可以了。
Tree-Shaking 指的是消除哪些永远不会被执行的代码,排除dead code
实现Tree-Shaking必须满足模板是ESM(ES Module)依赖ESM的静态结构
01 ├── demo
02 │ └── package.json
03 │ └── input.js
04 │ └── utils.js
首先安装rollup.js
01 yarn add rollup -D
02 # 或者 npm install rollup -D
input.js和util.js文件的内容
01 // input.js
02 import { foo } from './utils.js'
03 foo()
04 // utils.js
05 export function foo(obj) {
06 obj && obj.foo
07 }
08 export function bar(obj) {
09 obj && obj.bar
10 }
以input.js文件为入口,输出ESM,输出文件的名字叫作bundle.js
01 npx rollup input.js -f esm -o bundle.js
bundle.js的内容
01 // bundle.js
02 function foo(obj) {
03 obj && obj.foo
04 }
05 foo();
如果一个函数产生了副作用,那么就不会被消除。
副作用:当调用函数的时候会对外界产生影响
01 //input.js
02 import {foo} from './utils'
03
04 /*#__PURE__*/ foo()
注释代码 /#PURE/,其作用就是告诉 rollup.js,对于foo函数的调用不会产生副作用
IIFE格式的资源:iife 立刻调用的函数表达式
ESM格式的资源:esm
vue.esm-browser.js中的-browser字样的ESM资源是直接给
cjs格式的资源:cjs 全称:CommonJS