SEO check

Reduce JavaScript Execution Time: How to Check and Fix It

What JavaScript execution time is, how our free report measures it, and the practical steps that bring a slow page under one second.

Free to use 12 min read Updated Oct 2026

Reduce JavaScript execution time in one minute

Quick answer: JavaScript execution time is how long the browser spends running your scripts, and our report measures the part that happens before the page is ready. To reduce JavaScript execution time you have to shrink or postpone that work. Our report flags anything above 1 second, and the usual cure is to remove or trim scripts, split large bundles, then let non-essential code run after the load event.

  • Pass: Execution Time of 1.0 s or less in our report.
  • Warning: Above 1 s and up to 3 s, which still opens the How to Fix button.
  • Fail: Above 3 s, or a missing value.
  • Fix: Remove unused scripts, split bundles, delay what the first screen doesn't need.

Check my website

One honest note before you compare numbers: our figure is a page-ready window, not the same measurement Lighthouse reports, and the section on how our test works below explains the difference.

What is JavaScript execution time?

Put simply, this is the time the browser's main thread spends parsing, compiling and running your code in the V8 JavaScript engine (or its equivalent). While that thread is busy it can't paint or answer a tap, a state called main thread blocking, so a script-heavy page feels stuck even when every file has already downloaded.

Download time is a separate problem. A small script with a heavy loop can cost more than a large library that mostly sits idle, so JavaScript payload alone tells you little. The cost usually comes from several places: your own bundles, jQuery plugins, a tag manager, ad code, chat widgets, analytics and social embeds.

In PageSpeed Insights you'll meet this topic as the Lighthouse audit called Reduce JavaScript execution time, which Lighthouse knows internally as bootup time. According to the Lighthouse source code, the audit turns orange above about 1.3 seconds and red above 3.5 seconds on its slowed mobile profile. The Lighthouse bootup time audit documentation page was last updated in 2019 and still quotes 2 seconds as the warning point, so don't be surprised when the two sources disagree.

Two neighbouring metrics are easy to mix up with it. Total Blocking Time adds up the part of every long task beyond 50 ms, where a long task is any single stretch of main thread work over 50 ms. Interaction to Next Paint measures how quickly the page reacts after a real click or tap. Execution time is the raw script cost behind both.

How our JavaScript execution time test works

Here is exactly what our report does, so you can judge the result and reproduce it yourself.

The exact rule: the report line called Execution Time shows domContentLoadedEventEnd minus responseStart, in seconds, rounded to two decimals. 1.0 s or less passes, above 1 s up to 3 s is a warning, and above 3 s fails.

The report loads your page in headless Chromium driven by Playwright inside a container, using the default desktop settings with no CPU or network throttling. It waits for the load event with a 20 second limit, then reads the Navigation Timing entry. Because the clock is wall time, the window also holds the time to receive the HTML, to download scripts that block or are deferred, and to wait for blocking stylesheets, not only the CPU time of your code.

What counts is the HTML parse plus every script that runs before the DOMContentLoaded event: classic, defer and module scripts, and async scripts when they happen to land before that event. What doesn't count is anything injected after load, on first interaction or when the browser is idle. That is exactly why postponing a script lowers our number.

What the report measures

The window starts at the first byte of the server response and ends when the DOMContentLoaded handlers finish. The entry comes from the Navigation Timing API (a PerformanceNavigationTiming object), and the domContentLoadedEventEnd on MDN page in the MDN Web Docs documents the property.

What pass, warning and fail mean

The limits are 1.0 s and 3.0 s. A warning shows a warning icon, and a fail shows an error icon, yet both open the same How to Fix button. The score treats each check as passed or not passed, so a warning costs exactly as many points as a fail, and only passed checks add to it.

Why it differs from Lighthouse

