码农编程阁-全国最大的中文编程交流平台

 找回密码
 立即注册
查看: 206|回复: 1

[其他] 为什么jQuery会被淘汰?Vue一定比jQuery好吗?

[复制链接]
  • TA的每日心情
    擦汗
    2025-3-10 11:56
  • 签到天数: 95 天

    连续签到: 1 天

    [LV.6]常住居民II

    170

    主题

    902

    帖子

    2万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    26745
    发表于 2025-1-15 22:41:15 | 显示全部楼层 |阅读模式
    前言

    曾经面试时碰到过一个问题:为什么现有的Vue框架开发可以淘汰之前的JQuery?

    我回答:Vue框架无需自己操作DOM,可以避免自己频繁的操作DOM。

    面试官接着反问我:Vue框架无需自己操作DOM,有什么优势吗,不用操作DOM就一定是好的吗?

    我懵了,在我的认知里Vue框架无需自己操作DOM性能是一定优于自己来操作DOM元素的,其实并不是的.....

    声明式框架与命令式框架

    首先我们得了解声明式框架和命令式框架的区别。

    命令式框架关注过程

    JQuery就是典型的命令式框架。

    例如我们来看如下一段代码:

    $( "button.continue" ).html( "Next Step..." ).on('click', () => { alert('next') })

    这段代码的含义就是先获取一个类名为continue的button元素,它的内容为 Next Step...,并为它绑定一个点击事件。可以看到自然语言描述与代码是一一对应的,这更符合我们做事的逻辑。

    声明式框架更关注结果

    现有的Vue,React都是典型的声明式框架。

    接着来看一段Vue的代码:

    <button class="continue" @click="() => alert('next')">Next Step...</button>

    这是一段类HTML模板,它更像是直接提供一个结果。至于怎么实现这个结果,就交给Vue内部来实现,开发者不用关心。

    性能比较

    首先告诉大家结论:声明式代码性能不优于命令式代码性能。

    即:声明式代码性能 <= 命令式代码性能

    为什么会这样呢?

    还是拿上面的代码举例

    假设我们要将button的内容改为 pre Step,那么命令式的实现就是:

    button.textContent = "pre Step"

    很简单,就是直接修改

    声明式的实现就是:

    <!--之前 -->
    <button class="continue" @click="() => alert('next')">Next Step...</button>
    <!--现在 -->
    <button class="continue" @click="() => alert('next')">pre Step</button>

    对于声明式框架来说,它需要找到更改前后的差异并只更新变化的地方。但是最终更新的代码仍然是:

    button.textContent = "pre Step"

    假设直接修改的性能消耗为 A, 找出差异的性能消耗为 B, 那么就有:

    • 命令式代码的更新性能消耗 = A
    • 声明式代码的更新性能消耗 = A + B

    可以看到声明式代码永远要比命令式代码要多出找差异的性能消耗。

    那既然声明式代码的性能无法超越命令式代码的性能,为什么我们还要选择声明式代码呢?这就要考虑到代码可维护性的问题了。当项目庞大之后,手动完成dom的创建,更新与删除明显需要更多的时间和精力。而声明式代码框架虽然牺牲了一点性能,但是大大提高了项目的可维护性,降低了开发人员的心智负担

    那么,有没有办法能同时兼顾性能和可维护性呢?

    有!那就是使用虚拟dom

    虚拟DOM

    首先声明一个点,命令式代码只是理论上会比声明式代码性能高。因为在实际开发过程中,尤其是项目庞大之后,开发人员很难写出绝对优化的命令式代码。而Vue框架内部使用虚拟Dom + 内部封装Dom元素操作的方式,能让我们不用付出太多精力的同时,还能保证程序的性能下限,甚至逼近命令式代码的性能。

    在讨论虚拟Dom的性能之前,我们首先要说明一个点:JavaScript层面的计算所需时间要远低于Dom层面的计算所需时间  看过浏览器渲染与解析机制的同学应该很明白为什么会这样。

    我们在使用原生JavaScript编写页面时,很喜欢使用innerHTML,这个方法非常特殊,下面我们来比较一下使用虚拟Dom和使用innerHTML的性能差异。

    创建页面时

    我们在使用innerHTML创建页面时,通常是这样的:

    const data = "hello"
    const htmlString = `<div>${data}</div>`
    domcument.querySelect('.target').innerHTML = htmlString

    这个过程需要先通过JavaScript层的字符串运算,然后是Dom层的innerHTML的Dom运算 (将字符串赋值给Dom元素的innerHTML属性时会将字符串解析为Dom树)

    而使用虚拟Dom的方式通常是编译用户编写的类html模板得到虚拟Dom(JavaScript对象),然后遍历虚拟Dom树创建真实Dom对象

    两者比较:

    innerHTML
    虚拟Dom

    JavaScript层面运算计算拼接HTML字符串创建JavaScript对象(虚拟Dom)
    Dom层面运算新建所有Dom元素新建所有Dom元素

    可以看到两者在创建页面阶段的性能差异不大。尽管在JavaScript层面,创建虚拟Dom对象貌似更耗时间,但是总体来说,Dom层面的运算是一致的,两者属于同一数量级,宏观来看可认为没有差异。

    更新页面时

    使用innerHTML更新页面,通常是这样:

    //更新
    const newData = "hello world"
    const newHtmlString = `<div>${newData}</div>`
    domcument.querySelect('.target').innerHTML = newHtmlString

    这个过程同样是先通过JavaScript层的字符串运算,然后是Dom层的innerHTML的Dom运算。但是它在Dom层的运算是销毁所有旧的DOM元素,再全量创建新的DOM元素。

    而使用虚拟Dom的方式通常是重新创建新的虚拟Dom(JavaScript对象),然后比较新旧虚拟Dom,找到需要更改的地方并更新Dom元素。

    两者比较:

    innerHTML
    虚拟Dom

    JavaScript层面运算计算拼接HTML字符串创建JavaScript对象(虚拟Dom)+ Diff算法
    Dom层面运算销毁所有旧的Dom元素,新建所有新的DOM元素必要的DOM更新

    可以看到虚拟DOM在JavaScript层面虽然多出一个Diff算法的性能消耗,但这毕竟是JavaScript层面的运算,不会产生数量级的差异。而在DOM层,虚拟DOM可以只更新差异部分,对比innerHTML的全量卸载与全量更新性能消耗要小得多。所以模板越大,元素越多,虚拟DOM在更新页面的性能上就越有优势。

    总结

    现在我们可以回答这位面试官的问题了:JQuery属于命令式框架,Vue属于声明式框架。在理论上,声明式代码性能是不优于命令式代码性能的,甚至差于命令式代码的性能。但是声明式框架无需用户手动操作DOM,用户只需关注数据的变化。声明式框架在牺牲了一点性能的情况下,大大降低了开发难度,提高了项目的可维护性,且声明式框架通常使用虚拟DOM的方式,使其在更新页面时的性能大大提升。综合来说,声明式框架仍旧是更好的选择。


  • TA的每日心情
    擦汗
    2025-3-10 11:56
  • 签到天数: 95 天

    连续签到: 1 天

    [LV.6]常住居民II

    170

    主题

    902

    帖子

    2万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    26745
     楼主| 发表于 2025-1-15 22:41:37 | 显示全部楼层
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|码农编程阁-全国最大的中文编程交流平台

    GMT+8, 2025-4-29 21:12 , Processed in 0.176971 second(s), 23 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.

    快速回复 返回顶部 返回列表