DEV Community

Cover image for Building Your Own Virtual DOM Reconciler in JavaScript: A Minimal Approach
Ezhill Ragesh
Ezhill Ragesh

Posted on

Building Your Own Virtual DOM Reconciler in JavaScript: A Minimal Approach

Introduction to Virtual DOM Reconciliation

An Image Explaining how VDOM works with the help of a Tree made by Ezhill Ragesh

Imagine your website is like a house. The real DOM would be the actual bricks and cement, every single element on the page. Changing even a small thing, like a light bulb, requires touching the physical structure.

The virtual DOM is like a blueprint of your house. It's a lightweight version that exists in memory, representing all the elements and their properties. When you want to make a change, you update the blueprint first. This is much faster and easier than manipulating the real house every time.

Benefits

Faster updates: When only a small part of your website needs to change, the virtual DOM allows you to update only that part, instead of re-rendering the entire page. This can significantly improve the performance of your website, especially on slower devices.

More predictable behavior: By separating the logic of what you want to see on the page from the actual rendering, you can ensure that your website behaves consistently and predictably across different browsers and devices.

Easier debugging: Since the virtual DOM is a representation of your website's state, it can be easier to debug issues and identify the root cause of any problems.

Reusable components: Building components with their own virtual DOM representations allows you to easily reuse them throughout your website, making your code more efficient and maintainable.

Concepts Involved in Reconciliation 

Virtual DOM: A lightweight copy of the real DOM, allowing us to make changes efficiently before updating the actual webpage.

Differencing Algorithm: The process of identifying what has changed between the current Virtual DOM and the previous one.
Patch and Update Strategy: Determining how to update the real DOM based on the differences found during the differencing process.

Step-by-Step Guide to Building Your Reconciler

In this step-by-step guide, we'll create a basic reconciler for dynamic updates in the DOM using a virtual document. Here's a breakdown of the process with practical steps.

Get Full Code here: fullCode

Initialize Virtual Document : Start with an empty array to represent the virtual document.

let virtualDocument = [];

2. Update DOM Elements : Create a function that compares the current virtual document with the existing one, updating the real DOM accordingly.

function updateDOMElements(existingDOM, currentDOM) {
  var parentElement = document.getElementById("mainArea");

  let additions = 0, removals = 0, modifications = 0;


  currentDOM.forEach(function(item) {

    var existingItem = existingDOM.find(function(oldItem) {
      return oldItem.id === item.id;
    });

    if (existingItem) {
      modifications++;

      var existingChild = document.querySelector(`[data-id='${item.id}']`);
      existingChild.children[0].innerHTML = item.title;
      existingChild.children[1].innerHTML = "Author: " + item.author;
    } else {
      additions++;

      var childElement = document.createElement("div");
      childElement.dataset.id = item.id; 

      var titleElement = document.createElement("span");
      titleElement.innerHTML = item.title;

      var authorElement = document.createElement("span");
      authorElement.innerHTML = "Author: " + item.author;

      var deleteButtonElement = document.createElement("button");
      deleteButtonElement.innerHTML = "Delete";
      deleteButtonElement.setAttribute("onclick", "removeBook(" + item.id + ")");

      childElement.appendChild(titleElement);
      childElement.appendChild(authorElement);
      childElement.appendChild(deleteButtonElement);
      parentElement.appendChild(childElement);
    }
  });


  existingDOM.forEach(function(oldItem) {
    if (!currentDOM.some(item => item.id === oldItem.id)) {
      removals++;
      var childToRemove = document.querySelector(`[data-id='${oldItem.id}']`);
      parentElement.removeChild(childToRemove);
    }
  });

  console.log(additions);
  console.log(modifications);
  console.log(removals);
}
Enter fullscreen mode Exit fullscreen mode

*3. Handle DOM Updates : * Utilize a function to manage the addition, modification, and removal of DOM elements based on changes in the virtual document.

function updateVirtualDocument(data) {
  let existingDOM = [...virtualDocument]; 
  virtualDocument = data.map(item => {
    return {
      id: item.id,
      title: item.title,
      author: item.author
    };
  });
  updateDOMElements(existingDOM, virtualDocument); 
}
Enter fullscreen mode Exit fullscreen mode

4. Set Interval for Dynamic Updates : Periodically invoke the update function to simulate dynamic data changes.

window.setInterval(() => {
  let books = [];
  for (let i = 0; i < Math.floor(Math.random() * 100); i++) {
    books.push({
      title: "Book " + (i + 1),
      author: "Author " + (i + 1),
      id: i + 1
    });
  }

  updateVirtualDocument(books);
}, 5000);
Enter fullscreen mode Exit fullscreen mode

Building your own virtual DOM reconciler is a rewarding experience that offers valuable insights into the heart of modern web development. While challenges exist, the benefits of performance optimization, customization, and deeper understanding outweigh the initial hurdles.

By embracing best practices, focusing on efficiency, and leveraging existing resources, you can build a powerful and versatile reconciler that empowers you to create exceptional web applications.
Stay Connected:
GitHub: ezhillragesh
Twitter: ezhillragesh
Website: ragesh.me

Don't hesitate to share your thoughts, ask questions, and contribute to the discussion. 
Happy coding!

Top comments (0)