Skip to content

Latest commit

 

History

History

VirtualDOM

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 

1. Summary

This is a simplified virtual DOM implemented using native JavaScript. It includes key features like creating virtual nodes, rendering the virtual DOM to real DOM, performing a diff operation, and updating the real DOM. By recursively comparing differences between old and new virtual DOM trees, it generates update instructions (patches) and applies changes to the real DOM. This basic implementation demonstrates the core principles of a virtual DOM, though real-world applications may require further optimization and complexity adjustments.

2. How it works

This project contains just two files: a basic HTML file and a JavaScript file. These files work together to create and update a virtual DOM structure, which is then used to render elements to the actual DOM. Here is a guide on the key functions and their usage:

createElement()

    const dom = createElement('tagname', { 
        attribute1: "value1", 
        attribute2: "value2" 
    }, ["Content or tag"]);

The createElement function generates virtual DOM nodes. You can define the tag type, attributes, and either nested elements or text content as children. This virtual node structure allows elements to be represented in memory before rendering them to the actual DOM.

renderElement()

    parent.appendChild(renderElement(dom));

The renderElement function takes a virtual DOM node and converts it into a real DOM element. After calling createElement, use renderElement to render the virtual node onto the page by appending it to a parent node in the actual DOM.

diff()

    const patch = diff(oldDom, newDom);

The diff function compares two virtual DOM trees—oldDom and newDom—and identifies differences between them. This function generates a set of changes (patches) that can be applied to the actual DOM to make it match the new virtual DOM structure.

patch()

    patch(parent, patch);

The patch function applies the changes generated by diff to the real DOM. Using the patch instructions, this function efficiently updates only the parts of the DOM that need changes, minimizing unnecessary re-renders and optimizing performance.

Together, these functions create a streamlined process for building and updating a DOM structure with virtual DOM principles. By first creating a virtual DOM, rendering it, and then applying updates only when differences are detected, this project demonstrates a simplified virtual DOM setup. This structure offers a foundation for understanding virtual DOM operations.

3. Code Implementation

3.1 Create Element

This function creates a virtual DOM node by taking in three arguments: tag, props, and children. It returns an object that represents the node:

tag

  • The type of HTML tag (e.g., 'div', 'span').

props

  • An object containing the node’s attributes or properties, such as id or class.

children

  • An array representing child nodes, which can be strings or other virtual DOM nodes. The function returns an object representing the virtual node structure, which is used for further rendering or updating.

3.2 Render Element

The renderElement function converts a virtual DOM node into an actual DOM node.

  • If the virtual node is a string, it creates and returns a text node.
  • If the virtual node is an object (created by createElement), it:
    1. Creates a DOM element based on the tag.
    2. Loops through each property in props to add them as attributes to the created element.
    3. Recursively renders each child in the children array and appends them as child nodes of the newly created element.
  • This function returns a fully constructed DOM element tree that mirrors the virtual DOM structure.

3.3 Diff

The diff function compares an old virtual DOM node with a new one and generates a list of patches (changes) required to transform the old DOM into the new one:

  1. Add or Remove Nodes

If oldNode or newNode is undefined, it creates an "ADD" or "REMOVE" patch.

  1. Text Changes

If both nodes are text nodes and their content differs, it generates a "TEXT" patch.

  1. Node Replacement

If the tag values of oldNode and newNode differ, it generates a "REPLACE" patch.

  1. Props Changes

Compares props in both nodes to identify differences, generating a "PROPS" patch containing any added, changed, or removed properties.

  1. Children Changes

Recursively compares child nodes in children, generating a "CHILDREN" patch with a list of child patches.

The function returns an array of patches to update the DOM structure efficiently.

3.4 Patch

The patch function applies the patches generated by the diff function to update the real DOM:

  • It targets a DOM element (el) at a specified index in the parent node.
  • Each type of patch is handled by specific actions:
    1. ADD:
    • Appends a new DOM node rendered from newNode to the parent.
    1. REMOVE:
    • Removes the target DOM element from the parent.
    1. TEXT:
    • Updates the text content of el with the new text.
    1. REPLACE:
    • Replaces el with a new DOM node created from newNode.
    1. PROPS:
    • Updates attributes of el by setting or removing properties as per the patch.
    1. CHILDREN:
    • Recursively applies patches to each child element, matching their order.

The function uses these patches to make precise updates to the DOM, ensuring minimal re-rendering.

4. ~ Last

These codes were created to help me understand the basic principles and implementation of a virtual DOM. By building each part—from creating virtual nodes to rendering, diffing, and updating the DOM—I’ve gained a clearer sense of how a virtual DOM operates at its core. However, this is just a simplified version, far from a robust, efficient virtual DOM system used in real-world applications.

There are still many limitations in this implementation, such as optimizations for performance, deep-level diff algorithm improvements, event handling, and compatibility issues. The diff and patch methods here don’t handle certain edge cases and would struggle with more complex application scenarios. Even so, this exercise has strengthened my grasp of the virtual DOM’s core concepts and given me confidence to explore more advanced implementations and optimizations.

In summary, this is just a learning exercise and has much room for improvement before it could be considered a mature virtual DOM implementation. Moving forward, I hope to build on this foundation and create a more efficient and comprehensive virtual DOM system.


Last Modified by SeeChen @ 06-NOV-2024 19:38 UTC +08:00