这 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 直接操作的能力,使得其性能会下降,在类似页面列表渲染种,使用虚拟列表,展示可见部分,或者分页等物理方式进行优化。

相关推荐
糕冷小美n2 小时前
elementuivue2表格不覆盖整个表格添加固定属性
前端·javascript·elementui
小哥不太逍遥2 小时前
Technical Report 2024
java·服务器·前端
沐墨染2 小时前
黑词分析与可疑对话挖掘组件的设计与实现
前端·elementui·数据挖掘·数据分析·vue·visual studio code
anOnion2 小时前
构建无障碍组件之Disclosure Pattern
前端·html·交互设计
threerocks2 小时前
前端将死,Agent 永生
前端·人工智能·ai编程
苍何2 小时前
即梦Seedance2.0海外火爆出圈,AI 视频的 DeepSeek 时刻来了!(附实测教程)
后端
苍何2 小时前
阿里卷麻了,千问 Qwen-Image-2.0 发布,超强文字渲染、信息图、PPT 轻松做(附实测提示词)
后端
苍何3 小时前
被马斯克疯狂点赞的国产 AI,很可能是 AI 时代的抖音!
后端
苍何3 小时前
国产Windows 版 Claude Cowork 来了,内置海量 Skills,绝了。
后端
问道飞鱼3 小时前
【前端知识】Vite用法从入门到实战
前端·vite·项目构建