Vue.js设计与实现

第一章 权衡艺术

1.1 命令式和声明式

从范式上看,视图层框架分为命令式和声明式。
命令式:

一大特点是:关注过程

声明式:

一大特点是:关注结果

1.2 性能与可维护性

声明式代码的性能不优于命令式代码的性能

框架本身就是封装了命令式代码才实现了面向用户的声明式

声明式代码的可维护性强

1.3 虚拟DOM的性能

为了使声明式的性能更接近命令式的性能,这就是虚拟DOM的作用

通过innerHTML创建页面的性能:HTML字符串拼接的计算量+innerHTML的DOM计算量

虚拟DOM创建页面的性能:创建JavaScript对象的计算量+创建真实DOM的计算量

innerHTML更新页面的时候:要重新构建HTML字符串,再重新设置DOM元素的innerHTML属性。其实就是要销毁所有旧的DOM元素,再全量的创建新的DOM元素。

虚拟DOM更新页面的时候:比较新旧虚拟DOM,找到变化的元素更新它

性能:原生JavaScript > 虚拟DOM > innerHTML(模板)

1.4 运行时和编译时

纯运行时:

编写一个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 <div>
03   <span>hello world</span>
04 </div>
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

Tree-Shaking 指的是消除哪些永远不会被执行的代码,排除dead code

实现Tree-Shaking必须满足模板是ESM(ES Module)依赖ESM的静态结构

Tree-Shaking工作原理:
目录结构
01 ├── demo
02 │   └── package.json
03 │   └── input.js
04 │   └── utils.js

首先安装rollup.js

01 yarn add rollup -D
02 # 或者 npm install rollup -D

input.jsutil.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();
Tree-Shaking中的第二个关键点------副作用

如果一个函数产生了副作用,那么就不会被消除

副作用:当调用函数的时候会对外界产生影响

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值