虚拟DOM

目录

  • 由状态到UI
    • 状态
    • 渲染
    • 命令式操作DOM
    • 声明式操作DOM
  • 效率的取舍
  • 虚拟DOM
  • VNode
  • Patch

由状态到UI

状态

状态可以是JavaScript中的任意类型。Object、Array、String、Number、Boolean等都可以作为状态,这些状态可能最终会以段落、表单、链接或按钮等元素呈现在用户界面上,具体地说是呈现在页面上

渲染

本质上,我们将状态作为输入,并生成DOM输出到页面上显示出来,这个过程叫作渲染

在Web开发的早期,因为网页的展现十分简陋,我们所维护的状态也十分的简单,我们大可以直接操作DOM来进行开发,然而随着时代的发展,我们所开发的web也变的十分复杂,维护的状态也十分的多,DOM操作也十分频繁

命令式操作DOM

随着开发的深入,我们会发现在我们的项目中存在着大量用于操作DOM的代码,这种由我们直接通过代码来操作DOM的开发方法被称为命令式操作DOM

这些代码难以复用,所用到的状态也很难管理,会导致整个项目的逻辑变得十分混乱

声明式操作DOM

幸运的是,现代的主流框架,如vue,react,angular等都支持声明式操作DOM

声明式操作DOM即我们只用声明状态,通过模板或者其他方式来描述状态与视图的关系,框架就能帮我们渲染视图

自此,我们不再需要手动的操作DOM,统一由框架来操作DOM也能获得更好地渲染效率

事实上,并不是因为框架的出现web才有了状态,任何应用本就具有状态,只不过现代框架揭露了一个事实:我们的精力应该放在状态上,而不是如何将状态变成视图

效率的取舍

框架的设计处处充斥着权衡的艺术

假设我们将直接操作DOM的性能损耗设为A

div.innerHTML = "hello world"

那么通过声明式操作DOM的性能损耗为A+B

<div>{{ hello world }}</div>

因为框架不仅需要直接修改,而且还需要找出差异,所以声明式的代码性能并不优于命令式代码,但声明式代码的可维护性高,效果直观,而且我们可以通过各种手段来提升声明式代码的性能

但是需要注意的是,声明式代码本就依托于命令式代码,所以声明式代码优化也只能在寻找差异步骤处优化,再怎么优化性能也不会比命令式代码性能高效

虚拟DOM

理论上,用户的任何操作都有可能造成状态的改变,当状态改变时我们就需要重新渲染,直接操作DOM向来是简单且直接的,我们大可以将现有的DOM直接删除,然后重新根据现有状态来生成一个DOM,但是访问DOM是非常昂贵的。按照上面说的方式做,会造成相当多的性能浪费。状态变化通常只有有限的几个节点需要重新渲染,所以我们不仅需要找出哪里需要更新,还需要尽可能少地访问DOM
如何在找出哪里需要更新并且最大限度的减少DOM的访问,各家框架都有自己的一套解决方案,angular是脏检查的流程,react是虚拟DOM,vue1是细粒度的绑定,但从vue2开始就变成了虚拟DOM

虚拟DOM的解决方式是通过状态生成一个虚拟节点树,然后使用虚拟节点树进行渲染。在渲染之前,会使用新生成的虚拟节点树和上一次生成的虚拟节点树进行对比,只渲染不同的部分

虚拟DOM
在vue中,我们使用模板来描述状态与DOM之间的映射关系。vue通过编译将模板转换成渲染函数(render),执行渲染函数就可以得到一个虚拟节点树,使用这个虚拟节点树就可以渲染页面

render

VNode

VNode是vue中的一个类,通过new Vnode来生成虚拟节点,我们所谓的虚拟节点,本质上就是一个js对象,所谓的虚拟DOM树,就是由一个个js对象构成

在vue中,VNode的类型有以下几种

  1. 注释节点
  2. 文本节点
  3. 元素节点
  4. 组件节点
  5. 函数式组件
  6. 克隆节点

由于vue对组件采用了虚拟DOM来更新视图,当属性发生变化时,整个组件都要进行重新渲染的操作,但组件内并不是所有DOM节点都需要更新,所以将vnode缓存并将当前新生成的vnode和上一次缓存的oldVnode进行对比,只对需要更新的部分进行DOM操作可以提升很多性能

