DOM Performance

  • This lesson explains performance best practices for DOM operations.
  • Introduction to DOM Performance

    The DOM (Document Object Model) represents the structure of a web page.
    Whenever JavaScript interacts with HTML elements, it interacts through the DOM.

    While DOM manipulation is powerful, it is also expensive in terms of performance.

    Poor DOM handling can cause:

    • Slow websites

    • Laggy user interface

    • Screen flickering

    • High CPU usage

    • Bad user experience

    This lesson focuses on:

    • Traversing the DOM efficiently

    • Optimizing DOM manipulation

    • Avoiding reflow and repaint

    • Maintaining a clean DOM structure

      DOM Traversing

      What is DOM Traversing ?

      DOM Traversing means moving through the DOM tree to access elements based on their relationship.

      JavaScript allows us to navigate:

      • Parent elements

      • Child elements

      • Sibling elements

      Why DOM Traversing is Important ?

      • Access elements without re-querying the DOM

      • Improve performance

      • Write cleaner and faster code

      • Avoid unnecessary DOM searches

    • Common DOM Traversing Properties

      Parent Traversing

      element.parentElement

    Access Parent Element Using parentElement

    Retrieves the parent node of a selected element in the DOM

    let item = document.getElementById("child");
    
    console.log(item.parentElement); // parent element
    • Child Traversing

      element.children

      element.firstElementChild

      element.lastElementChild


    Access Child Elements in DOM

    Retrieves child elements using children, firstElementChild, and lastElementChild

    let container = document.getElementById("box");
    
    // All child elements
    console.log(container.children);
    
    // First child
    console.log(container.firstElementChild);
    
    // Last child
    console.log(container.lastElementChild);
    • Sibling Traversing

      element.nextElementSibling

      element.previousElementSibling

    Access Sibling Elements in DOM

    Retrieves next and previous sibling elements of a selected node

    let current = document.getElementById("item");
    
    // Next sibling
    console.log(current.nextElementSibling);
    
    // Previous sibling
    console.log(current.previousElementSibling);
    • Best Practice for DOM Traversing

      Instead of repeatedly using:

      document.getElementById("box").children[0]

      Store the element once:

      let box = document.getElementById("box");

      let firstChild = box.children[0];

      This improves performance.

      Optimizing DOM Manipulation

      Why DOM Manipulation is Expensive

      Each DOM change may cause:

      • Layout recalculation

      • Style recalculation

      • Repaint or reflow

      Frequent DOM changes slow down performance.

    Avoid Repeated DOM Updates for Better Performance

    Shows how frequent DOM changes can slow down your application

    // Bad Practice: Multiple DOM updates
    let list = document.getElementById("list");
    
    for (let i = 1; i <= 5; i++) {
      list.innerHTML += `<li>Item ${i}</li>`; // updates DOM repeatedly
    }
    • Optimized Approach: Use a Single Update

    Optimize DOM Updates Using Single Render

    Improves performance by updating the DOM only once instead of multiple times

    let list = document.getElementById("list");
    
    let content = "";
    
    for (let i = 1; i <= 5; i++) {
      content += `<li>Item ${i}</li>`;
    }
    
    // Single DOM update
    list.innerHTML = content;
    • DOM is updated only once.

      Use DocumentFragment for Better Performance

    Improve Performance Using DocumentFragment

    Minimizes DOM reflows by batching updates before inserting into the DOM

    let fragment = document.createDocumentFragment();
    let list = document.getElementById("list");
    
    for (let i = 1; i <= 5; i++) {
      let li = document.createElement("li");
      li.textContent = `Item ${i}`;
      fragment.appendChild(li);
    }
    
    // Single DOM insertion
    list.appendChild(fragment);
    • This minimizes reflows.

      Avoiding Reflow & Repaint

      What is Reflow ?

      Reflow occurs when the browser recalculates:

      • Element size

      • Position

      • Layout

      Triggered by:

      • Changing width/height

      • Adding or removing elements

      • Changing font size

      What is Repaint ?

      Repaint occurs when visual styles change but layout stays the same.

      Triggered by:

      • Changing color

      • Background

      • Visibility

      Why Reflow is More Expensive Than Repaint

      • Reflow affects layout

      • Reflow may trigger repaint

      • Multiple reflows cause lag

    Avoid Multiple Style Changes to Prevent Reflow

    Shows how repeated style updates can trigger costly layout recalculations

    let box = document.getElementById("box");
    
    // Bad Practice: multiple style changes
    box.style.width = "200px";
    box.style.height = "200px";
    box.style.backgroundColor = "red";
    • Each line may trigger reflow or repaint.

      Optimized Approach: Use CSS Class

    Optimize Styling Using CSS Classes

    Applies multiple styles efficiently using a single class instead of multiple inline changes

    <!-- CSS -->
    <style>
    .active {
      width: 200px;
      height: 200px;
      background-color: red;
    }
    </style>
    
    <script>
    // JavaScript
    let box = document.getElementById("box");
    
    box.classList.add("active");
    </script>
    • Avoid Layout Thrashing

    Avoid Layout Thrashing in DOM Updates

    Prevents performance issues caused by repeated read and write operations on layout

    // Bad example: read + write causes layout thrashing
    let width = box.offsetWidth;
    
    box.style.width = (width + 10) + "px";
    • Better approach:

      • Read values first

      • Write changes later

      Clean DOM Structure

      What is a Clean DOM Structure ?

      A clean DOM means:

      • Minimal nesting

      • No unnecessary elements

      • Clear hierarchy

      • Semantic HTML

      Why Clean DOM Improves Performance

      • Faster DOM traversal

      • Less memory usage

      • Easier rendering

      • Better maintainability

    implify DOM Structure for Better Performance

    Reduces unnecessary nesting to improve readability and rendering performance

    <!-- Bad DOM Structure -->
    <div>
      <div>
        <div>
          <span>Text</span>
        </div>
      </div>
    </div>
    
    <!-- Improved Clean Structure -->
    <div>
      <span>Text</span>
    </div>
    • Remove Unused Elements

      Unused or hidden elements still:

      • Consume memory

      • Increase DOM size

      • Slow down rendering

      Remove them when not needed.

    Use Semantic HTML for Better Structure

    Improves readability and accessibility by using meaningful HTML tags

    <!-- Non-semantic -->
    <div class="header"></div>
    <div class="footer"></div>
    
    <!-- Semantic -->
    <header></header>
    <footer></footer>
    • Semantic HTML improves performance and readability.

      General DOM Performance Best Practices

      • Cache DOM elements

      • Minimize DOM updates

      • Batch changes together

      • Use class toggling

      • Avoid deep nesting

      • Remove unused nodes

      • Prefer CSS over JavaScript animations

      Common Mistakes

      • Manipulating DOM inside loops repeatedly

      • Querying DOM multiple times

      • Using innerHTML unnecessarily

      • Ignoring performance impact

      • Creating deeply nested HTML

      Impact of Poor DOM Performance

      • Slow scrolling

      • Laggy animations

      • Delayed clicks

      • Poor SEO

      • High bounce rate