2026-03-01|Formatting

JavaScript Performance Tips: Optimize Your Web Applications

Debouncing and Throttling

Control the rate of function execution:

// Debounce: wait until user stops typing
function debounce(fn, delay) {
  let timer;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => fn(...args), delay);
  };
}

// Throttle: execute at most once per interval
function throttle(fn, limit) {
  let inThrottle;
  return (...args) => {
    if (!inThrottle) {
      fn(...args);
      inThrottle = true;
      setTimeout(() => inThrottle = false, limit);
    }
  };
}

Efficient DOM Manipulation

Batch DOM Reads and Writes

// Bad: causes layout thrashing
elements.forEach(el => {
  const height = el.offsetHeight; // read
  el.style.height = height + 10 + 'px'; // write
});

// Good: batch reads, then batch writes
const heights = elements.map(el => el.offsetHeight);
elements.forEach((el, i) => {
  el.style.height = heights[i] + 10 + 'px';
});

Use DocumentFragment

const fragment = document.createDocumentFragment();
for (let i = 0; i < 1000; i++) {
  const li = document.createElement('li');
  li.textContent = `Item ${i}`;
  fragment.appendChild(li);
}
ul.appendChild(fragment); // Single DOM update

Memory Management

Avoid Memory Leaks

// Remove event listeners when no longer needed
function cleanup() {
  button.removeEventListener('click', handler);
}

// Avoid holding references to removed DOM nodes
let data = fetchData();
processData(data);
data = null; // Release reference

Efficient Iteration

// Use for...of instead of forEach for large arrays
const largeArray = new Array(100000).fill(0);

// Slower
largeArray.forEach((v, i) => { /* ... */ });

// Faster
for (const [i, v] of largeArray.entries()) { /* ... */ }

Lazy Loading

Images

<img loading="lazy" src="photo.jpg" alt="...">

Components (Vue Example)

const HeavyComponent = defineAsyncComponent(() =>
  import('./HeavyComponent.vue')
);

Web Workers for CPU-Intensive Tasks

// main.js
const worker = new Worker('worker.js');
worker.postMessage({ data: largeDataset });
worker.onmessage = (e) => updateUI(e.data);

// worker.js
self.onmessage = (e) => {
  const result = processLargeData(e.data);
  self.postMessage(result);
};

Performance Measurement

console.time('operation');
// ... perform operation
console.timeEnd('operation');

// Or use Performance API
performance.mark('start');
// ...
performance.mark('end');
performance.measure('operation', 'start', 'end');