The clock and the window are different. Ours is plain wall time from the first server byte to DOMContentLoaded. Lighthouse sums script evaluation time and script parse time for every file, on a throttled phone profile. Treat our result as a quick yes or no, then open PageSpeed Insights for the per script list. Run the check twice, because server response time and third party hosts shift the figure a little between runs.

Scripts that start after load, long tasks, Interaction to Next Paint and per script CPU time are not tested here. When you're ready, run the free report on any page you care about.

What is a good JavaScript execution time?

It depends on which tool produced the number, because the three common ones use different clocks and units. Seconds in our report and milliseconds in Interaction to Next Paint are not interchangeable.

MeasureWhat it measuresGoodNeeds workPoor
SEO Site Checker checkWall time from server response to the end of DOMContentLoaded1.0 s or lessAbove 1 s up to 3 sAbove 3 s
Lighthouse bootup time auditScript evaluation plus parse time on a throttled mobile profileUp to about 1.3 sAbout 1.3 s to 3.5 sAbove 3.5 s
Interaction to Next PaintDelay before the page responds, from real visitors200 ms or less200 ms to 500 msAbove 500 ms

As a rule of thumb, aim for under 1 s in our report, then confirm the page in PageSpeed Insights.

Why JavaScript execution time matters for SEO and users

When the main thread is blocked, the first paint arrives later and taps feel ignored. That shows up as a poor Interaction to Next Paint and a high Total Blocking Time, two measures of how responsive the page really is. Our Core Web Vitals guide covers the wider set.

Your own laptop flatters you. A mid range phone can take several times longer to run the same script, so a desktop pass may still be a miss for real visitors.

Google Search Central treats speed as a light signal, and Core Web Vitals sit inside it, so don't expect a jump in position from one fix. The bigger payoff is fewer people leaving and more of them finishing what they came to do. The post on page speed and SEO explains how the two connect.

How to find which scripts take the most time

You don't need to guess. A short routine points at the files that deserve attention first.

Find heavy scripts in DevTools

  1. Run the report. Note the Execution Time value and its status, so you have a baseline to beat.
  2. Record a reload. Open Chrome DevTools, choose the Performance panel, start a recording with reload, then read the Bottom Up tab sorted by self time to see the heaviest scripts and functions.
  3. Check the Coverage tab. It shows how many bytes of each file never run on this page, which is a quick way to spot unused JavaScript. The Network panel, filtered to JS, shows which files are large and which hosts are third party.
  4. Open PageSpeed Insights. Read the Reduce JavaScript execution time table for script evaluation and parse time per file, then write down the three biggest names.

Reproduce the report number in the console

You can read the same entry our report uses. Paste this into the DevTools console after the page has finished loading. Expect a different value, because your browser has extensions and caches.

JavaScript
const nav = performance.getEntriesByType('navigation')[0];
const seconds = (nav.domContentLoadedEventEnd - nav.responseStart) / 1000;
console.log(seconds.toFixed(2) + ' s');

Time one function in code

If you suspect a single function, wrap it with performance.now() from the User Timing API before and after, or use console.time for a quick label. A PerformanceObserver can also log long tasks from the Long Tasks API in Chromium based browsers.

JavaScript
const start = performance.now();
buildMenu();
console.log('buildMenu took', (performance.now() - start).toFixed(1), 'ms');

new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    console.log('Long task', Math.round(entry.duration), 'ms');
  }
}).observe({ type: 'longtask', buffered: true });

A developer machine is much faster than a phone, so treat these timings as a ranking of suspects.

How to reduce JavaScript execution time, step by step

Work through these six fixes in order, since the first two usually deliver the most.

1. Remove scripts you do not need

Old plugins, abandoned tags and dead widgets keep running long after anyone looks at them. Delete what you can't justify, because the script you don't ship costs nothing.

2. Trim or replace third party scripts

Chat widgets, heatmaps, A/B testing tools and social embeds are common offenders, and you don't control their code. Keep the ones that earn their place and load tags only on the trigger that needs them. For video embeds, use a script facade: a static preview image that loads the real player on click.

