Fast JavaScript = Happy Users
Performance matters more than you think.
DOM Manipulation
// Bad - multiple reflows
for (let i = 0; i < 1000; i++) {
container.innerHTML += `<div>${i}</div>`
}
// Good - single reflow
const html = Array.from({length: 1000}, (_, i) => `<div>${i}</div>`).join('')
container.innerHTML = html
// Better - document fragment
const fragment = document.createDocumentFragment()
for (let i = 0; i < 1000; i++) {
const div = document.createElement('div')
div.textContent = i
fragment.appendChild(div)
}
container.appendChild(fragment)
Event Handling
// Bad - handler on every item
items.forEach(item => {
item.addEventListener('click', handleClick)
})
// Good - event delegation
container.addEventListener('click', (e) => {
if (e.target.matches('.item')) {
handleClick(e)
}
})
Debounce and Throttle
// Debounce - wait until user stops
function debounce(fn, delay) {
let timeout
return (...args) => {
clearTimeout(timeout)
timeout = setTimeout(() => fn(...args), delay)
}
}
// Usage: search input
input.addEventListener('input', debounce(search, 300))
// Throttle - limit frequency
function throttle(fn, limit) {
let waiting = false
return (...args) => {
if (!waiting) {
fn(...args)
waiting = true
setTimeout(() => waiting = false, limit)
}
}
}
// Usage: scroll handler
window.addEventListener('scroll', throttle(handleScroll, 100))
Lazy Loading
// Images
<img loading="lazy" src="image.jpg">
// Code splitting (dynamic imports)
button.addEventListener('click', async () => {
const { heavyFunction } = await import('./heavy-module.js')
heavyFunction()
})
Measure First
console.time('operation')
doSomething()
console.timeEnd('operation')
// Or Performance API
performance.mark('start')
doSomething()
performance.mark('end')
performance.measure('operation', 'start', 'end')
Use DevTools Performance tab for real profiling.
