Total Blocking Time (TBT) is a lab metric of web performance that measures how long the browser main thread is blocked by long tasks during page load, so that the page cannot respond quickly to user input. It adds up the blocking portion of every long task, meaning the time beyond 50 milliseconds, that occurs between First Contentful Paint (FCP) and Time to Interactive (TTI).
TBT is collected in controlled test environments such as Lighthouse rather than from real visitors. It is widely used as the lab proxy for responsiveness, because field metrics such as Interaction to Next Paint (INP) require real interactions that a synthetic page load does not produce.
How Total Blocking Time is calculated
Total Blocking Time is calculated by finding every long task on the main thread, subtracting 50 milliseconds from each, and adding up the remainders. A task is long when it runs for more than 50 ms; the 50 ms threshold comes from the idea that a response within about 100 ms feels instant, leaving time for the browser to handle the input itself.
The measurement window starts at First Contentful Paint and ends at Time to Interactive, the point after which the main thread stays quiet for about five seconds. The example below shows how four tasks in that window produce a TBT value.
| Main-thread task | Duration | Blocking portion |
|---|---|---|
| Task A, script evaluation | 250 ms | 200 ms |
| Task B, style recalculation | 40 ms | 0 ms |
| Task C, framework hydration | 90 ms | 40 ms |
| Task D, analytics setup | 155 ms | 105 ms |
| Total Blocking Time | 535 ms of work | 345 ms |
The example shows why TBT is more informative than total script time: Task B adds no blocking at all, while one 250 ms task contributes more than all the others combined. Breaking a long task into short pieces can therefore cut TBT sharply even when the total amount of work stays the same.
Thresholds and interpretation
Lighthouse rates Total Blocking Time against fixed thresholds that assume a throttled mid-range mobile device. Results depend heavily on CPU throttling and the test machine, so values are only comparable when they come from the same test setup.
| TBT value | Rating | Practical meaning |
|---|---|---|
| 0 to 200 ms | Good | Input during load is handled promptly |
| 200 to 600 ms | Needs improvement | Noticeable delays on slower devices |
| Above 600 ms | Poor | Taps and clicks may wait a second or more |
In recent Lighthouse versions, TBT carries the largest single weight in the performance score, about 30 percent. A poor TBT therefore lowers the overall score more than any other single lab metric, which is one reason teams track it closely during development.
TBT compared with related performance metrics
TBT belongs to a family of metrics that describe different moments of the loading experience. It is often confused with interactivity metrics measured in the field, although it captures a narrower situation.
| Metric | What it measures | Lab or field | Relation to TBT |
|---|---|---|---|
| TBT | Main-thread blocking during load | Lab | Reference metric |
| INP | Latency of real interactions over the visit | Field | TBT is its usual lab proxy |
| FCP | First text or image painted | Both | Starts the TBT window |
| TTI | Point of sustained main-thread quiet | Lab | Ends the TBT window |
| LCP | Largest content element painted | Both | Measures loading, not blocking |
The relationship with INP is a correlation, not an equivalence. TBT covers only the loading phase, while INP covers interactions throughout the whole visit, including work triggered by clicks long after load. A page can show good TBT and poor INP when expensive event handlers run later, and the reverse also occurs.
Reducing Total Blocking Time
Reducing TBT means doing less JavaScript work during load or splitting it so that no single task holds the main thread for long. The most effective techniques are listed in the decision table below.
| Cause | Recommended fix | Expected effect |
|---|---|---|
| Large application bundle | Code splitting and lazy loading | Less script parsed during load |
| Heavy third-party tags | Defer or load after interaction | Removes blocking from the load window |
| Long synchronous loops | Yield to the main thread | Breaks one long task into short ones |
| Expensive hydration | Partial or progressive hydration | Spreads framework work over time |
| CPU-intensive computation | Move work to a web worker | Keeps the main thread free |
Yielding is done with techniques such as setTimeout chunks or the newer scheduler.yield() API, which lets pending input run between chunks. Minification reduces download size but has limited effect on TBT, because the cost lies mainly in parsing and executing code, not transferring it.
Limitations and common mistakes
TBT is useful but narrow, and misreading it leads to wasted optimization effort.
- Treating TBT as a user metric: it is not a Core Web Vitals metric and is not collected from real visitors.
- Comparing across machines: a fast developer laptop can report a fraction of the TBT measured on throttled hardware.
- Ignoring variance: single runs fluctuate, so a median of several runs is more reliable.
- Optimizing only the score: delaying all scripts past the test window can improve TBT while users still meet the same delays later.
- Overlooking third parties: advertising and tag scripts frequently cause the longest tasks.
The most reliable approach is to pair TBT with field data. Lab measurements reveal which scripts block the main thread and allow quick before-and-after comparisons in continuous integration, while real user monitoring of INP confirms whether visitors on their own devices actually experience faster responses to input. When the two disagree, the field result should guide priorities.
The short version
While a page loads, the browser works through a single to-do list. When one job on that list takes too long, the page cannot react to your taps or clicks. Total Blocking Time adds up those frozen moments.
Imagine a cashier who cannot serve the next customer until a long phone call ends. Short calls are fine. Long calls make the queue wait. A lower TBT means a page that answers sooner.
Where it makes a difference
An online retailer notices that product pages feel sluggish on budget phones, even though images appear quickly. A Lighthouse audit on mobile settings reports a TBT of about 1,100 ms, and the performance trace shows one 600 ms task for product-review widgets and several long tasks from marketing tags.
The team loads the review widget only when it scrolls into view, defers two marketing tags until after the first interaction, and splits the cart initialization script into smaller chunks that yield to the main thread. The next audits show TBT around 250 ms. Field data collected over the following weeks also shows better INP on product pages, confirming that the lab improvement reached real shoppers.