How to Reduce Total Blocking Time in WordPress (and Improve INP)

What Total Blocking Time is, how it relates to INP, and a practical process to reduce it in WordPress: find long tasks, cut and delay JavaScript, tame third-party scripts and page builders.

To reduce Total Blocking Time in WordPress, find the long JavaScript tasks with Chrome DevTools or Lighthouse, remove scripts you do not need, load the rest only on pages that use them, defer or delay non-critical scripts, and replace heavy third-party widgets with lighter options. TBT is a lab metric; the real-user measure it predicts is INP.

This is part of my speed series; start with the Core Web Vitals guide for context.

What is Total Blocking Time?

Total Blocking Time measures how long the browser’s main thread was too busy to respond during page load. Any task longer than 50 ms is a “long task,” and the time beyond 50 ms counts as blocking. TBT adds up those blocking portions between First Contentful Paint and Time to Interactive. A 250 ms task contributes 200 ms.

TBT and INP: how they relate

Interaction to Next Paint, a Core Web Vital, measures how fast the page responds to real taps and clicks during the whole visit. Lab tools cannot tap your page like users do, so Lighthouse reports TBT instead. A high TBT means the main thread is busy, so interactions during load are likely to feel slow. Fix TBT in the lab, then confirm with INP field data.

Step 1: find what blocks the main thread

  1. Lighthouse → “Avoid long main-thread tasks” and “Reduce JavaScript execution time” list the worst scripts.
  2. “Reduce the impact of third-party code” groups costs by provider.
  3. DevTools Performance panel: record a page load with CPU throttling, find the red-flagged long tasks, and expand them to see which script and function caused them.
  4. Coverage tab: shows how much of each JS file is actually used on the page.

Write down each script, its source (plugin, theme, third party), its cost, and whether this page needs it.

Step 2: remove what is not needed

The cheapest JavaScript is the one never loaded. Typical candidates:

  • Plugins no longer used (see my plugin audit).
  • Duplicate libraries (two versions of a slider library, several icon fonts).
  • jQuery Migrate, if nothing depends on it.
  • Emoji scripts, if you do not need them.
  • Old tracking tags from past campaigns in your tag manager.

Step 3: load scripts only where needed

Contact form scripts on every page, slider scripts on pages without sliders, map scripts site-wide: all common. Dequeue them conditionally:

add_action( 'wp_enqueue_scripts', function () {
    if ( ! is_page( 'contact' ) ) {
        wp_dequeue_script( 'contact-form-7' );
        wp_dequeue_style( 'contact-form-7' );
    }
}, 100 );

Handles differ per plugin; find them in the page source or with Query Monitor. Some optimisation plugins offer per-page script managers that do the same without code.

Step 4: defer and delay

  • Defer (defer attribute) downloads in parallel and runs after HTML parsing. Since WordPress 6.3, wp_enqueue_script() accepts a loading strategy:
wp_enqueue_script( 'mx-ui', get_stylesheet_directory_uri() . '/assets/ui.js', array(), '1.0', array(
    'strategy'  => 'defer',
    'in_footer' => true,
) );
  • Delay until interaction waits until the user scrolls, moves the mouse or taps before loading a script. Very effective for chat widgets, review widgets, heat maps and some analytics. Not suitable for anything needed immediately: navigation menus, above-the-fold sliders, cookie consent required before tracking.

Always test after enabling delay: open the mobile menu, submit forms, add to cart, check analytics still records.

Step 5: tame third-party scripts

Third parties are often the biggest share. Options:

  • Chat widgets: load on click with a lightweight placeholder button; or load after a delay.
  • YouTube and map embeds: use a facade (a thumbnail that loads the real embed on click).
  • Tag managers: audit tags; each one runs on your users’ devices.
  • A/B testing tools: these often block rendering by design; use them deliberately and remove when tests end.
  • Social feeds: replace with static content or links.

Step 6: reduce DOM and page builder weight

Large DOMs make every script and style recalculation slower, which affects both TBT and INP. With page builders:

  • Avoid deeply nested sections and columns.
  • Turn off unused widgets and modules in the builder settings.
  • Use the builder’s performance options (for example, loading only used assets).
  • For key templates, a lean custom template in the child theme may outperform the builder.

Step 7: write lighter JavaScript

If you control the code:

  • Break long work into smaller chunks and yield to the main thread between them.
  • Use event delegation instead of thousands of listeners.
  • Avoid layout thrashing: batch DOM reads, then writes.
  • Use CSS for animation where possible, and IntersectionObserver instead of scroll handlers.

Measuring correctly

Lab TBT varies between runs and between machines. Run Lighthouse several times and compare medians, always with the same device settings. After deploying, purge caches (page cache, optimisation plugin cache, CDN) so you test the new version.

Checklist

  • Long tasks identified and attributed to scripts
  • Unused plugins and tags removed
  • Page-specific scripts loaded only on those pages
  • Non-critical scripts deferred; widgets delayed until interaction
  • Embeds replaced with facades
  • DOM size reduced on key templates
  • Key interactions tested after changes
  • INP field data monitored

Common mistakes

  • Enabling “delay all JavaScript” and not noticing the mobile menu is broken.
  • Measuring with a cached old version.
  • Blaming WordPress core when one chat widget causes most of the blocking time.
  • Combining all JS into one large file, which can create one huge long task.

If your site feels sluggish on phones, contact me and I will trace where the time goes. Related: improving LCP.

Frequently asked questions

What is Total Blocking Time?

TBT is the total time, between First Contentful Paint and Time to Interactive, that the main thread was blocked long enough to prevent input responsiveness. Each task over 50 ms contributes its time beyond 50 ms.

What is a good TBT score?

Lighthouse treats around 200 ms or less on mobile as good. Because it is a lab metric, use it to compare changes, and judge users' experience with INP field data.

Is delaying JavaScript safe?

Often, but not always. Delaying scripts until user interaction can break menus, sliders, forms or analytics. Exclude critical scripts and test key pages after enabling it.

Why did TBT get worse after an update?

New plugin versions, added tracking tags, or a theme adding scripts site-wide are common causes. Compare the scripts loaded before and after in DevTools.

Muhamed Ahmed

Ecommerce & Web Solutions Developer

I'm Muhamed Ahmed, an ecommerce and web solutions developer with 15 years of experience building fast, secure online stores and websites on WooCommerce, WordPress and custom Laravel platforms. I write about website speed, SEO, automation and conversion.

All articles Work with me

Related articles