Document Object Model (DOM): Definition, Tree, Manipulation
The DOM is the browser's tree representation of an HTML document. JavaScript reads + manipulates the DOM to update pages dynamically.
What is the Document Object Model (DOM)?
The Document Object Model (DOM) is the browser's in-memory representation of an HTML (or XML) document, structured as a tree of nodes. Every HTML element, attribute, and piece of text becomes a node. JavaScript uses the DOM API to read the structure, modify it, and respond to user events — that's how dynamic web pages work.
The DOM is a W3C standard, implemented by every browser. It's the bridge between HTML markup and JavaScript code: HTML defines the initial tree; JS reshapes it as the user interacts.
The DOM tree
Every HTML document becomes a tree:
<!DOCTYPE html>
<html>
<head><title>Hello</title></head>
<body>
<h1 id="title">Welcome</h1>
<p class="intro">Hi there!</p>
</body>
</html>Becomes a tree like:
document
└── html
├── head
│ └── title
│ └── "Hello" (text node)
└── body
├── h1#title
│ └── "Welcome" (text node)
└── p.intro
└── "Hi there!" (text node)Common DOM operations
Selecting elements
document.getElementById('title');
document.querySelector('.intro');
document.querySelectorAll('p');
document.getElementsByClassName('intro');
document.getElementsByTagName('h1');Reading content
const title = document.getElementById('title');
console.log(title.textContent); // "Welcome"
console.log(title.innerHTML); // "Welcome" (HTML)
console.log(title.id); // "title"Modifying content
title.textContent = 'Hello, world';
title.innerHTML = '<span>Bold</span>';
title.classList.add('highlighted');
title.setAttribute('data-id', '42');Creating + inserting elements
const newP = document.createElement('p');
newP.textContent = 'New paragraph';
document.body.appendChild(newP);
// Or insert at specific position
document.body.insertBefore(newP, document.querySelector('.intro'));Removing elements
const intro = document.querySelector('.intro');
intro.remove();
// Or older API:
intro.parentNode.removeChild(intro);Event handling
document.getElementById('btn').addEventListener('click', (event) => {
console.log('Clicked!', event.target);
});DOM node types
| Type | Description |
|---|---|
| Element | HTML elements (<div>, <p>, etc.) |
| Text | Text content inside elements |
| Comment | HTML comments |
| Document | The root document |
| DocumentFragment | Lightweight container for off-DOM building |
| Attribute | Element attributes |
Performance: DOM operations are expensive
DOM manipulation triggers reflow (layout recalculation) and repaint. Slow when overused. Optimization patterns:
- Batch DOM changes. One reflow per batch, not per change.
- Use DocumentFragment. Build off-DOM, then insert once.
- Read then write. Avoid "layout thrashing" (read-write-read-write triggers multiple reflows).
- Use CSS transforms for animation. No layout impact (vs animating
top,left). - Virtualize long lists. Render only visible items (react-window, etc.).
- Debounce/throttle event handlers. Especially scroll, resize.
Virtual DOM (React, Vue) vs real DOM
Frameworks like React maintain a "virtual DOM" — a JS object representation of the real DOM. When state changes:
- Compute new virtual DOM
- Diff against previous virtual DOM
- Apply minimal real DOM changes
This batches and minimizes real DOM operations, often resulting in faster apps. Modern frameworks (Svelte, Solid) skip the virtual DOM entirely and compile to direct DOM updates.
DOM events
Events bubble up from the target element to the document root (default), or capture down (with { capture: true }). Common events:
| Event | Triggered by |
|---|---|
click | Mouse click on element |
input / change | Form field updates |
submit | Form submission |
keydown / keyup | Keyboard interaction |
scroll | Scrolling |
resize | Window resize |
load / DOMContentLoaded | Page load events |
mouseover / mouseout | Mouse hover |
DOM best practices
- Cache DOM lookups. Don't
document.getElementByIdin a loop; store the reference. - Use event delegation. One listener on parent vs many on children.
- Prefer textContent over innerHTML. Avoids XSS; faster.
- Use classes, not inline styles. CSS handles, JS toggles class.
- requestAnimationFrame for visual updates. Sync with browser paint.
- Disconnect observers. MutationObserver, IntersectionObserver — clean up.
- Avoid forced synchronous layout. Read all measurements before any writes.
Common DOM pitfalls
- innerHTML with user input. XSS vulnerability. Use textContent.
- Layout thrashing. Reading offsetHeight then writing height in a loop = reflow on every read.
- Memory leaks. Detached DOM nodes still referenced by JS.
- Many small DOM updates. Each triggers reflow. Batch with DocumentFragment.
- Listening on every child. Use event delegation on parent.
- document.write. Slow + blocks parser. Don't use.
- Synchronous DOM in scroll handler. Janks scrolling.
FAQ: Document Object Model
Is the DOM the same as HTML?
No. HTML is the source markup. The DOM is the browser's in-memory tree representation, parsed from the HTML. JS interacts with the DOM, not the HTML text.
What's the difference between DOM and BOM?
DOM = the document tree. BOM (Browser Object Model) = the browser itself: window, navigator, history, location.
Why is DOM manipulation slow?
DOM changes trigger reflow + repaint, which the browser must do synchronously. Many small changes = many reflows. Batch them.
Why do React/Vue use a virtual DOM?
To minimize expensive real DOM operations by computing diffs and applying changes in batches.
What's the "Shadow DOM"?
An encapsulated DOM tree attached to an element (used by Web Components). Styles/scripts don't leak in/out.
How do I prevent XSS in DOM operations?
Use textContent instead of innerHTML for user-supplied content. Sanitize HTML if you must use innerHTML (DOMPurify).
What's MutationObserver?
An API to observe DOM changes. Useful for libraries that need to react to dynamic content.
Test DOM-heavy app performance with LoadFocus
LoadFocus runs Lighthouse audits from 25+ regions, measuring main-thread blocking from heavy DOM work and INP. Sign up free at loadfocus.com/signup.
Related LoadFocus Tools
Put this concept into practice with LoadFocus — the same platform that powers everything you just read about.