3. Split bundles and load only what a page needs

A single large bundle makes every page pay for features it never uses, so watch your bundle size. Use code splitting with dynamic import(), let your bundler such as webpack drop dead code through tree shaking, and build route level bundles so each page loads its own code.

Why defer alone isn't enough: our check counts scripts that run before DOMContentLoaded, and deferred scripts do exactly that. Defer only overlaps the download with parsing, so it barely lowers the figure, while loading code after the load event does. Be careful about waiting for first interaction, because that moves the cost into Interaction to Next Paint.

4. Move non-critical work after the load event

Anything the first screen doesn't need can start after the page is ready, which is how you lazy load scripts and delay JavaScript safely. Create the script element inside a load listener, and our report no longer counts it because it begins after DOMContentLoaded. Our number will fall even though the device still runs the script, so a heavy late script still shows up as Total Blocking Time and Interaction to Next Paint in PageSpeed Insights.

HTML
<script>
  window.addEventListener('load', function () {
    var s = document.createElement('script');
    s.src = '/js/chat-widget.js';
    s.async = true;
    document.body.appendChild(s);
  });
</script>

5. Break up long tasks

One 400 ms loop blocks everything for 400 ms. Chunk it, and hand control back to the browser between chunks so clicks and paints can happen. The Optimize long tasks guide explains the pattern in depth. For truly heavy calculations, move the work into web workers, which run off the main thread.

The loop below uses the Scheduler API and yields with scheduler.yield where it exists (Chrome and Edge 129 and later, Firefox 142 and later, not Safari) and falls back to setTimeout everywhere else.

JavaScript
async function processItems(items) {
  let lastYield = performance.now();
  for (const item of items) {
    handle(item);
    if (performance.now() - lastYield > 40) {
      if (globalThis.scheduler && scheduler.yield) {
        await scheduler.yield();
      } else {
        await new Promise((resolve) => setTimeout(resolve, 0));
      }
      lastYield = performance.now();
    }
  }
}

6. Minify, compress and cache

Smaller files parse faster, but the gain is modest, so treat it as housekeeping. To minify JavaScript, run files through our free JavaScript Minifier, serve them with Brotli or gzip, and give them long cache lifetimes so repeat visits skip the download. Our JavaScript minification check covers file size, and the guide to minify HTML, CSS and JavaScript walks through the steps.

If scripts in the head hold up rendering as well, check the render blocking resources result next.

How to reduce JavaScript execution time in WordPress, Shopify and frameworks

The principles stay the same everywhere, but the switches live in different places.

WordPress

Audit your plugins and page builder add-ons such as Elementor, and delete anything unused. Then unload plugin scripts on pages that don't use them, using the per page unloading option of an asset manager plugin. Caching plugins usually offer a delay JavaScript execution setting (the label differs), but retest forms and checkout afterwards.

Shopify

Uninstalling Shopify apps often leaves code behind in the theme files. Go to Online Store, Themes, Edit code, then search theme.liquid and the snippets folder for the names of apps you removed, and delete the leftovers. In the theme editor, the App embeds tab lets you switch off embeds you don't need.

Next.js and React

Load heavy components with next/dynamic and keep client components small, which limits React hydration work. For third party scripts, next/script with the lazyOnload strategy waits for an idle browser.

Google Tag Manager

Delete unused tags and keep one tag per vendor. Fire non-essential tags on the Window Loaded trigger.

Common mistakes when cutting JavaScript time

Test after every change: deferring or delaying everything at once can silently break menus, forms and consent banners, and you won't know which change did it.

  • Delaying all scripts until first interaction. It hands the cost to Interaction to Next Paint and loses early analytics hits.
  • Trusting minification alone. It shrinks bytes, not the work the code performs.
  • Testing once, or while logged in as an admin. Admin sessions load extra scripts, and one run can be an outlier.
  • Comparing numbers from different tools. Our window from server response to DOMContentLoaded, Lighthouse CPU time and Interaction to Next Paint in milliseconds measure three different things, as the table above shows, so a gap between them is not a contradiction.
  • Adding an optimization plugin that ships its own heavy script. A minification or lazy loading plugin can inject its own loader script, so compare Execution Time before and after you install it.

