Performance Optimisation
Making JavaScript faster — measuring before optimising, common bottlenecks, V8 engine hints, lazy loading, and memory management.
What it is, in plain English: Performance optimisation in JavaScript starts with measurement — you can't know what to fix until you know what's slow. The three main performance concerns are: runtime speed (how fast code executes), load time (how fast the page becomes interactive), and memory (avoiding leaks). The first rule: measure first, optimise second. Premature optimisation adds complexity without guaranteed benefit.
Measure first, then fix
The first rule of performance: measure before optimising.
Making guesses about what's slow is almost always wrong. Use the profiler —
then fix what the data says is slow.
Measuring performance
// console.time / timeEnd — easiest way to measure a block:
console.time("data processing");
const result = processData(largeArray);
console.timeEnd("data processing");
// "data processing: 234.5ms"
// performance.now() — more precise, good for comparisons:
const start = performance.now();
doSomethingExpensive();
const elapsed = performance.now() - start;
console.log(`Took ${elapsed.toFixed(2)}ms`);
// Browser DevTools — Performance tab (the real tool):
// 1. Open DevTools → Performance tab
// 2. Click Record → do the slow thing → Stop
// 3. See a flame chart: which functions took the most time
// 4. Fix the slowest ones first (biggest blocks in the chart)Debounce and throttle — the two most impactful optimisations
// DEBOUNCE — wait until user stops doing something
// Use for: search input, form validation, resize handlers
function debounce(fn, delay) {
let timer;
return function(...args) {
clearTimeout(timer);
timer = setTimeout(() => fn.apply(this, args), delay);
};
}
const handleSearch = debounce((query) => {
fetch(`/api/search?q=${query}`); // only fires 300ms after user stops typing
}, 300);
searchInput.addEventListener("input", (e) => handleSearch(e.target.value));
// THROTTLE — run at most once per interval
// Use for: scroll events, mouse moves, window resize
function throttle(fn, interval) {
let lastTime = 0;
return function(...args) {
const now = Date.now();
if (now - lastTime >= interval) {
lastTime = now;
fn.apply(this, args);
}
};
}
const handleScroll = throttle(() => updateScrollIndicator(), 100);
window.addEventListener("scroll", handleScroll);
// Max 10 updates per second, no matter how fast the user scrollsAvoiding common slow patterns
// ✗ Slow — querying DOM inside a loop:
for (let i = 0; i < items.length; i++) {
document.querySelector(".list").appendChild(createItem(items[i])); // reflows each time!
}
// ✓ Fast — build once, insert once:
const fragment = document.createDocumentFragment();
items.forEach(item => fragment.appendChild(createItem(item)));
document.querySelector(".list").appendChild(fragment); // one reflow
// ✗ Slow — reading layout properties inside a write loop (layout thrashing):
elements.forEach(el => {
const h = el.offsetHeight; // forces layout recalculation
el.style.height = h + 10 + "px"; // then writes
});
// ✓ Fast — read all, then write all:
const heights = elements.map(el => el.offsetHeight); // read phase
elements.forEach((el, i) => el.style.height = heights[i] + 10 + "px"); // write phase
Try It Yourself
Official Sources
- MDN Web Docs — Performance
- web.dev — Performance
- Chrome DevTools — Performance Features Reference
- MDN Web Docs — Web Workers API
The Codex links only to official documentation and the ECMAScript specification. No third-party tutorials.