Interview question
How do you optimize DOM manipulation performance when updating many elements? कई elements update करते समय DOM manipulation performance कैसे optimize करें?
Answer
Direct DOM manipulation in a loop causes repeated reflow/repaint, which is expensive. Batching changes minimizes the number of times the browser needs to recalculate layout.
// SLOW - triggers a reflow on every iteration (100 separate DOM insertions)
const list = document.getElementById('list');
for (let i = 0; i < 100; i++) {
const li = document.createElement('li');
li.textContent = `Item ${i}`;
list.appendChild(li); // reflow happens 100 times
}
// FAST - use DocumentFragment to batch DOM insertions
const fragment = document.createDocumentFragment();
for (let i = 0; i < 100; i++) {
const li = document.createElement('li');
li.textContent = `Item ${i}`;
fragment.appendChild(li); // no reflow, fragment is off-DOM
}
list.appendChild(fragment); // single reflow for all 100 items
// FAST alternative - build HTML string and set once
let html = '';
for (let i = 0; i < 100; i++) {
html += `<li>Item ${i}</li>`;
}
list.innerHTML = html; // single reflow, but be cautious with untrusted data (XSS)
// AVOID - reading layout properties inside a loop that also writes (layout thrashing)
const boxes = document.querySelectorAll('.box');
boxes.forEach(box => {
const height = box.offsetHeight; // read forces layout calculation
box.style.height = height + 10 + 'px'; // write invalidates layout
// repeating this in a loop causes forced synchronous layout each iteration
});
// BETTER - separate all reads from all writes
const heights = Array.from(boxes).map(box => box.offsetHeight); // all reads first
boxes.forEach((box, i) => {
box.style.height = heights[i] + 10 + 'px'; // all writes after
});
// Using requestAnimationFrame for visual updates
function updateUI() {
requestAnimationFrame(() => {
// DOM updates synced with the browser's paint cycle
list.style.transform = 'translateX(100px)';
});
}Loop में direct DOM manipulation हर iteration पर reflow/repaint trigger करता है, जो expensive है। Changes को batch करने से browser को layout recalculate कम बार करना पड़ता है।
// धीमा - हर iteration पर reflow
const list = document.getElementById('list');
for (let i = 0; i < 100; i++) {
const li = document.createElement('li');
li.textContent = `Item ${i}`;
list.appendChild(li); // 100 बार reflow
}
// तेज़ - DocumentFragment से batch करना
const fragment = document.createDocumentFragment();
for (let i = 0; i < 100; i++) {
const li = document.createElement('li');
li.textContent = `Item ${i}`;
fragment.appendChild(li); // कोई reflow नहीं
}
list.appendChild(fragment); // सिर्फ एक reflow
// तेज़ alternative - HTML string बनाकर एक बार set करना
let html = '';
for (let i = 0; i < 100; i++) {
html += `<li>Item ${i}</li>`;
}
list.innerHTML = html;
// गलत - loop में reads और writes mix करना (layout thrashing)
const boxes = document.querySelectorAll('.box');
boxes.forEach(box => {
const height = box.offsetHeight; // read
box.style.height = height + 10 + 'px'; // write
});
// बेहतर - सभी reads पहले, सभी writes बाद में
const heights = Array.from(boxes).map(box => box.offsetHeight);
boxes.forEach((box, i) => {
box.style.height = heights[i] + 10 + 'px';
});Was this answer clear?