How to Fix

The short version, the same steps you see when you click How to Fix in your report.

Why this fails: between the first byte of your server reply and the end of DOMContentLoaded, the browser needed more than 1 second (warning) or more than 3 seconds (fail). The check counts scripts that run before the page is ready, plus the time spent fetching them.

How to fix it:

  1. Find the heavy scripts. In Chrome DevTools, record a reload in the Performance panel, open Bottom Up and sort by self time. Check the Coverage tab for files that mostly never run, and write down the three biggest scripts.
  2. Remove unused plugins, old tags and dead widgets.
  3. Trim or replace third party scripts such as chat, heatmaps and social embeds.
  4. Split bundles so each page loads only its own code.
  5. Run non-critical scripts after the load event, using the pattern below.
  6. Break long tasks into smaller chunks, then minify the files.
HTML
<script>
  window.addEventListener('load', function () {
    var s = document.createElement('script');
    s.src = '/js/widget.js';
    document.body.appendChild(s);
  });
</script>

Adding defer on its own barely lowers this number, because deferred scripts still run before DOMContentLoaded.

  • WordPress: unload plugin scripts on pages that don't need them and use the delay option of your caching plugin.
  • Shopify: remove unused apps and the code they left in the theme files.
  • Google Tag Manager: fire non-essential tags on the Window Loaded trigger.
  • Next.js or custom code: use next/script with lazyOnload, or a dynamic import for heavy components.

Re-test: run our free report again and check that Execution Time reads 1.0 s or lower to pass, or 3 s or lower if you only need to leave the fail state. Run it twice, because the figure moves a little between runs, then confirm real visitor results in PageSpeed Insights. For the audit PageSpeed Insights uses, see the Lighthouse bootup time audit.

Re-test my website

Frequently Asked Questions

What JavaScript execution time is too slow?
In our report anything above 1 second is flagged: 1.0 s or less passes, up to 3 s warns and above 3 s fails. A warning costs the same score points as a fail, so aim for under 1 s on key pages such as the homepage.
How do I check my website's JavaScript execution time?
Run the free report and read the Execution Time value, then use the Chrome DevTools Performance panel or PageSpeed Insights for a per script breakdown. Developers can read the Navigation Timing entry in the console too, and a repeat run confirms the figure.
How do I reduce JavaScript execution time in WordPress?
Remove unused plugins and page builder add-ons first, then unload scripts on pages that do not need them and switch on the delay JavaScript setting of your caching plugin. Retest forms, menus and checkout afterwards.
How do I reduce JavaScript execution time in Shopify?
Remove unused apps and the code they left in theme files, choose apps built as theme app extensions and load widgets late. To find leftovers, open Online Store, Themes, Edit code and search the snippets folder.
Does JavaScript execution time affect Google rankings?
Indirectly. Slow scripts hurt responsiveness measures such as Interaction to Next Paint, which belongs to Core Web Vitals, and speed is a light ranking signal. Google reports Interaction to Next Paint from real Chrome users.
Is it safe to defer all JavaScript?
No. Defer analytics and chat widgets first, because they are the safest to move, and leave consent tools and above the fold features alone until tested. Do it in small groups so a broken menu or form is easy to trace.
Why is the time in your report different from PageSpeed Insights?
Because they measure different things. Ours is a wall clock window on an unthrottled desktop browser, while PageSpeed Insights sums script CPU time on a throttled mobile profile. The same page can also differ between runs because server response time changes.

See how your site scores right now

Paste your address into the free report, then use the How to Fix button on anything that needs work.

Free to use. Results in under a minute for most sites.