Skip to main content

Main Thread Work.

Performance Core Web Vitals & Page Load

Total main thread activity — parsing, compiling, painting. Keep under 4s

What does this check test?

This check measures the total time spent on the browser's main thread during page load, encompassing all categories of work: JavaScript evaluation, style calculations, layout, paint, compositing, HTML parsing, garbage collection, and other browser tasks. Lighthouse flags pages where total main thread work exceeds 4 seconds. Unlike JS Execution Time which only measures JavaScript, this metric captures the full picture of main thread utilization including the cascade effects of JavaScript on layout and painting.

Why does it matter?

The main thread is the single most critical bottleneck in browser performance — it handles JavaScript execution, DOM/CSSOM construction, layout computation, painting, and user input processing. When any of these tasks takes too long, the browser cannot respond to user interactions. High main-thread work results in poor TBT, delayed TTI, and input lag that users perceive as the site being slow or broken. Understanding the breakdown of main-thread work (how much is script vs. layout vs. paint) is essential for targeted optimization — reducing JavaScript alone does not help if excessive layout thrashing is the real problem.

Who is affected?

Sites with complex layouts (many DOM elements, deeply nested structures), heavy use of CSS animations and transitions, frequent DOM manipulation (infinite scroll, real-time updates), and large component trees that trigger cascading layout recalculations are most affected. Dashboards, data tables, social media feeds, and interactive web applications typically have the highest main-thread utilization.

Where does this apply?

Chrome DevTools Performance panel provides a complete breakdown of main-thread work by category in the Summary tab. The Main thread flame chart shows a timeline of all tasks. Key categories: Script (JS execution), Rendering (style calculation + layout), Painting (paint + compositing), System (browser internal tasks), and Idle (time available for user input). Focus optimization efforts on the largest category first.

How to fix it

For JavaScript-heavy pages: apply all JS execution time optimizations (code splitting, deferral, Web Workers). For layout-heavy pages: reduce DOM size (aim for under 1,500 nodes), avoid forced synchronous layouts by batching DOM reads before writes. Batch DOM reads and writes to avoid layout thrashing:
js
// Bad — triggers layout on every iteration
elements.forEach(el => {
  const height = el.offsetHeight; // read (forces layout)
  el.style.height = height + 10 + 'px'; // write
});

// Good — batch reads, then writes
const heights = elements.map(el => el.offsetHeight);
requestAnimationFrame(() => {
  elements.forEach((el, i) => {
    el.style.height = heights[i] + 10 + 'px';
  });
});
Skip rendering off-screen content with content-visibility:
css
section {
  content-visibility: auto;
  contain-intrinsic-size: 0 500px;
}
For paint-heavy pages: use `will-change` on animated elements to promote them to compositor layers, prefer `transform` and `opacity` for animations (these skip layout and paint), and reduce paint area with `contain: paint`. Reduce style calculation cost by keeping CSS selectors simple and reducing the total number of CSS rules.

References

AppVet checks Main Thread Work automatically

Run a free performance scan and get a full report with actionable fixes, including a Fix with AI prompt you can paste into any coding tool.

Run Audit