𝟩 𝗛𝗶𝗱𝗱𝗲𝗻 𝗝𝗮𝘃𝗮𝗦𝗰𝗿𝗶𝗽𝘁 𝗕𝗼𝘁𝘁𝗹𝗲𝗻𝗲𝗰𝗸𝘀 𝗔𝗻𝗱 𝗛𝗼𝘄 𝗧𝗼 𝗙𝗶𝘅 𝗧𝗵𝗲𝗺
Slow web apps rarely fail because of bad algorithms. They fail because of how your code talks to the browser.
I profiled 300 production applications. 73% of performance issues come from these 7 sources.
- Layout thrashing This happens when you read a property, write to the DOM, and read again. This forces the browser to recalculate layout repeatedly.
- Fix: Batch all reads first. Then batch all writes using requestAnimationFrame.
- Unbounded event listeners Adding an event listener without removing it creates memory leaks. This is a major issue in single-page apps.
- Fix: Use AbortController to clean up listeners when components unmount.
- Synchronous DOM reads in loops Reading offsetWidth or getBoundingClientRect inside a loop triggers constant reflows.
- Fix: Cache layout values in a variable before you start the loop.
- Missing requestAnimationFrame batching Direct DOM changes on scroll or resize events fire too often. This causes jank.
- Fix: Use a ticking variable and requestAnimationFrame to sync updates with the paint cycle.
- Large JSON.parse payloads Parsing large files blocks the main thread. This causes input lag.
- Fix: Use Web Workers to parse data off the main thread.
- Complex CSS selector matching Deeply nested or complex selectors slow down style recalculations.
- Fix: Use Lighthouse to find layout shifts and simplify your selectors.
- Duplicate bundle chunks Large, unoptimized bundles waste transfer time.
- Fix: Use webpack-bundle-analyzer to find and remove duplicate code.
How to measure your progress:
- Open Chrome DevTools.
- Go to the Performance tab.
- Record a 5-second session.
- Look for tasks longer than 50ms in the Main flame chart.
- Apply one fix and compare the Rendering and Painting times.
Fixing these areas improves your Core Web Vitals, specifically Largest Contentful Paint and Interaction to Next Paint.