TBT Reduction — Total Blocking Time Optimization Guide

Reduce Total Blocking Time (TBT) to under 200ms. Learn how to identify long tasks, break up JavaScript execution, use code splitting, and optimize third-party scripts.

Supplementary Metrics

Detailed Explanation

Reducing Total Blocking Time (TBT)

TBT measures the total amount of time between FCP and Time to Interactive (TTI) during which the main thread was blocked by "long tasks." A long task is any task that takes more than 50ms. The blocking time is the portion over 50ms.

How TBT Is Calculated

Task Duration: 250ms → Blocking Time: 200ms (250 - 50)
Task Duration: 30ms  → Blocking Time: 0ms (under threshold)
Task Duration: 80ms  → Blocking Time: 30ms (80 - 50)

TBT = Sum of all blocking times = 200 + 0 + 30 = 230ms

TBT Thresholds

Rating Value
Good ≤ 200ms
Needs Improvement ≤ 600ms
Poor > 600ms

TBT as a Lab Proxy for INP

TBT is a lab metric (measured in controlled environments like Lighthouse), while INP is a field metric (measured on real users). However, TBT is strongly correlated with INP — optimizing TBT generally improves INP.

Identifying Long Tasks

Use Chrome DevTools Performance panel:

  1. Record a page load
  2. Look for red flags on tasks in the Main thread flame chart
  3. Any task bar with a red corner is a long task
  4. Click to see the call stack and identify the code responsible

Optimization Strategies

Code Splitting:

// Instead of importing everything upfront
import { heavyModule } from './heavy';

// Split into dynamic imports
const heavyModule = await import('./heavy');

Break Up Long Tasks:

// BAD: One long 200ms task
function processAll(items) {
  items.forEach(item => expensiveOperation(item));
}

// GOOD: Yield between chunks
async function processAll(items) {
  const CHUNK_SIZE = 10;
  for (let i = 0; i < items.length; i += CHUNK_SIZE) {
    const chunk = items.slice(i, i + CHUNK_SIZE);
    chunk.forEach(item => expensiveOperation(item));
    await new Promise(r => setTimeout(r, 0)); // yield
  }
}

Tree Shaking: Ensure your bundler (webpack, Rollup, esbuild) eliminates unused exports. Large utility libraries like lodash should be imported selectively:

// BAD
import _ from 'lodash';

// GOOD
import debounce from 'lodash/debounce';

Defer Third-Party Scripts: Move non-critical third-party scripts (analytics, ads, chat widgets) to load after the main content is interactive. Use async or defer attributes, or load them programmatically after TTI.

Use Case

TBT reduction is essential for JavaScript-heavy applications — SPAs built with React, Angular, or Vue, dashboard applications with complex initialization, and pages loading multiple third-party scripts. Lighthouse uses TBT as a significant scoring factor, so optimizing TBT directly improves your Lighthouse Performance score.

Try It — Web Vitals Reference

Open full tool