How to Efficiently Append Elements Using jQuery
Appending thousands of elements to the DOM individually causes severe
performance bottlenecks due to repeated browser reflows and repaints.
This guide explains how to efficiently append a large number of elements
in jQuery by minimizing direct DOM interactions. You will learn the best
practices, including string accumulation, array joins, utilizing native
DocumentFragment objects, and passing element collections
directly into jQuery's .append() method.
The Problem: Appending in a Loop
The most common mistake is calling .append() inside a
standard loop:
// Inefficient: Triggers DOM reflow on every iteration
for (let i = 0; i < 5000; i++) {
$('#container').append('<div>Item ' + i + '</div>');
}Every time .append() executes directly against an
element currently rendered in the document, the browser recalculates the
layout (reflow) and re-renders the pixels (repaint). Doing this
thousands of times freezes the UI.
Method 1: HTML String Concatenation or Array Join
The fastest approach is building the entire HTML structure in memory
as a single string and calling .append() once.
Using Array Join
const items = [];
for (let i = 0; i < 5000; i++) {
items.push('<div>Item ' + i + '</div>');
}
$('#container').append(items.join(''));Using Template Literals
let html = '';
for (let i = 0; i < 5000; i++) {
html += `<div>Item ${i}</div>`;
}
$('#container').append(html);Both patterns limit the browser to a single reflow cycle, yielding immediate performance gains over standard loops.
Method 2: Passing an Array of jQuery or DOM Objects
If elements must be instantiated as objects to bind event handlers or attach arbitrary data before appending, collect them in an array first:
const elements = [];
for (let i = 0; i < 5000; i++) {
const $div = $('<div>', {
text: 'Item ' + i,
class: 'list-item'
}).on('click', function() {
console.log('Clicked item ' + i);
});
elements.push($div);
}
// Pass the entire array to a single append call
$('#container').append(elements);jQuery natively accepts an array of elements in a single
.append() call, batching the insertion into the
document.
Method 3: Using a Native DocumentFragment
A DocumentFragment is a lightweight, non-rendered DOM
container. It behaves like a standard DOM node, but operations performed
on it happen entirely offscreen in memory.
const fragment = document.createDocumentFragment();
for (let i = 0; i < 5000; i++) {
const div = document.createElement('div');
div.textContent = 'Item ' + i;
fragment.appendChild(div);
}
// Append the fragment via jQuery
$('#container').append(fragment);When a DocumentFragment is appended to the DOM, its
child nodes are transferred in one single operation without inserting
the fragment itself.
Method 4: Detaching the Parent Element
If you must modify an existing DOM node extensively, detach it from
the document tree first using .detach(), make the changes,
and then reinsert it.
const $container = $('#container');
// Temporarily remove from DOM while keeping jQuery data/events intact
const $detached = $container.detach();
for (let i = 0; i < 5000; i++) {
$detached.append('<div>Item ' + i + '</div>');
}
// Put it back into the DOM
$detached.appendTo('#parentWrapper');This prevents the browser from recalculating layouts while the container is being modified.
Summary of Best Practices
- Never call
.append()inside a loop directly on an active DOM element. - Use String Concatenation or
Array.join('')when elements are static HTML. - Use
DocumentFragmentor an array of elements when dynamic configuration or event binding is required prior to insertion. - Use
.detach()when performing extensive bulk updates on existing containers.