Lädt...


🔧 React Virtual DOM


Nachrichtenbereich: 🔧 Programmierung
🔗 Quelle: dev.to

Introduction

Hi, Gleb Kotovsky is here!

Today I wanna talk about Virtual DOM, specifically - React Virtual DOM

So, the virtual DOM (Virtual Document Object Model) is a cool programming idea that keeps a "virtual" version of a user interface in memory. This version syncs up with the browser's DOM (Document Object Model) using a library.

You’ll find the virtual DOM is a big part of many JavaScript front-end frameworks, and it’s one of the reasons they’re so efficient. In this article, we're going to dive into how the virtual DOM works in React and why it’s important for the library.

What is the DOM?

When a webpage loads in a browser, it typically receives an HTML document from the server. The browser then builds a logical, tree-like structure from this HTML to render the requested page for the user. This structure is known as the DOM.

The Document Object Model (DOM) represents a logical tree that describes a document. Each branch of the tree ends in a node , which contains an object . Because the browser parses the document into this tree structure, there is a need for methods that allow for programmatic access to the tree, enabling modifications to the document's structure, style, or content. This necessity led to the development of the DOM API, which offers these methods for manipulating the nodes representing the elements in the tree.

Dom Objects

React's Virtual DOM Implementation

To optimize re-rendering in websites and applications, many JavaScript frameworks offer different strategies. However, React employs the concept of the virtual DOM.

The virtual DOM in React represents the user interface as a "virtual" tree structure, where each element is a node containing an object. This representation is maintained in memory and synchronized with the browser's DOM through React's React DOM library.

When React and many other famous frameworks uses Virtual DOM, Svelte meanwhile has no Virtual DOM. Svelte works directly with the DOM in the browser and modifies it as needed.

Here's a simple example to illustrate the Virtual DOM in a React component:

import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  const increment = () => setCount(count + 1);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={increment}>Increment</button>
    </div>
  );
}

In this example:

  • The component renders a counter and a button.
  • When the button is clicked, the state is updated, prompting React to create a new Virtual DOM tree.
  • The diffing algorithm checks what has changed (only the count) and updates the real DOM accordingly.

After the component is first rendered and the state is count: 0, the actual DOM will look like this:

<div>
  <h1>Counter</h1>
  <p>Count: 0</p>
  <button>Increment</button>
</div>

How the Virtual DOM Works:

Here's a simple example to illustrate the Virtual DOM in a React component, starting with the component definition:

1. Component Definition

import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  const increment = () => setCount(count + 1);

  return (
    <div>
      <h1>Counter</h1>
      <p>Count: {count}</p>
      <button onClick={increment}>Increment</button>
    </div>
  );
}

2. Initial Render Process

2.1 Component Initialization

When the component is first rendered, React calls the Counter function.

2.2 State Initialization

useState(0) initializes the component's state to 0.

2.3 Creating the Virtual DOM

React generates a Virtual DOM tree using the component's returned JSX structure. This tree is a lightweight representation of the UI.

For the initial render, the Virtual DOM might look like this:

{
  "type": "div",
  "props": {
    "children": [
      { "type": "h1", "props": { "children": "Counter" } },
      { "type": "p", "props": { "children": "Count: 0" } },
      { "type": "button", "props": { "children": "Increment" } }
    ]
  }
}

2.4 Updating the Real DOM

React then takes this Virtual DOM and calculates what changes need to be made to the actual DOM. In this case, it creates the following HTML:

<div>
  <h1>Counter</h1>
  <p>Count: 0</p>
  <button>Increment</button>
</div>

3. User Interaction

When a user clicks the "Increment" button, the following steps occur:

3.1 Event Handling

The button's onClick event triggers the increment function, calling setCount(count + 1).

3.2 State Update

The component's state is updated, which causes React to know that it needs to re-render the component with the new state.

4. Re-render Process

4.1 Component Re-invocation

React calls the Counter function again due to the state change.

4.2 New Virtual DOM Creation

A new Virtual DOM tree is created reflecting the updated state:

{
  "type": "div",
  "props": {
    "children": [
      { "type": "h1", "props": { "children": "Counter" } },
      { "type": "p", "props": { "children": "Count: 1" } },
      { "type": "button", "props": { "children": "Increment" } }
    ]
  }
}

4.3 Diffing the Virtual DOM

React compares the new Virtual DOM with the previous Virtual DOM. It identifies what has changed—in this case, the text in the <p> tag has changed from "Count: 0" to "Count: 1".

4.4 Reconciliation

Only the parts of the real DOM that have changed are updated. In this case, React updates the real DOM to reflect the new count:

