Skip to content

DOM, Virtual DOM, Shadow DOM

Document Object Model (DOM)

When we say a webpage is loaded we mean a document is loaded which contain various object like HTML, head, body and, so on think of it as a file system. Arranged in a tree structure. JS can manipulate the DOM directly by specifying the tags/objects and perform operations like read, write, delete, and update to the DOM bringing Dynamic nature to it.

 
console.log(document);  //we can access the entire DOM with it.
 

Virtual DOM

With the introduction of JS frameworks which are bringing MVC patterns to the front end, more and more dynamic the web apps are getting which in turn is increasing the use of DOM.

Problem: Typically when you want to update the DOM, we usually reload the DOM after updations, consider doing it hundreds of times during a page load you end up increasing the latency, and memory consumption.

Solution: Creating a Virtual DOM

A Virtual DOM is a copy of the original DOM on which components perform their updations and once all operations are done. This DOM will be compared to the snapshot of the previous virtual DOM to determine all the objects that are modified and only update those DOM objects in the real DOM (once). This process is called reconciliation.

Shadow DOM

The biggest problem working with DOM is Encapsulation. Let’s assume you have an h1 tag of your own for which you want to apply color and you are consuming a service which is returning an h1 tag as well for which you don’t want to apply your styles. How do you create a boundary between the code that you wrote and the code that will consume it?

By default, you can get this done with the help of iframes but they are heavy and restrictive which is a big drawback. Here comes the Shadow DOM for rescue.

Shadow DOM refers to the ability of the browser to include a subtree of DOM elements into the rendering of a document, but not into the main document DOM tree

<!DocTYPE html>
<html lang="en">

<head>
    <title>Test DOM</title>
    <style>
        h1 {
            color: Red;
        }
    </style>
</head>

<body>
    <h1>Lorem ipsum dolor sit amet consectetur adipisicing elit. Aliquid, cupiditate!</h1>
    <script src="script.js"></script>
    <script>
        const el = document.createElement('div');
        const shadowroot = el.attachShadow({ mode: 'open' });
        shadowroot.innerHTML = '<h1>Shadow DOM </h1>'

        const container = document.querySelector('body');
        container.appendChild(el);
        console.log(document.querySelectorAll('h1').length);
        console.log(document.querySelectorAll('h1')[0].textContent);

        console.log(el.shadowRoot.querySelectorAll('h1').length);
        console.log(el.shadowRoot.querySelectorAll('h1')[0].textContent);
    </script>
</body>

</html>

use cases include adding video, audio from a third party api to your blog.

How are Events propagated?

To keep things natural, events fired in shadow DOM subtree can be listened to in the document. For instance, if you click on the mute button in the audio element, your event listeners on an enclosing div would hear the click:

If you are asked to identify who fired the event, you’ll find out it was the audio element itself, not some button inside of it.

Why? because when crossing the shadow DOM boundary, the events are retargeted to avoid exposing things inside of the shadow subtree. this way you get to gear the events, fired from the shadow DOM, and the implementor gets to keep their details hidden from you.

Published inCS Fundamentals

Be First to Comment

Leave a Reply

Your email address will not be published. Required fields are marked *