Total Blocking Time (TBT) is a Lighthouse lab metric that adds up the blocking portions of long main-thread tasks between First Contentful Paint and Lighthouse's internal Time to Interactive point. A task becomes a long task when it lasts more than 50 milliseconds; only the time beyond 50 milliseconds contributes to TBT.
For example, a 120-millisecond task contributes 70 milliseconds. Several smaller long tasks can therefore produce the same TBT as one very large task. The trace, not only the total, tells you what to fix.
What TBT measures
The browser's main thread parses HTML and CSS, executes most JavaScript, calculates styles, lays out the page, and paints frames. While a long task occupies that thread, the browser may be unable to process input promptly.
TBT estimates the amount of potential blocking during a Lighthouse load. It is useful because a lab test may not contain meaningful user interaction. Lighthouse can still observe startup tasks that would have delayed an input if it arrived at that moment.
TBT carries 30% of the current documented Lighthouse performance score. That makes it influential in the lab score, but its purpose is diagnosis. Cutting 200 milliseconds from a trace does not guarantee a fixed number of score points because Lighthouse scoring is nonlinear and other metrics can change between runs.
TBT is not INP
Interaction to Next Paint (INP) is a Core Web Vital measured from real interactions in the field. TBT is a lab metric calculated during a defined loading interval. They are related because main-thread contention can harm both, but they are not interchangeable.
A page can have low TBT and poor INP if an expensive menu, editor, filter, or checkout interaction occurs after startup. It can also have high lab TBT while real visitors rarely interact during the blocking window. Use TBT to find startup work and use field INP plus interaction traces to assess responsiveness.
The broader Core Web Vitals guide explains the field thresholds and why lab proxies should remain clearly labeled.
Interpret TBT thresholds
Chrome's Lighthouse TBT documentation currently uses these mobile bands:
| Classification | Mobile TBT |
|---|---|
| Good | 0–200 milliseconds |
| Needs improvement | More than 200–600 milliseconds |
| Poor | More than 600 milliseconds |
For desktop, the documented bands are 0–150 milliseconds, more than 150–350 milliseconds, and more than 350 milliseconds. Always report the Lighthouse configuration with the value. These are lab score bands, not field Core Web Vital thresholds.
Find the responsible long tasks
Run Lighthouse against a production-like build, then record a Chrome DevTools Performance trace. In the Main track, inspect tasks marked as long and expand their call trees. Group them by owner:
- application bundles and framework hydration;
- component initialization and large synchronous renders;
- tag managers, analytics, ads, chat, consent, or experimentation;
- JSON parsing, sorting, syntax highlighting, or data transformation;
- style recalculation, layout, and large DOM updates;
- browser extensions present only in a local test.
The Bottom-Up view helps aggregate expensive functions. DevTools Coverage can reveal downloaded JavaScript or CSS that the tested route did not execute, although unused bytes alone do not prove removal is safe.
Capture the script URL, function, duration, and feature owner. “Reduce JavaScript” is not an actionable ticket; “delay the support widget until the launcher is opened” is.
Reduce first-party JavaScript work
Start with code that is not required for the initial experience:
- split route-specific features so they are not shipped globally;
- remove obsolete dependencies and duplicate libraries;
- import only the functions or icons used by the route;
- render static content on the server instead of recreating it through hydration;
- virtualize genuinely large interactive lists;
- avoid parsing large payloads before the user needs them;
- reduce DOM size and repeated layout reads and writes.
Bundle size is a useful lead, but execution time depends on the code and device. A compressed bundle can still require expensive parse and execution work. Confirm the change in a trace on a representative mobile CPU profile.
Control third-party scripts
Inventory every external script and assign a business owner. For each one, record where it loads, when it executes, which consent state permits it, and what user outcome it supports.
Where requirements allow, load nonessential code after consent, interaction, or viewport entry. Limit global tag-manager rules and remove retired campaign tags. Prefer a vendor's supported delayed-loading option over modifying its snippet in a way the vendor does not support.
async and defer change scheduling, not execution cost. An asynchronous script can still create a long task when it runs, and it may interrupt a critical rendering phase. Compare traces with the script present and absent to quantify its cost before choosing a policy.
Break up necessary work
When computation is required, divide it at safe boundaries so the browser can yield between chunks. The current web.dev long-task guidance describes yielding strategies and the emerging scheduler APIs. Choose an approach supported by your browser targets and provide a fallback where needed.
Use a Web Worker for computation that does not require the DOM, such as parsing or transforming a large dataset. The worker reduces main-thread pressure, but transferring large objects also has a cost. Measure the complete operation.
Framework transitions, idle callbacks, and timers can help schedule nonurgent work, but they should not delay essential accessibility, navigation, or input handlers.
Avoid fixes that only move the problem
Do not postpone all startup work until the first click. That may improve TBT while making the first real interaction slow and worsening INP. Likewise, a full-page loading overlay can hide visual updates without reducing main-thread work.
Be cautious with aggressive script combination, minification, or execution-delay plugins. They can change dependency order, consent behavior, analytics accuracy, and checkout functionality. Test the feature path, not only the score.
The legacy Time to Interactive guide explains why TTI was removed from Lighthouse and which modern measurements should replace it in reports.
Validate a TBT improvement
After a change:
- repeat the same Lighthouse scenario several times;
- verify that the intended long task disappeared or became shorter;
- confirm no equivalent task moved later into the first interaction;
- test keyboard, pointer, and touch flows on a representative device;
- watch field INP and error monitoring after release.
Track comparable results over time with IndieTools Speed, and annotate releases so a trend remains attributable. A durable improvement reduces unnecessary work while preserving business behavior and real interaction quality.


