PageSpeed Fix · June 2026

Shopify Total Blocking Time: How to Reduce TBT (2026)

Shopify Total Blocking Time gets high when JavaScript and browser work block the main thread during load. Start with a free Shopify speed test; Thunder defers the app scripts that usually cause the worst TBT, then this guide shows the manual theme fixes.

~12 min read · JavaScript examples included

Quick Fix with Thunder

TBT is one of the clearest places where Shopify apps hurt speed. Every review widget, chat script, popup, analytics tag, subscription app, and page builder competes for the same main thread. Thunder defers non-critical JavaScript so the browser can render and respond sooner.

Install Thunder first to reduce blocking app work, then use this guide for custom theme code and long tasks. If your field metric is also weak, read the Shopify INP guide; if PageSpeed also shows main-thread warnings, use the main-thread work guide.

Install Thunder

What Total Blocking Time Measures

Total Blocking Time is the sum of the blocking portions of long tasks between First Contentful Paint and Time to Interactive. A long task is any main-thread task longer than 50ms. If a task takes 120ms, the blocking portion is 70ms. Lighthouse adds those blocking portions together.

That matters because the browser cannot respond to a tap while the main thread is busy. A page can look loaded but still feel broken if the customer taps a variant selector, menu, or cart drawer while JavaScript is still executing.

TBT is not a real-user Core Web Vitals metric. But it is closely related to responsiveness. The field metric to watch is INP, where Google considers under 200ms good. If TBT is terrible in Lighthouse, your INP risk is usually higher too.

Why Shopify Total Blocking Time Gets High

App scripts

Reviews, popups, chat, bundles, subscriptions, analytics, and tag managers run code during load.

Theme bundles

Sliders, predictive search, quick view, cart drawers, animations, and product galleries can create long tasks.

Large pages

Large DOMs, big collection grids, and page builder sections increase style, layout, and JavaScript query work.

Step 1: Find the Long Tasks Behind TBT

Open Chrome DevTools -> Performance, record a mobile-like page load, and look for long yellow tasks. Click each task and inspect the call stack. The domain or file name often tells you whether the work comes from your theme, an app, a tag manager, or a third-party widget.

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

This small observer does not replace DevTools, but it gives you a quick feel for whether long tasks are happening during load. If most long tasks come from third-party domains, start with app loading. If they come from your theme bundle, inspect custom JavaScript.

Step 2: Defer Shopify App and Theme Scripts

The fastest TBT win is usually to stop non-critical scripts from running during the first load. For theme scripts that are not needed before content appears, use defer:

<script src="{{ 'theme.js' | asset_url }}" defer></script>

Be careful with order. defer preserves execution order after parsing. async does not. For app scripts, do not blindly edit files you do not own. Use Thunder for dependency-aware deferral and then remove low-value apps that still create heavy work.

Step 3: Load Widgets After Intent or Visibility

Chat, reviews, recommendations, video embeds, and personalization widgets rarely need to initialize before the first paint. Load them when the customer scrolls near the section or interacts with the feature.

const target = document.querySelector('[data-recommendations]');

if (target) {
  const observer = new IntersectionObserver((entries) => {
    if (!entries.some((entry) => entry.isIntersecting)) return;

    import('./recommendations.js').then((module) => {
      module.init(target);
    });

    observer.disconnect();
  }, { rootMargin: '400px' });

  observer.observe(target);
}

This pattern reduces initial TBT because the JavaScript still exists, but it does not execute during the most sensitive window. Pair it with our third-party scripts guide and Hotjar speed impact guide if tracking tools are part of the stack.

Step 4: Break Long Theme Tasks Into Chunks

Some Shopify theme code does legitimate work in a bad shape. Product filtering, search result rendering, cart recommendation updates, and variant option setup can loop through hundreds of elements in one task. Break the work into chunks so the browser can respond between batches.

async function hydrateCards(cards) {
  for (let index = 0; index < cards.length; index += 12) {
    cards.slice(index, index + 12).forEach(hydrateCard);

    if ('scheduler' in window && 'yield' in scheduler) {
      await scheduler.yield();
    } else {
      await new Promise((resolve) => setTimeout(resolve, 0));
    }
  }
}