<div>
  <h1>Counter</h1>
  <p>Count: 1</p> <!-- Updated content -->
  <button>Increment</button>
</div>

5. Performance Optimization

5.1 Batching Updates

If multiple state updates occur in rapid succession (e.g., multiple button clicks), React may batch these updates together for efficiency, minimizing the number of re-renders and DOM updates.

Common Problems with React Virtual DOM and How to Avoid Them

  1. Performance Bottlenecks
    • Issue: Excessive re-renders can occur even with the Virtual DOM.
    • Solution: Use React.memo to memoize functional components.
const MyComponent = React.memo(({ value }) => {
  console.log('Rendered: ', value);
  return <div>{value}</div>;
});

Legacy: Use shouldComponentUpdate in class components:

class MyClassComponent extends React.Component {
  shouldComponentUpdate(nextProps) {
    return nextProps.value !== this.props.value;
  }

  render() {
    return <div>{this.props.value}</div>;
  }
}

  1. Inefficient Key Management
    • Issue: Improper handling of keys in lists can lead to bugs.
    • Solution: Use unique and stable keys, not array indices.
   const items = ['Apple', 'Banana', 'Cherry'];
      return (
        <ul>
          {items.map(item => (
            <li key={item}>{item}</li> // Prefer unique values as keys
          ))}
        </ul>
      );
  1. Overusing State and Updates
    • Issue: Too many state updates lead to performance issues.
    • Solution: Combine related states
const [state, setState] = useState({
  name: '',
  age: 0,
});

const updateAge = (newAge) => {
  setState(prevState => ({ ...prevState, age: newAge }));
};

  1. Using Inline Functions
    • Issue: Inline functions create new instances on every render.
    • Solution: Use useCallback to memoize functions.
const increment = useCallback(() => {
  setCount(c => c + 1);
}, []); // Only recreate the function if dependencies change

  1. Deep Component Trees
    • Issue: Deeply nested components trigger multiple re-renders.
    • Solution: Use context.
const CountContext = React.createContext();

const ParentComponent = () => {
  const [count, setCount] = useState(0);

  return (
    <CountContext.Provider value={{ count, setCount }}>
      <ChildComponent />
    </CountContext.Provider>
  );
};

const ChildComponent = () => {
  const { count, setCount } = useContext(CountContext);
  return <div onClick={() => setCount(count + 1)}>Count: {count}</div>;
};

  1. Excessive Re-renders Due to Parent Component Updates
    • Issue: Child components re-render when parents update.
    • Solution: Memoize child components.
const ChildComponent = React.memo(({ count }) => {
  return <div>Count: {count}</div>;
});

  1. Inefficient Rendering of Expensive Components
    • Issue: Expensive components can slow down the app.
    • Solution: Use React.lazy and React.Suspense.
const LazyComponent = React.lazy(() => import('./LazyComponent'));

const App = () => (
  <React.Suspense fallback={<div>Loading...</div>}>
    <LazyComponent />
  </React.Suspense>
);

  1. Managing Side Effects
    • Issue: Side effects can cause bugs if not managed properly.
    • Solution: Use useEffect with proper dependencies.
useEffect(() => {
  const timer = setTimeout(() => {
    console.log('Time elapsed');
  }, 1000);

  return () => clearTimeout(timer); // Cleanup on unmount or if dependencies change
}, [dependencies]); // Replace with actual dependency

  1. Confusion Between State and Props
    • Issue: Misunderstanding when to use state vs. props.
    • Solution: Use props for externally managed data and state for local data.
const ParentComponent = () => {
  const [name, setName] = useState('John');

  return <ChildComponent name={name} setName={setName} />;
};

const ChildComponent = ({ name, setName }) => (
  <div>
    <p>{name}</p>
    <button onClick={() => setName('Jane')}>Change Name</button>
  </div>
);

  1. Neglecting Accessibility
    • Issue: Accessibility concerns can be ignored.
    • Solution: Use semantic HTML and accessibility tools.
const AccessibleButton = () => (
  <button aria-label="Increment" onClick={increment}>
    Increment
  </button>
);

Conclusion

To wrap things up, React’s Virtual DOM is a fantastic feature that really boosts the performance of your web applications. By creating a lightweight version of the actual DOM, React can make updates more efficiently, avoiding the slowdowns that come with direct DOM manipulation.

That said, it’s important to watch out for common issues like excessive re-renders, poor key management in lists, and mixing up state and props. By keeping some best practices in mind—like using memoization, deploying context for handling state, and managing side effects wisely—you can get the most out of React and keep your apps running smoothly.

