Update
5% faster than ALL examples
(including accepted answer)
The following example is from the Range API:
const rng = document.createRange();
rng.selectNodeContents(document.querySelector('ul'));
rng.deleteContents();
the Range interface deals with fragments of a Document that comprise of Nodes and Text. Although it appears slow, it's actually fast and 100% compatible with all browsers.
Range Methods
.createRange()
.selectNodeContents()
.deleteContents()
15% slower than All examples
This combo is faster than most examples and less verbose (with the exception of the Range demo being the fastest.)
document.querySelector('ul').replaceWith(document.createElement('ul'));
That's 2 DOM interactions: Find the list and replace it with an empty list. See Demo 1. If you want to support IE11 (ATM 2.26% global share) , then don't use it.
Demo 1
Range API
const rng = document.createRange();
rng.selectNodeContents(document.querySelector('ul'));
rng.deleteContents();
ul {
min-height: 30px;
min-width: 30px;
outline: 1px dashed red;
}
<ul>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
</ul>
Demo 2
.replaceWith()
and .createElement()
document.querySelector('ul').replaceWith(document.createElement('ul'));
ul {
min-height: 30px;
min-width: 30px;
outline: 1px dashed red;
}
<ul>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
</ul>
@50% slower than All examples
The best way to optimize any DOM manipulation is not to have them. Keep DOM access to a minimum -- it's very time consuming. Every time the JS engine looks for an element it will traverse the DOM tree, every time a tag is added or removed, the nodes (element, text, etc.) that are already in the DOM must be recalculated for positioning and dimensions so even if the number of nodes involved are just a few, it can domino into an exceptionally long process for the browser. This is called reflow and a similar problem involving CSS styles is called a repaint.
The following demo removes all
<li>
in a
<ul>
with 4 DOM operations:
References the <ul>
-- 1 lookup
Reference parent of <ul>
append an empty <ul>
-- 1 lookup, 1 addition
Create a documentFragment
and append original <ul>
to it -- 1 removal
.insertAdjacentHTML()
non-destructively renders htmlString
into HTML and it's highly optimized.
.createDocumentFragment()
never touches the DOM and whatever is attached to it is no longer touching the DOM.
Demo 3
.insertAdjacentHTML
and .createDocumentFragment()
// Reference the <ul>
const list = document.querySelector('ul');
// Reference parent of <ul> append an empty <ul>
list.parentElement.insertAdjacentHTML('beforeend', `<ul></ul>`);
// Create a document fragment and append original <ul> to it
document.createDocumentFragment().appendChild(list);
ul {
min-height: 30px;
min-width: 30px;
outline: 1px dashed red;
}
<ul>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
</ul>