JQuery属于命令式框架,Vue属于声明式框架

曾经面试时碰到过一个问题:为什么现有的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…
这是一段类HTML模板,它更像是直接提供一个结果。至于怎么实现这个结果,就交给Vue内部来实现,开发者不用关心

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

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

为什么会这样呢?

还是拿上面的代码举例

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

button.textContent = “pre Step”
很简单,就是直接修改

声明式的实现就是:

<button class=“continue” @click=“() => alert(‘next’)”>Next Step…

<button class=“continue” @click=“() => alert(‘next’)”>pre Step
对于声明式框架来说,它需要找到更改前后的差异并只更新变化的地方。但是最终更新的代码仍然是

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的方式,使其在更新页面时的性能大大提升。综合来说,声明式框架仍旧是更好的选择

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/17105.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【大模型实战篇】vLLM的由来以及大模型部署、推理加速实践

1. 问题背景分析及vLLM的由来 大模型毫无疑问&#xff0c;在工作、生活中已经逐渐扮演越来越重要的角色。但大模型的尺寸一般都比较大&#xff0c;处理一个大模型请求的成本可能比传统关键字查询高出 10 倍。推理的成本代价较高&#xff0c;因此提高大模型服务系统的吞吐量&…

[JAVAEE] 网络编程

目录 一. 什么是socket套接字 二. socket套接字 2.1 socket套接字根据传输层协议分类 2.2 TCP流套接字 UDP数据报套接字主要特点 三. UDP数据报套接字编程 3.1 DatagramSocket 是UDP socket, 用于发送和接受数据报 3.2 DatagramPacket 是UDP socket 发送和接收的数据报 …

SDF,一个从1978年运行至今的公共Unix Shell

关于SDF 最近发现了一个很古老的公共Unix Shell服务器&#xff0c;这个项目从1978年运行至今&#xff0c;如果对操作系统&#xff0c;对Unix感兴趣&#xff0c;可以进去玩一玩体验一下 SDF Public Access UNIX System - Free Shell Account and Shell Access 注册方式 我一…

物联网低功耗广域网LoRa开发(二):LoRa开发环境搭建及驱动移植

一、STM32CubeMX加载固件库 将F0固件库添加进来 二、IAR介绍、安装及快捷操作 &#xff08;一&#xff09;IAR介绍 1、简介 C/C编译器和调试器 集成开发环境(IDE) 实时操作系统和中间件 开发套件 硬件仿真器以及状态机建模工具2、IAR与Keil对比 MDK默认只创建工程&#xf…

RK3568平台开发系列讲解(设备树篇)device_node 转换成 platform_device

🚀返回专栏总目录 文章目录 一、DTB转换规则二、转换源码分析沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇将介绍通过设备树 device_node 转换成 platform_device 一、DTB转换规则 device 部分是用 platform_device 结构体来描述硬件资源的, 所以内核最终会…

深入理解 source 和 sh、bash 的区别

1 引言 在日常使用 Linux 的过程中&#xff0c;脚本的执行是不可避免的需求之一&#xff0c;而 source、sh、bash 等命令则是执行脚本的常用方式。尽管这些命令都能运行脚本&#xff0c;但它们之间的执行方式和效果却有着显著的区别。这些区别可能会影响到脚本的环境变量、工作…

基于Java Springboot鲜花商城系统

一、作品包含 源码数据库设计文档PPT全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA 数据库&#xff1a;MySQL8.0 …

413: Quick Sort

解法&#xff1a; #include <bits/stdc.h> using namespace std; const int N1e55; int a[N]; int n;int main(int argc, char** argv) {cin>>n;for (int i0;i<n;i) cin>>a[i];sort(a,an);for (int i0;i<n;i) cout<<a[i]<<" "…

通过轻易云高效实现ERP数据无缝传输

高效集成领星ERP数据至金蝶云星空 领星ERP数据集成到金蝶云星空&#xff1a;发货结算报告对接销售出库单&#xff08;日本站&#xff09; 在企业的日常运营中&#xff0c;数据的高效流动和准确处理至关重要。本文将分享一个实际运行的系统对接集成案例&#xff1a;如何将领星E…