Patch

对两个虚拟节点进行比对是虚拟DOM中最核心的算法(即patch),它可以判断出哪些节点发生了变化,从而只对发生了变化的节点进行更新操作,具体关于patch的文章可以看我这篇博客
未动笔,未来可寄

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

课程设计---哈夫曼树的编码与解码(Java详解)

目录 一.设计任务&&要求&#xff1a; 二.方案设计报告&#xff1a; 2.1 哈夫曼树编码&译码的设计原理&#xff1a; 2.3设计目的&#xff1a; 2.3设计的主要过程&#xff1a; 2.4程序方法清单&#xff1a; 三.整体实现源码&#xff1a; 四.运行结果展示&…

javaSE:继承

在谈继承之前&#xff0c;我们先观察下面这个代码&#xff1a; //定义一个猫类 class Cat {public String name;public int age;public float weigth;public void eat(){System.out.println(this.name"正在吃饭");}public void mimi(){System.out.println(this.nam…

等保测评-第一级通用要求

安全物理环境 物理访问控制 机房出入口应安排专人值守或配置电子门禁系统,控制、鉴别和记录进入的人员 防盗窃和防破坏 应将设备或主要部件进行固定,并设置明显的不易除去的标识。 防雷击 应将各类机柜、设施和设备等通过接地系统安全接地。 防火 机房应设置灭火设备 …

【面试】TCP 与 UDP区别

一、TCP 与 UDP 对比 TCP 传输控制协议 TCP&#xff08;Transmission Control Protocol&#xff09;&#xff0c;是面向连接的【3次握手&#xff0c;4次挥手】&#xff0c;提供可靠交付&#xff0c;具有错误恢复机制&#xff08;如超时重传、校验和等&#xff09;&#xff0c…

YoloV9改进策略:注意力篇|BackBone改进|自研像素和通道并行注意力模块(独家原创)

摘要 本文使用FFA-Net的注意力改进YoloV9,FFA-Net提出了通道注意力和像素注意力相结合的方式,提高Block的表征能力,我把这两种注意力结合起来改进YoloV8的BackBone,取得了非常好的效果,即插即用,简单易懂,非常适合大家入手。 论文翻译:《FFA-Net:用于单图像去雾的特征…

nccl 03 记 回顾:从下载,编译到调试 nccl-test

1&#xff0c; 下载与编译 1.1 源码下载 $ git clone https://github.com/NVIDIA/nccl.git 1.2 编译 1.2.1 一般编译&#xff1a; $ make -j src.build 1.2.2 特定架构gpu 编译 $ make -j src.build NVCC_GENCODE"-gencodearchcompute_80,codesm_80" A10…

qt pro工程文件通用宏定义

在 Qt .pro 文件中&#xff0c;有一些预定义的宏&#xff08;或变量&#xff09;&#xff0c;它们代表了特定的路径或与项目、构建环境相关的信息。 以下是一些常用的 .pro 文件宏&#xff1a; 通用宏 $$PWD: 当前 .pro 文件所在的绝对路径。这是一个非常重要的宏&#xff0c;…

react笔记-05react扩展篇

react笔记-扩展篇 包括新用法和hooks 1. setState setState更新状态的两种写法&#xff1a; 1. setState({}, [() > {}]) 2. setState(() > {// 返回一个状态修改对象return {} }, [() > {}])1. 对象写法&#xff1a; ⚠️注意&#xff1a;react更新状态是异步的 …

探究布局模型:从LayoutLM到LayoutLMv2与LayoutXLM

LAYOUT LM 联合建模文档的layout信息和text信息&#xff0c; 预训练 文档理解模型。 模型架构 使用BERT作为backbone&#xff0c; 加入2-D绝对位置信息&#xff0c;图像信息 &#xff0c;分别捕获token在文档中的相对位置以及字体、文字方向、颜色等视觉信息。 2D位置嵌入 …

Linux 查看进程 ps -ef | grep

说明 在 Unix 和 Linux 系统中&#xff0c;ps -ef 命令用于显示所有正在运行的进程的详细信息。而 grep 是一个强大的文本搜索工具&#xff0c;它允许你在输入流&#xff08;比如来自文件或另一个命令的输出&#xff09;中搜索特定的模式。 当你将 ps -ef 的输出通过管道 | 传…