This does not reduce total code size, but it lowers blocking time because the browser gets chances to paint and respond. It is especially useful on collection pages, search pages, and app-heavy product templates.

Step 5: Reduce DOM and Unused JavaScript

A large DOM makes JavaScript slower because queries, event delegation, style recalculation, and layout all touch more elements. If PageSpeed shows TBT plus DOM warnings, read our Shopify excessive DOM size guide and reduce product grids, duplicate mobile/desktop markup, mega menus, and page builder wrappers.

Unused JavaScript is the other quiet TBT cost. Old app snippets, unused theme features, legacy sliders, and abandoned A/B test code still parse and execute. Clean these up with our unused CSS and JavaScript guide.

If images are also huge, TBT will not be your only bottleneck. Use the enormous network payloads guide after the main script work is under control. If interactions still feel janky after scripts are deferred, audit drawers, sliders, and product cards with the non-composited animations guide.

Manual Fix vs Thunder Fix

TBT issueManual fixThunder fix
App scripts block loadAudit apps, remove low-value tools, conditionally load snippetsDefers non-critical app scripts automatically
Theme JS creates long tasksChunk loops, defer scripts, remove unused featuresReduces competing script work; custom code may still need edits
Widgets initialize too earlyLoad on scroll, click, or section visibilityImproves loading order around non-critical widgets
Large DOM slows handlersReduce nodes, product cards, menus, and duplicated markupKeeps extra scripts from worsening the DOM bottleneck

Retest TBT Without Chasing Noise

Lighthouse lab scores vary, especially on Shopify mobile tests. Run several tests, compare the median, and focus on the same template. Watch TBT, main-thread work, JavaScript execution time, and INP field data together.

If TBT improves but LCP remains weak, move to Shopify LCP optimization. If TBT stays high after app deferral, the issue is probably custom theme code or a necessary app that needs deeper work. For automation, see Thunder’s features and pricing.

References and Validation

Use Chrome's Total Blocking Time documentation as the source of truth for how TBT is calculated. For real-user responsiveness, compare it with web.dev's INP guidance.

Shopify Community examples tend to give broad advice like compress images or remove apps. That can help, but TBT is specifically about blocking main-thread work. The best fix is precise: find long tasks, defer non-critical scripts, remove low-value JavaScript, and break custom work into smaller chunks. For layout-related performance problems that can worsen TBT, also check forced reflow fixes and passive event listeners.

Do It Yourself

Free plan · 1-click install · Instant results

Install Thunder Free →

Done For You

Core Web Vitals guarantee · 2-week delivery · 6 months Thunder free

Get Expert Optimization →

Starting from €1,500

FAQ

What is Total Blocking Time on Shopify?

Total Blocking Time is the Lighthouse lab metric that measures how long the main thread is blocked by tasks over 50 milliseconds between First Contentful Paint and Time to Interactive. On Shopify, high TBT usually means too much JavaScript is running too early.

Is TBT the same as INP?

No. TBT is a lab metric from Lighthouse, while INP is a real-user Core Web Vitals metric. They are related because both get worse when the browser's main thread is busy and cannot respond quickly.

What is a good Total Blocking Time score?

Lighthouse considers under 200ms good, 200-600ms needing improvement, and over 600ms poor. Shopify mobile tests often exceed this when several apps, page builders, and theme scripts run during load.

Can Thunder reduce Total Blocking Time automatically?

Yes. Thunder defers non-critical scripts, improves loading order, and reduces the amount of app JavaScript competing for the main thread during initial load. Custom theme code may still need manual cleanup if it creates long tasks.

Which Shopify apps cause high TBT?

Any app can contribute, but common offenders include chat, popups, reviews, subscriptions, bundles, upsells, page builders, personalization, analytics, heatmaps, and tag managers that load on every page.

Should I remove apps to reduce TBT?

Remove low-value apps first, but do not remove revenue-critical apps blindly. Measure each app, defer or conditionally load what you can, and use Thunder to reduce the blocking cost of scripts you still need.