在 WSL2 Ubuntu22.04环境安装 MySQL

一、安装步骤 1.1. 确保/etc/apt/sources.list源配置文件一切正常 sudo nano /etc/apt/sources.list需要包括以下内容 deb http://archive.ubuntu.com/ubuntu/ focal main restricted universe multiverse deb-src http://archive.ubuntu.com/ubuntu/ focal main restricted…

通信塔台、网点、线路数据

通信塔台&#xff1a; 数量&#xff1a; 通信电缆&#xff1a; 通信网点&#xff1a;

C#桌面应用制作计算器

C#桌面应用制作简易计算器&#xff0c;可实现数字之间的加减乘除、AC按键清屏、Del按键清除末尾数字、/-按键取数字相反数、%按键使数字缩小100倍、按键显示运算结果等...... 页面实现效果 功能实现 布局 计算器主体使用Panel容器&#xff0c;然后将button控件排列放置Pane…

【C++进阶】C++11 -- 智能指针

【C进阶】C11 -- 智能指针 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;C&#x1f96d; &#x1f33c;文章目录&#x1f33c; 1. 智能指针的使用场景分析 2. RAII和智能指针的设计思路 3. C标准库智能指针的使用 4. 智能指针的原…

web——upload-labs——第一关

今天新开一个upload-labs的靶场&#xff0c;文件上传&#xff0c;加油&#xff01;&#xff01;&#xff01;&#xff01; 先讲讲文件上传 文件上传&#xff1a;在Web开发中&#xff0c;文件上传功能是一个允许用户将文件&#xff08;例如图片、文档&#xff09;上传到服务器…

提升企业库存管理效率:聚水潭与金蝶云星空集成方案

查询聚水潭库存生成金蝶物料盘点作业 在企业的日常运营中&#xff0c;库存管理和物料盘点是至关重要的环节。为了实现高效、准确的数据对接&#xff0c;我们采用了轻易云数据集成平台&#xff0c;将聚水潭的库存数据无缝集成到金蝶云星空系统中。本案例将详细介绍如何通过API接…

MacOS下,如何在Safari浏览器中打开或关闭页面中的图片文字翻译功能

MacOS下&#xff0c;如何在Safari浏览器中打开或关闭页面中的图片文字翻译功能 在Mac上的Safari浏览器中&#xff0c;可以通过实况文本功能来实现图片中的文本翻译。关闭步骤具体步骤如下&#xff1a; 在浏览器地址栏&#xff0c;鼠标右击翻译按钮&#xff0c;然后点击“首选…

使用 PyAnsys 在 Ansys 随机振动分析中检索螺栓连接中的力和应力

介绍 随机振动模拟通常用于评估组件承受运输过程中振动的能力。随机振动分析利用先前模态分析的频率和模式内容对通过功率谱密度 (PSD) 负载定义的频谱和功率内容进行线性叠加。在大多数装配模型中&#xff0c;螺栓连接&#xff08;由求解器变为 BEAM188 元素&#xff09;通常…

使用Axios函数库进行网络请求的使用指南

目录 前言1. 什么是Axios2. Axios的引入方式2.1 通过CDN直接引入2.2 在模块化项目中引入 3. 使用Axios发送请求3.1 GET请求3.2 POST请求 4. Axios请求方式别名5. 使用Axios创建实例5.1 创建Axios实例5.2 使用实例发送请求 6. 使用async/await简化异步请求6.1 获取所有文章数据6…

让你的 环境变量 更合理

PATH PATH 环境变量由 shell 或 libc 读取来查找并执行程序&#xff0c;这就是当在终端中键入 ls 时 shell 可以找到 /bin/ls 的方式。 在基于 Debian 的桌面系统上&#xff0c;默认 PATH 变量如下所示&#xff1a; PATH/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sb…

vue3中将在线url地址转为图片显示方法教程

vue3中将在线url地址转为图片显示方法教程 转化后&#xff1a; 原来&#xff1a; 代码&#xff1a; <el-table-column label"制单人" align"center"><template #default"scope"><imgv-if"scope.row.maker":src"s…