【 React 】虚拟DOM - 也没那么复杂

了解一个名词,首先得了解它产生的背景~

1、虚拟DOM的背景

最早由开发者 Jordan Walke 在 2010 年提出,应用在React框架中。(这个概念提出居然有14年了~)

当时解决什么问题?

Web 应用开发中普遍存在的性能问题

就像: 频繁操作DOM --> 导致页面重绘 --> 页面卡顿

背景基本Get, 那什么是虚拟DOM?

2、什么是虚拟DOM?

上简单案例:

javaScript 复制代码
<div id="app">
  <p class="text">hello world!!!</p>
</div> 

上面的HTML转换成虚拟DOM如下:

javaScript 复制代码
const virtualDOM = {
  tag: 'div',
  props: {
    id: 'app'
  },
  children: [
    {
      tag: 'p',
      props: {
        className: 'text'
      },
      children: [
        'hello world!!!'
      ]
    }
  ]
}

从案例可知, 虚拟DOM:

  • 包含了 tag、props、children 三个属性
  • 是个对象
  • 是对真实DOM的一种抽象表示

背景,概念结构基本已清晰,接着了解它是如何工作的?

3、虚拟 DOM 的工作原理

上简单案例:

假设我们有以下两个虚拟 DOM 树:

首先:从图比对发现className 属性发生了变化,从 'text' 变为 'updated-text'。

其次:根据这个变化,生成一个 DOM 操作指令,更新className。

接着:将这个 DOM 操作指令应用到真实的 DOM 上,以更新页面的显示。

最后:用简单的话概括虚拟 DOM 的工作流程也就是

  • 构建虚拟 DOM 树
  • 比较新旧树找差异
  • 生成 DOM 操作指令
  • 将指令应用到真实DOM上

工作原理基本大致了解,接着再往深挖一层

上面我们是通过眼睛观察到className 属性发生了变化,那机器是基于什么原则来观察这个变化?

也就是新旧树找出差异是如何比较的?

4、闪亮登场 diff(差异比较)算法

都说diff算法复杂,可是复杂不是由简单构成的么,那就先认识一个最简单的 diff 算法示例也可~

上简单案例:

一个简单的 diff 函数比较:

javaScript 复制代码
// 比较两个节点是否相同
function diff(oldNode, newNode) {
  if (!oldNode || !newNode) {
    // 如果有一个节点不存在,则返回替换节点的指令
    return { type: 'replace', newNode };
  }
  
  if (oldNode.tag !== newNode.tag) {
    // 如果两个节点的标签名不同,则返回替换节点的指令
    return { type: 'replace', newNode };
  }

  return null; // 节点相同,返回空指令
}

// 测试 diff 算法
const oldNode = new Node('div', { id: 'app' }, []);
const newNode = new Node('div', { id: 'app' }, []);
const patches = diff(oldNode, newNode);

console.log(patches); // 输出:null
javaScript 复制代码
// 定义节点的数据结构
class Node {
  constructor(tag, props, children) {
    this.tag = tag; // 标签名
    this.props = props; // 属性对象
    this.children = children; // 子节点数组
  }
}

在上面这个简单的示例中,定义了一个 diff 函数,它接受两个节点作为参数。

并比较它们的标签名是否相同。如果标签名不同,则返回一个表示替换节点的指令。

如果标签名相同,则返回空指令表示节点相同。

而在我们平时框架中的diff算法:

  • 通常会结合深度优先搜索、优化策略、最小化更新技术;
  • 这三个概念在 diff 算法中起着重要作用,帮助实现虚拟 DOM 的快速更新和渲染
  • 简言之:水有点深,改日再挖~

以上就是对虚拟DOM产生背景、概念、工作原理的分层概述~

最后总结虚拟DOM的优点。

5、优点表彰

1)性能提升:

在内存中进行 DOM 结构的比较和计算 -> 提高页面渲染性能。

2)更好的跨平台兼容性:

也就是一次编写多端运行的能力。

可以在浏览器端使用 React 渲染虚拟 DOM,也可以在服务器端使用 Node.js 渲染相同的虚拟 DOM。

不需要修改虚拟 DOM 的结构或代码。

相关推荐
qiyi.sky8 分钟前
JavaWeb——Vue组件库Element(3/6):常见组件:Dialog对话框、Form表单(介绍、使用、实际效果)
前端·javascript·vue.js
煸橙干儿~~11 分钟前
分析JS Crash(进程崩溃)
java·前端·javascript
安冬的码畜日常20 分钟前
【D3.js in Action 3 精译_027】3.4 让 D3 数据适应屏幕(下)—— D3 分段比例尺的用法
前端·javascript·信息可视化·数据可视化·d3.js·d3比例尺·分段比例尺
l1x1n01 小时前
No.3 笔记 | Web安全基础:Web1.0 - 3.0 发展史
前端·http·html
昨天;明天。今天。1 小时前
案例-任务清单
前端·javascript·css
zqx_72 小时前
随记 前端框架React的初步认识
前端·react.js·前端框架
惜.己3 小时前
javaScript基础(8个案例+代码+效果图)
开发语言·前端·javascript·vscode·css3·html5
什么鬼昵称3 小时前
Pikachu-csrf-CSRF(get)
前端·csrf
长天一色3 小时前
【ECMAScript 从入门到进阶教程】第三部分:高级主题(高级函数与范式,元编程,正则表达式,性能优化)
服务器·开发语言·前端·javascript·性能优化·ecmascript
NiNg_1_2343 小时前
npm、yarn、pnpm之间的区别
前端·npm·node.js