Deep Dive12 min read · Updated 2025-06-01

JavaScript Performance Optimization: What Actually Makes Code Fast

Most performance advice is about symptoms. This guide targets causes — how V8 compiles your code, why layout thrashing is expensive, and which optimizations move the needle vs which are cargo cult.

💡 Practice these concepts interactively with AI feedback

Start Practicing →

JavaScript Performance Optimization

Debounce — Implement from Scratch

function debounce(fn, delay) {
  let timer
  return function(...args) {
    clearTimeout(timer)
    timer = setTimeout(() => fn.apply(this, args), delay)
  }
}

// Usage: search input autocomplete const search = debounce((query) => fetchResults(query), 300) input.addEventListener('input', e => search(e.target.value))

Fires ONCE after user stops typing for 300ms.

Throttle — Implement from Scratch

function throttle(fn, interval) {
  let lastTime = 0
  return function(...args) {
    const now = Date.now()
    if (now - lastTime >= interval) {
      lastTime = now
      fn.apply(this, args)
    }
  }
}

// Usage: scroll event handler window.addEventListener('scroll', throttle(updateNav, 100))

Fires at most once per 100ms regardless of scroll speed.

Memory Leaks

Forgotten intervals:

const id = setInterval(() => update(), 1000) // When done: clearInterval(id)

Detached DOM nodes:

let ref = document.createElement('div') document.body.appendChild(ref) document.body.removeChild(ref) // ref still holds the node in memory! ref = null // fix: release the reference

Closures over large objects:

function leaky() {   const bigData = new Array(1_000_000).fill('*')   return () => bigData[0] // keeps ALL of bigData alive! } function fixed() {   const bigData = new Array(1_000_000).fill('*')   const first = bigData[0]   return () => first // only keeps 'first' }

Reflow vs Repaint

Repaint: visual change only (color). Cheaper. Reflow: geometry change (width, height, position). Cascades — expensive.

// ❌ Layout thrashing (alternating read/write = N reflows)
for (let i = 0; i < 100; i++) {
  const h = el.offsetHeight   // READ — forces layout
  el.style.height = h + 1 + 'px'  // WRITE — invalidates layout
}

// ✅ Batch reads then writes (1 reflow) const h = el.offsetHeight for (let i = 0; i < 100; i++) { el.style.height = (h + i) + 'px' }

// ✅ Best: CSS transforms — composited on GPU (no reflow at all) el.style.transform = 'translateY(10px)'

Practice performance questions at [JSPrep Pro](/auth).

📚 Practice These Topics
Arrays
8–12 questions
Performance
6–10 questions
Event loop
6–10 questions
Async await
5–8 questions

Put This Into Practice

Reading articles is passive. JSPrep Pro makes you actively recall, predict output, and get AI feedback.

Start Free →Browse All Questions

Related Articles

Core Concepts
map() vs forEach() in JavaScript: Which One to Use and Why It Matters
7 min read
Core Concepts
Arrow Functions vs Regular Functions in JavaScript: 6 Key Differences
9 min read
Interview Prep
Promise.all vs allSettled vs race vs any: The Complete Comparison
9 min read