Happy hacking!

Resources

1) https://www.geeksforgeeks.org/reactjs-virtual-dom/
2) https://svelte.dev/blog/virtual-dom-is-pure-overhead
3) https://refine.dev/blog/react-virtual-dom/#introduction

...

🔧 Virtual DOM and Actual DOM with Analogy Explanation


📈 31.83 Punkte
🔧 Programmierung

🔧 Virtual DOM and Actual DOM with Analogy Explanation


📈 31.83 Punkte
🔧 Programmierung

🔧 Dom and Virtual Dom


📈 31.83 Punkte
🔧 Programmierung

🔧 Actual DOM and Virtual DOM in Javascript


📈 31.83 Punkte
🔧 Programmierung

🔧 Real DOM vs Virtual DOM


📈 31.83 Punkte
🔧 Programmierung

🔧 Efficient DOM Manipulation with the Virtual DOM and Refs


📈 31.83 Punkte
🔧 Programmierung

🔧 Shadow DOM vs Virtual DOM: Understanding the Key Differences


📈 31.83 Punkte
🔧 Programmierung

🔧 Understanding Reconciliation in ReactJs - Keeping the Virtual DOM and the Real DOM in Sync.


📈 31.83 Punkte
🔧 Programmierung

🔧 Difference between a virtual DOM and a real DOM


📈 31.83 Punkte
🔧 Programmierung

🔧 Difference Between DOM and Virtual DOM


📈 31.83 Punkte
🔧 Programmierung

🔧 React - Virtual DOM, Reconciliation, Fiber


📈 25.28 Punkte
🔧 Programmierung

🔧 React's Virtual DOM: Unveiling the Engine Behind Lightning-Fast Web Applications


📈 25.28 Punkte
🔧 Programmierung

🔧 The Role of Virtual DOM in React.js Transforming Frontend Development


📈 25.28 Punkte
🔧 Programmierung

🔧 React Virtual DOM


📈 25.28 Punkte
🔧 Programmierung

🔧 Understanding the React Virtual DOM


📈 25.28 Punkte
🔧 Programmierung

🔧 O que é o Virtual DOM e por que ele torna o React tão eficiente?


📈 25.28 Punkte
🔧 Programmierung

🔧 "Day 16: Exploring React Workflow & Virtual DOM!"


📈 25.28 Punkte
🔧 Programmierung

🔧 Understanding Reconciliation and the Virtual DOM in React


📈 25.28 Punkte
🔧 Programmierung

🔧 Mastering React Virtual DOM: Boost Your App Performance and Efficiency


📈 25.28 Punkte
🔧 Programmierung

🔧 What is the Virtual DOM in React?


📈 25.28 Punkte
🔧 Programmierung

🔧 Virtual DOM and its Significance in React


📈 25.28 Punkte
🔧 Programmierung

🔧 Uhmm Virtual DOM In React?...


📈 25.28 Punkte
🔧 Programmierung

🔧 Deciphering the Origins: Why the DOM is called the DOM?


📈 25.09 Punkte
🔧 Programmierung

🔧 Mythbusting DOM: Is DOM the same as HTML?


📈 25.09 Punkte
🔧 Programmierung

🔧 Mythbusting DOM: Was DOM Invented Alongside HTML?


📈 25.09 Punkte
🔧 Programmierung

🕵️ Mozilla Firefox bis 46 DOM Element Handler mozilla::dom::Element Pufferüberlauf


📈 25.09 Punkte
🕵️ Sicherheitslücken

🕵️ Mozilla Firefox bis 46 DOM Element Handler mozilla::dom::Element Pufferüberlauf


📈 25.09 Punkte
🕵️ Sicherheitslücken

🔧 DOM Manipulation: Selecting and Manipulating DOM Elements


📈 25.09 Punkte
🔧 Programmierung

🔧 Deciphering the Origins: Why the DOM is called the DOM?


📈 25.09 Punkte
🔧 Programmierung

🔧 React JS DOM vs React Native Component Tree: A Comprehensive Technical Comparison


📈 24.55 Punkte
🔧 Programmierung

🔧 Routing in React with React Router Dom


📈 24.55 Punkte
🔧 Programmierung

🔧 Como usar o React Router Dom versão 6.26.0 em seu projeto com react js.


📈 24.55 Punkte
🔧 Programmierung

🔧 React Router | React Router DOM


📈 24.55 Punkte
🔧 Programmierung

🔧 React Rooting (react-router-dom)


📈 24.55 Punkte
🔧 Programmierung

matomo