装备制造行业数据分析指标体系

数字化飞速发展的时代&#xff0c;多品种、定制化的产品需求、越来越短的产品生命周期、完善的售后服务、极佳的客户体验和快速的交货速度等&#xff0c;使得装备制造行业的经营环境越来越复杂&#xff0c;企业竞争从拼产品、拼价格迈向拼服务&#xff0c;装备制造企业正处于数…

阿里云 debian10.3 sudo apt-get updat 报错的解决方案

阿里云全新的debian10.3(buster)镜像&#xff0c;却无法正常执行 sudo apt-get update。主要报错信息如下&#xff1a; Err:6 http://mirrors.cloud.aliyuncs.com/debian buster-backports Release404 Not Found [IP: 100.100.2.148 80] Err:3 http://mirrors.cloud.aliyuncs…

无引擎游戏开发(1):EasyX图形库引入 + 跟随鼠标移动的小球

来自bilibili up主的Voidmatrix的视频教程&#xff1a;【从零开始的C游戏开发】 一、图形库引入 EasyX在国内文档最多&#xff0c;而且功能函数齐全&#xff0c;最适合入门。 环境配置&#xff1a;vs2022 &#xff08;官网下载免费版&#xff09; 百度搜EasyX官方&#xff0…

后方穿行预警系统技术规范(简化版)

后方穿行预警系统技术规范(简化版) 1 系统概述2 预警区域3 预警目标4 预警条件5 指标需求1 系统概述 RCTA后方穿行预警系统工作在驾驶员有倒车意向的时候。在倒车过程中当驾驶员视线因周围障碍物被遮挡而产生碰撞风险时,系统通过光学信号对驾驶员进行提醒。 2 预警区域 RCT…

前端入门篇(五十二)练习6:transition过渡小动画

所以应该先找到第n个li&#xff0c;找到li再找img&#xff0c;li没有找错&#xff0c;底下又各自只有一个img&#xff0c;解决 ul li:nth-child(1) img { } 描述文字从下往上&#xff1a; 一开始描述也在框框下面&#xff0c;当hover时&#xff0c;translateY(0)&#xff0…

js处理数组的方法总结

本文总结了JavaScript操作数组的所有方法方式。包含了ES6新增的方法。会在操作方法上解释出现的版本。 内容较多&#xff0c;建议收藏查看。 push(): 在数组末尾添加一个或多个元素&#xff0c;并返回新的长度。 let arr [1, 2, 3]; let newLength arr.push(4, 5); console.…

【JS重点18】原型链(面试重点)

一&#xff1a;原型链底层原理 以下面一段代码为例&#xff0c;基于原型对象&#xff08;Star构造函数的原型对象&#xff09;的继承使得不同构造函数的原型对象关联在一起&#xff08;此处是最大的构造函数Object原型对象&#xff09;&#xff0c;并且这种关联的关系是一种链…

CleanShot X for Mac v4.7 屏幕滚动长截图录像工具(保姆级教程,小白轻松上手,简单易学)

Mac分享吧 文章目录 一、下载软件二、部分特有功能效果1、截图软件的普遍常用功能&#xff08;画框、箭头、加文字等&#xff09;都具备&#xff0c;不再详细介绍2、ABCD、1234等信息标注&#xff08;每按一下鼠标&#xff0c;即各是A、B、C、D...等&#xff09;3、截图更换背…

SQL注入-下篇

HTTP注入 一、Referer注入 概述 当你访问一个网站的时候&#xff0c;你的浏览器需要告诉服务器你是从哪个地方访问服务器的。如直接在浏览器器的URL栏输入网址访问网站是没有referer的&#xff0c;需要在一个打开的网站中&#xff0c;点击链接跳转到另一个页面。 Less-19 判…

Oracle中先进先出数据结构的例子

在Oracle中&#xff0c;实现先进先出&#xff08;FIFO&#xff09;数据结构的一个典型例子可以通过设计和查询特定的表来完成。以下是一个简化的例子来说明这个概念&#xff1a; 1. 设计表结构 首先&#xff0c;我们需要一个包含“入队”时间戳的表来模拟队列的行为。以下是一…