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

Ezhill RageshEzhill Ragesh
4 min read

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

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

  2. Differencing Algorithm: The process of identifying what has changed between the current Virtual DOM and the previous one.

  3. 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

  1. Initialize Virtual Document : Start with an empty array to represent the virtual document.
let virtualDocument = [];
  1. 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);
}

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); 
}

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);

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:

Don’t hesitate to share your thoughts, ask questions, and contribute to the discussion.

Happy coding!

10
Subscribe to my newsletter

Read articles from Ezhill Ragesh directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Ezhill Ragesh
Ezhill Ragesh

🎓 I'm currently studying Computer Science Engineering and Business Systems at Vellore Institute of Technology, Vellore. 💡 Some technologies I enjoy working with include Javascript, Typescript, React. 🌱 I'm on track for learning more about Data Structures and Algorithm, Software Development, Systems Design. ✉️ Get in touch with me via email at ragesh@duck.com.