Direct DOM manipulation has gotten a bad reputation in the last decade of web development. From Ruby on Rails to React, the DOM was seen as something to gloriously destroy and re-render from the server or even from the browser. Never mind that the browser already exerted a lot of effort parsing HTML and constructing this tree! Mind-numbingly complex HTML string regular expression tests and manipulations had to deal with low-level details of the HTML syntax to insert, delete and change elements, sometimes on every keystroke! Contrasting to that, functions like
insertBefore from the DOM world were largely unknown and unused, except perhaps in jQuery.
Processing of HTML is destructive: The original DOM is destroyed and garbage collected with a certain time delay. Attached event handlers are detached and garbage collected. A completely new DOM is created from parsing new HTML set via
.innerHTML =. Event listeners will have to be re-attached from the user-land (this is no issue when using
on* HTML attributes, but this has disadvantages as well).
It doesn’t have to be this way. Do not eliminate, but manipulate!
Save the (DOM) trees!
sanitize-dom crawls a DOM sub-tree (beginning from a given node, all the way down to its ancestral leaves) and filters and manipulates it non-destructively. This is very efficient: The browser doesn’t have to re-render everything; it only re-renders what has been changed (sound familiar from React?).
The benefits of direct DOM manipulation:
- Nodes stay alive.
- References to nodes (i.e. stored in a
WeakMap) stay alive.
- Already attached event handlers stay alive.
- The browser doesn’t have to re-render entire sections of a page; thus no flickering, no scroll jumping, no big CPU spikes.
- CPU cycles for repeatedly parsing and dumping of HTML are eliminated.
I just released version 4 of my sanitize-dom library which is my tool of choice to sanitize user-generated content. As mentioned in this post, my project takes a different approach: It doesn’t work with HTML, it operates only on DOM nodes.
sanitize-doms further advantages:
- No dependencies.
- Small footprint (only about 7 kB minimized).
- Faster than other HTML sanitizers because there is no HTML parsing and serialization.
Check out sanitize-dom here on Github!