第一章 权衡的艺术

文章探讨了声明式和命令式编程在视图层框架中的应用,指出Vue.js如何通过声明式接口封装命令式实现。讨论了性能与可维护性的权衡,强调虽然命令式代码性能可能优于声明式,但声明式更利于维护。虚拟DOM被引入以提高性能,尤其是在页面更新时。最后,文章提到了运行时和编译时的概念,展示纯运行时与运行时+编译时的差异,并以Vue.js为例说明其优化策略。
摘要由CSDN通过智能技术生成

1.1 声明式和命令式

(1)视图层框架通常分为命令式和声明式。

  • 命令式:关注过程(例如jQuery)
const div = document.querySelector('#app') //获取id为app的div标签
div.innerText = 'hello world' // 设置文本
div.addEventListener('click',() => { alert('ok') })//绑定点击事件
  • 声明式:关注结果
<div @click="() => alert('ok')">
    hello world
</div>

(2)Vue.js帮我们封装了过程,内部是命令式的,暴露给用户的是声明式。

1.2 性能与可维护性的权衡

(1)结论:命令式代码性能优于声明式代码。

(2)例如上述代码,命令式代码若要修改text内容,直接修改即可,而声明式它需要找出前后差异并更新,那么有:

  • 命令式代码的更新性能消耗=A,声明式代码的更新性能消耗=A+B (A是直接修改的性能消耗,B是找出差异的性能消耗)

(3)声明式代码的可维护性更强。

1.3 虚拟DOM的性能

(1)虚拟DOM是为了性能消耗最小化找出差异,对比JS操作和DOM运算,JS要快的多。

const html = <div><span>...</span></div> //构造HTML字符串
div.innerHTML = html  //赋值给dom元素的innerHTML属性

(2)性能分析

对于创建页面:

  • innerHTML它的性能:HTML字符串拼接的计算量 + innerHTML的DOM计算量。

  • 而虚拟DOM创建页面是先创建JS对象(理解为真实DOM的描述),再递归遍历虚拟DOM树并创建真实的DOM,它的性能:创建JS对象的计算量 + 创建真实的DOM的计算量。

对于更新页面:

  • innerHTML,它是重构HTML字符串再重新设置DOM元素的innerHTML属性 <=> 销毁旧的DOM元素,再创建新的DOM元素。

  • 对于虚拟DOM更新页面,它是重建JS对象,再比较新旧虚拟DOM找出不同并更新它。

二者在宏观的角度上,若是在同个数量级上,创建页面时,性能二者差异不大,但在更新页面时,虚拟DOM在JS层面的运算只是多个diff运算,不过产生数量级的差异,而DOM层面运算,虚拟DOM只会更新必要的元素,但innerHTML需要全部更新,若页面很大,此时的虚拟DOM的优势体现出来了。

1.4 运行时和编译时

(1)纯运行时:设计Render函数,用户为该函数提供一个树形的数据对象,然后Render函数将该对象递归渲染成DOM元素。

const obj = {    // 规定的树形结构的数据对象
    tag: 'div',   // 代表标签名称
    children: [   // 代表子节点
        {tag: 'span', children: 'hello world' }
    ]
}
function Render(obj, root) {
    const el = document.creatElement(obj.tag)
    if(typeof obj.children === 'string') {
        const text = document.creatTextNode(obj.children)
        el.appendChild(text)
    } else if (obj.children) {
        //数组,递归调用Render,使用el作为root参数
        obj.children.forEach((child) => Render(child, el))
    }
    root.appendChild(el) // 将元素添加到root
}
Render(obj,document.body) //渲染到body中

(2)运行时+编译时:用户提供HTML字符串,Comlier函数将其编译成数据对象在给Render函数运行时处理。

<div>
    <span> hello world </span>
</div>
const html = 
<div>
    <span> hello world </span>
</div>

const obj = Complier(html) // 调用Complier编译得到树形结构的数据对象
Render(obj,document.body)  // 调用Render进行渲染

(3)编译时:将HTML字符串编译成命令式代码。

const div = document.creatElement('div')
const span = document.creatElement('span')
span.innerText = 'hello world'
div.appendChild(span)
document.body.appendChild(div)
  • Vue.js 3 保持了运行时+编译时的架构,在保持灵活性的基础上能够尽可能的去优化。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值