Reduce main-thread work: where the time goes

The main thread parses, styles, lays out, paints and runs scripts. How to see where its time goes, what Lighthouse flags, and the fix for each kind of work.

IntermediateHow-to6 min readUpdated October 30, 2026

In this guide
  1. What the main thread does
  2. What Lighthouse reports
  3. See your own breakdown
  4. The fix for each kind of work
    1. Style and layout in a little more detail
    2. Animations
  5. A worked example
  6. Mistakes to avoid
  7. Check your own page
  8. Sources

What the main thread does

MDN describes the path from code to pixels as the critical rendering path. The browser turns the HTML into the Document Object Model (DOM) and the CSS into the CSS Object Model (CSSOM). It combines the two into a render tree that holds the visible content and its styles. Then it works out the size and position of everything, which is layout, and finally paints the pixels.

JavaScript sits in the middle of all this. A script can add or remove elements, change styles and ask for measurements, which sends the browser back to earlier steps. Input events, timers and network callbacks run on the same thread.

Two things follow:

What Lighthouse reports

Lighthouse 13.5 measures main-thread work with several diagnostics. None of them counts towards the performance score, which takes this work into account only through Total Blocking Time. They are leads.

AuditWhat it showsHow it scores
Minimize main-thread workThe time spent in each group of work90 at about 2.0 seconds, 50 at 4.0 seconds
Reduce JavaScript execution timeFor each script of 50 milliseconds or more: total time, running it, and parsing and compiling it90 at about 1.3 seconds, 50 at 3.5 seconds
Avoid long main-thread tasksThe 20 longest tasks of 50 milliseconds or more, with the script behind eachA list, no score
Optimize DOM sizeThe biggest layout and style updates, with the size of the DOMInformational
Forced reflowThe functions that asked for a measurement right after changing the pageFails when any are found
Avoid non-composited animationsAnimations that the browser could not hand to the graphics processorInformational

The groups in the first audit are:

The lab test slows the processor down four times to imitate a mid-range phone, so these numbers are bigger than you would see on a fast laptop. That is intended. The numbers are best used to compare one group with another and one test with another.

See your own breakdown

In the report. Open Minimize main-thread work and read the table. Then open Reduce JavaScript execution time to see which scripts are responsible, and notice whether their time is in running the code or in parsing and compiling it.

In Chrome DevTools. Record a page load in the Performance panel. The recording can be filtered by four kinds of activity, Loading, Scripting, Rendering and Painting, by switching the checkboxes off, so you can see how much of the recording each one takes up. Click a long task and read its call tree to see which function is behind it. The Lighthouse guide shows how to save a trace to compare later.

For real visitors. Interaction to Next Paint shows how often the main thread is too busy to answer. See the INP guide.

The fix for each kind of work

Largest groupUsual causeWhat to do
Script EvaluationBig bundles, frameworks, tag managers, third-party scriptsSend less code (unused code), delay or remove scripts from other companies (third-party scripts), use defer (script loading), and break up what is left (long tasks), or move heavy work that does not touch the page to a web worker
Script Parsing & CompilationLarge files, code that is duplicated or written for old browsersSmaller bundles, split by page, and drop code that modern browsers do not need (bundle size and code splitting)
Style & LayoutA large DOM, complicated selectors, scripts that force layoutFewer elements, simpler styles, and measurement and changes kept apart
RenderingLarge images to decode, heavy effects, animations that cannot use the graphics processorResize images (image optimization), animate only transform and opacity
Parse HTML & CSSVery large HTML pages, very large style sheetsSmaller documents, CSS for the page only
Garbage CollectionCode that creates many short-lived objectsAllocate less, reuse objects

Style and layout in a little more detail

The web.dev article on style calculation says that, roughly, half of the time Chrome's engine spends on a computed style goes to matching selectors and half to building the resulting style. The worst-case cost is the number of elements multiplied by the number of rules, because each element must be checked against each rule. The practical advice is to reduce the number of elements that a change invalidates, and to keep selectors simple.

Layout is almost always scoped to the whole document, and larger DOMs generally cost more to lay out. web.dev warns against forced synchronous layout. This happens when a script changes a style and then asks for a measurement such as offsetHeight. To answer, the browser must first apply the change and lay the page out. In a loop it repeats for every item. The fix is to read all the measurements first, then make all the changes. Lighthouse's Forced reflow insight points at the functions that cause it. See DOM size and rendering costs.

Animations

MDN explains that properties that change an element's geometry or position cause style recalculation, layout and repaint. Properties that only change appearance cause recalculation and repaint. A few, such as transform and opacity, can be handled in their own layer and cost only the recalculation. That is why moving things with transform is smoother than changing top or left. Lighthouse's Avoid non-composited animations audit warns that animations which are not composited can be janky and increase layout shift.

A worked example

Suppose a report on a phone shows 4.8 seconds of main-thread work. These numbers are made up to show the method. Script Evaluation takes 2.9 seconds, Style & Layout 0.9, Script Parsing & Compilation 0.5, Rendering 0.3, and the rest 0.2.

The biggest group is Script Evaluation, so the first question is which scripts. In Reduce JavaScript execution time the table shows a tag manager script with 1.1 seconds, the main bundle with 0.9 and a chat widget with 0.6. That points to three decisions:

  1. Is the chat widget needed on every page? If not, load it only on the contact page, or after a click.
  2. What does the tag manager load? Remove the tags that nobody looks at.
  3. How much of the main bundle runs on this page? If most of it belongs to other pages, split it.

After those changes the test is run again, five times, with the median taken. See why scores change. The Style & Layout group at 0.9 seconds comes second. It is not worth touching until the larger one is dealt with.

Mistakes to avoid

Check your own page

Run the free audit and open the main-thread work and JavaScript execution time lists. Note the biggest group and the three biggest scripts. The total blocking time guide explains how the same work turns into the lab number that counts towards the score.

Sources

Start here

Free website audit

Live Google data for any public page: mobile and desktop.

Mobile + desktop · Lighthouse lab test · Real-user Chrome data when Google has it

Rather have this done for you? Speed optimization · Book a call

Related guides

All guides →