这 5 种情况下虚拟 dom 的性能不如原生 dom

虚拟DOM的设计目的是提供一种更高效的方式来构建和更新Web应用程序的用户界面,同时降低了性能开销和提高了开发效率。有时候我们会遇到这个问题,虚拟 dom 性能一定会超过原生 dom?

答案是:不一定。

一、页面初始化渲染

像 React/Vue 这种基于虚拟 dom 的框架,在第一渲染页面的时候,如果页面内容较多,需要虚拟 dom 的运行时计算出实际 dom, 此时还没有涉及到重新渲染复用虚拟 dom, 此时与运行计算时间肯会造成页面的白屏时间。

二、静态内容渲染

  • React 渲染
ts 复制代码
// 引入React
import React from 'react';
import ReactDOM from 'react-dom';

// 一个简单的React组件
const SimplePage = () => (
  <div>
    <h1>Hello, World!</h1>
    <p>This is a simple static page.</p>
  </div>
);

// 渲染React组件到实际DOM
ReactDOM.render(<SimplePage />, document.getElementById('app'));
  • 原生 dom 渲染
ts 复制代码
// 获取实际DOM容器
const container = document.getElementById('app');

// 创建和设置实际DOM元素
const div = document.createElement('div');
const heading = document.createElement('h1');
heading.textContent = 'Hello, World!';
const paragraph = document.createElement('p');
paragraph.textContent = 'This is a simple static page.';

// 将元素添加到容器
div.appendChild(heading);
div.appendChild(paragraph);
container.appendChild(div);

对于页面(组件)中包含了静态内容的时候,使用 React 渲染,需要 React 的运行时计算过程,显然没有原生 dom 直接渲染的性能好。

三、大规模数据更新

tsx 复制代码
const container = document.getElementById('container');

function updateData() {
  const data = Array.from({ length: 1000 }, (_, index) => index);

  const virtualList = data.map((item) => {
    return <li key={item}>{item}</li>;
  });
  ReactDOM.render(<ul>{virtualList}</ul>, container);
}

updateData();


setInterval(() => {
  updateData(); // 模拟每秒更新一次数据
}, 1000);

一个每秒更新一次数据。尽管虚拟DOM通常能够提高性能,但由于每秒更新大量数据,虚拟DOM需要不断创建虚拟DOM元素、比较差异并更新实际DOM,这可能会导致性能下降。这里我们需要了解 React 一些特性来优化:

  • 物理上可以:分页和无限滚动加载,减少一次性加载的数据量。
  • 使用 memo api 来优化重复重复渲染。
  • 渲染可见部分的数据,而不是全部的数据,例如虚拟列表组件
  • 其他的

四、复杂的动画

动画一般都会涉及到元素的重绘和重排,这些操作会导致浏览器重新渲染页面元素。

  • 重绘:在不改变元素的布局的情况下,更新元素的可见样式(颜色、背景)
  • 重排:改变元素的布局,可能导致整个元素的重新布局。

它们都会影响性能的开销,如通过虚拟 dom 进行修改,虚拟 dom 需要额外的自己的与运行时,增加额外的性能。

  • React 渲染
ts 复制代码
import React, { useState } from 'react';

function AnimatedComponent() {
  const [left, setLeft] = useState(0);

  const animateLeft = () => {
    setLeft(left + 10);
  };

  return (
    <div>
      <button onClick={animateLeft}>Animate</button>
      <div
        style={{
          width: '100px',
          height: '100px',
          backgroundColor: 'blue',
          transform: `translateX(${left}px)`,
        }}
      />
    </div>
  );
}

export default AnimatedComponent;
  • 原生 dom 渲染
ts 复制代码
const box = document.getElementById('box');
let left = 0;

document.getElementById('animateButton').addEventListener('click', () => {
  left += 10;
  box.style.transform = `translateX(${left}px)`;
});

React 渲染需要状态配合,计算整个 style 当前值,会影响 dom 的内容,明显此时的性能会稍微有所下降。

五、低级的 dom 控制

直接访问和操作底层DOM元素的情况,而虚拟DOM库通常会将这些细节进行抽象和封装。在这些情况下,直接使用原生DOM操作通常更合适,因为它提供了更大的灵活性。

ts 复制代码
// 获取一个DOM元素
const element = document.getElementById('myElement');

// 直接操作DOM,例如添加一个事件处理程序
element.addEventListener('click', () => {
  element.style.backgroundColor = 'red';
});

// 手动创建新的DOM元素
const newElement = document.createElement('div');
newElement.textContent = 'This is a new element';

// 插入新元素到DOM中
document.body.appendChild(newElement);

// 移除DOM元素
const elementToRemove = document.getElementById('elementToRemove');
if (elementToRemove) {
  elementToRemove.parentNode.removeChild(elementToRemove);
}

此处挂载节点:

  • appendChild 添加到元素到指定 dom 种。
  • 从父接节点 parentNode.removeChild 移除一个元素

六、虚拟 dom 的优势

虚拟 dom 优势在于:

  • 优化、批量处理更新以及减少重排和重绘等性能。
  • 组件化开发
  • 跨平台兼容性
  • 生态系统和社区支持

八、原生 dom 优势

  • 学习曲线
  • 直接控制
  • 适合小型项目
  • 性能优势
  • 定制需求

七、小结

虚拟 dom 自身的优点是适合工程化组件化开发的大型项目,但是存在 运行时, 这些虚拟 dom 一般都有自己的运行时代码,在一些小的 dom 操作时不占据优势,在一些大的项目中虚拟 dom 配合组件化开发的优势得以体现,尽管虚拟 dom 可以优化,但是原生 dom 直接操作的能力,使得其性能会下降,在类似页面列表渲染种,使用虚拟列表,展示可见部分,或者分页等物理方式进行优化。

相关推荐
想用offer打牌7 小时前
MCP (Model Context Protocol) 技术理解 - 第二篇
后端·aigc·mcp
崔庆才丨静觅8 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60619 小时前
完成前端时间处理的另一块版图
前端·github·web components
KYGALYX9 小时前
服务异步通信
开发语言·后端·微服务·ruby
掘了9 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅9 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅9 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
爬山算法9 小时前
Hibernate(90)如何在故障注入测试中使用Hibernate?
java·后端·hibernate
崔庆才丨静觅10 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment10 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端