Feedback

Reduce JavaScript execution time

By Christian Schreiber ยท Updated

The Lighthouse finding Reduce JavaScript execution time measures how long the browser's main thread spends parsing, compiling and running the scripts a page loads. It is the lab-side view of the problem behind a slow Interaction to Next Paint: while the main thread executes JavaScript, it cannot respond to a tap, update a layout or paint. Unlike page weight, execution time scales with device speed, so a bundle that feels fine on a developer laptop can block a mid-range phone for seconds.

From PerfDelta's measurements: In the mobile lab test, 22% of 4,075 home pages have a good Total Blocking Time and 57% a poor one. The median is 771 ms, with the middle half between 245 ms and 1671 ms. More in the data section below.

What the audit measures

Lighthouse records every script the page loads and attributes three kinds of main-thread time to it: parsing and compiling the source, executing it, and the time spent in functions the script calls. The finding appears when the total exceeds two seconds in the mobile run, with the heaviest scripts listed by URL. The mobile run simulates a slowed CPU, which is why the numbers are several times larger than what you see on a desktop; that simulation is closer to the phones a large share of visitors use.

The related finding Minimize main-thread work breaks the same time down by category: script evaluation, style and layout, rendering, parsing HTML and CSS, garbage collection. If script evaluation dominates, this guide is the right place. If style and layout dominate, look at DOM size first.

Why execution time matters more than file size

Bytes cost time on the network once. Execution costs time on the device every time the page loads, and again for every interaction that triggers the same code. Two scripts of the same size can differ by a factor of ten in execution time: a library that builds a large data structure at startup, a framework that hydrates the whole page, or a tag manager that runs dozens of triggers on load all keep the main thread busy long after the download finished. This is why Total Blocking Time correlates with execution time far more than with transfer size.

How to reduce JavaScript execution time

1. Read the breakdown before touching code

Open the finding in PageSpeed Insights and sort by total CPU time. In most pages, two or three scripts account for most of the time, and at least one of them is third-party. Chrome DevTools gives the detailed view: record a performance profile with CPU throttling enabled, then use the bottom-up view grouped by script URL. Fix the biggest item first; the long tail rarely pays off.

2. Ship less code

Code that is not loaded cannot execute. Code splitting, tree shaking and removing dead dependencies are covered in Reduce unused JavaScript. Pay attention to large libraries pulled in for one function: a date library, a full charting package on a page with one chart, or a utility collection where three helpers are used.

3. Defer what the first screen does not need

Scripts for a chat widget, a cookie banner's analytics layer, below-the-fold carousels or a recommendation engine can run after the page is interactive. Load them with defer, on user intent (first scroll or first interaction) or with requestIdleCallback:

// Load a heavy widget only when the browser is idle after load
window.addEventListener('load', () => {
  (window.requestIdleCallback || setTimeout)(() => {
    import('./chat-widget.js');
  });
});

Moving work later does not reduce total execution time, but it moves it out of the window that decides Largest Contentful Paint and the first interactions.

4. Break up long tasks

Any single task over 50 milliseconds blocks input. A startup routine that initializes ten components in one go should yield between them so the browser can handle a tap in between:

async function init(components) {
  for (const component of components) {
    component.init();
    // Give the main thread a chance to respond to input
    await new Promise(resolve => setTimeout(resolve, 0));
  }
}

Where supported, scheduler.yield() does the same with better priority handling. This is the single most effective change for INP on pages that already load lean.

5. Reduce hydration cost in frameworks

React, Vue and similar frameworks re-run component code in the browser to attach event handlers to server-rendered HTML. On large pages that hydration is often the biggest single task. Server components (React), islands (Astro), partial or lazy hydration and smaller client bundles reduce it directly. The Next.js guide covers the framework-specific options.

6. Tame third-party scripts

Tag managers, A/B testing tools, session replay and ad scripts frequently sit at the top of the execution list. Audit which tags still have a purpose, consolidate duplicate trackers, load non-essential tags after interaction, and consider server-side tagging for analytics. The third-party code guide goes through this in detail.

7. Avoid expensive patterns

Some code is slow regardless of size: synchronous layout reads inside loops (forced reflow), large JSON parsed on startup, polyfills loaded for all browsers instead of only old ones, and animation loops that run while nothing is visible. The performance profile shows these as wide blocks with the same function name repeated.

Measuring progress

Compare the finding's total before and after each change, and watch Total Blocking Time in the lab and INP in the field. Lab numbers move immediately; field INP follows over the 28-day CrUX window as real visitors load the new version.

Frequently asked questions

Why is my execution time so much higher on mobile than on desktop?

The mobile Lighthouse run throttles the CPU to simulate a mid-range phone. The same script that takes 300 ms on a laptop can take over a second there. Real visitors on cheaper devices see similar numbers.

Does minifying or compressing JavaScript reduce execution time?

Only marginally. Both reduce transfer size, not the amount of code the engine has to parse and run. Removing and deferring code does.

Which scripts should I look at first?

The top two or three by total CPU time in the finding. One of them is usually a third-party tag; the other is often the main application bundle or framework hydration.

How does execution time relate to INP?

Long scripts block the main thread, so a tap that arrives during execution waits until it finishes. Reducing execution time and breaking long tasks are the two main levers for INP.

What PerfDelta's measurements show

In the mobile lab test, 22% of 4,075 home pages have a good Total Blocking Time and 57% a poor one. The median is 771 ms, with the middle half between 245 ms and 1671 ms.

PerfDelta does not store JavaScript execution time as a metric of its own; the Total Blocking Time of the mobile lab test shows the same load from the main thread's point of view.

By industry, the median ranges from 195 ms in Professional services to 1143 ms in Travel and hospitality.

Data as of October 16, 2026, recalculated daily. Source: PerfDelta's own measurements (Chrome UX Report and Lighthouse); details in the website speed statistics and the methodology.

Thresholds and sources

Lab test (Lighthouse):

Sources:

All sources retrieved on October 9, 2026. Thresholds and documentation change; the linked page is authoritative.

Test your site

Run a free scan to see whether this applies to your pages, on mobile and desktop, with lab and field data side by side.

Run a free test

A free account saves your tests and shows how your values change from one test to the next. Daily monitoring with field data and alerts starts with the Solo plan.

Related audits