What is TBT? Total Blocking Time Explained
Learn what Total Blocking Time measures, how it differs from the Core Web Vitals, and why Lighthouse leans on TBT when it scores your page.

Total Blocking Time (TBT) is a lab metric that measures how long the browser's main thread was blocked during page load, blocked meaning busy running long tasks and unable to respond to input. It sums the blocking portion of every task longer than 50 milliseconds between First Contentful Paint and Time to Interactive. Per web.dev's documentation, only the time beyond the 50 ms threshold counts, so a 70 ms task contributes 20 ms of blocking time.
TBT is not a Core Web Vital. It's the lab stand-in for responsiveness, the thing you measure in Lighthouse when you can't measure real users. The field metric it predicts is INP, and before that FID.
How TBT Is Calculated
The main thread processes tasks, parsing, script execution, layout. Any single task over 50 ms is a "long task," and the excess over 50 ms is its blocking time. TBT adds up those excesses across the load window.
A worked example, because the summing trips people up:
| Task | Duration | Blocking time |
|---|---|---|
| Parse bundle A | 200 ms | 150 ms |
| Run analytics init | 45 ms | 0 ms |
| Execute bundle B | 90 ms | 40 ms |
| Hydrate components | 130 ms | 80 ms |
| TBT | 270 ms |
Four tasks, but the 45 ms one contributes nothing because it never crossed the threshold. That threshold exists because tasks under roughly 50 ms don't produce human-noticeable input delay. What TBT punishes is not total work but how the work clumps. The same 465 ms of JavaScript split into ten 46 ms chunks would score a TBT of zero.
That last sentence is basically the whole optimization strategy in disguise.
TBT, FID, and INP
The relationship confuses almost everyone at first, me included when the metrics were being shuffled around.
- TBT is lab-only. Lighthouse and similar tools compute it on a simulated load with no user present.
- FID was the old field metric, the delay before the first real interaction got handled. It was retired as a Core Web Vital in March 2024.
- INP replaced it, measuring interaction latency across the whole visit rather than just the first input.
Since no user exists in a lab run, Lighthouse can't measure either field metric directly, so it uses TBT as the proxy, a busy main thread is what makes interactions slow. The correlation is good, not perfect. A page can have decent TBT and bad INP if the slow interactions come from event handlers that only run on click, which a no-interaction lab load never executes.
What Counts as a Good TBT
Lighthouse's scoring treats roughly 200 ms or under as good on emulated mobile hardware, with the score degrading as TBT climbs into the several-hundreds. Treat the exact boundaries loosely, they're scoring-curve parameters rather than official thresholds like the Core Web Vitals have, and they've been tuned over Lighthouse versions.
The number that matters more in practice is the trend. A TBT of 900 ms says the main thread is drowning in JavaScript, and whatever the scoring curve says, real phones will feel it.
How to Reduce TBT
Ship less JavaScript. The unglamorous first answer. Audit the bundle, remove dead dependencies, and question whether each framework feature earns its bytes. Everything else on this list is a workaround for shipping too much.
Break up long tasks. Chunk large loops and init work so the thread gets breathing room between pieces, yielding to the event loop between chunks. Same total work, radically better TBT, because only the over-50 ms excess counts.
Defer what the first paint doesn't need. Third-party scripts, analytics, chat widgets, load them after interactive or on interaction. Third-party tags are the biggest TBT line item on a lot of real sites.
Move work off the main thread. Web workers for genuinely heavy computation. Less commonly applicable, dramatic when it applies.
On static sites, hydrate less. For Astro sites like this one, the islands model is the TBT strategy, HTML by default, JavaScript only where a component genuinely needs it. A mostly-static page has almost nothing to block on, which is why static-first stacks tend to post very low TBT without anyone optimizing.
Common Mistakes to Avoid
Optimizing TBT and declaring responsiveness fixed. TBT is the proxy. INP from real users is the target, and slow event handlers hide from lab runs entirely.
Comparing TBT across different machines. Lab TBT depends heavily on the hardware and throttling profile. Your laptop's numbers and PageSpeed Insights' emulated phone aren't the same scale. Compare like with like.
Blaming the framework before the tags. I've seen audits where the app code contributed a fraction of the long tasks and the rest was tag-manager cargo. Check the third-party column in the trace first, it's the cheapest win available.
Chasing zero. Sub-100 TBT on mobile emulation is already excellent for an interactive app. The last 50 ms is rarely worth the engineering it costs.
In Practice
The fastest useful diagnosis is a Lighthouse run followed by opening the performance trace and just looking at the long-task blocks. They're marked, you can see exactly which script produced each one. In my experience the first trace usually contains one embarrassing surprise, an A/B testing snippet, a video embed loading eagerly on every page, a polyfill bundle for browsers nobody uses anymore. Fix the embarrassing thing before touching application code.
Related Terms
- What is INP? - the field responsiveness metric TBT approximates in the lab.
- What is FID? - the retired predecessor, replaced in March 2024.
- What are Core Web Vitals? - the field-metric set TBT supports but doesn't belong to.
- What is Page Speed? - the broader loading-performance picture.
- What is Lazy Loading? - deferring work the first paint doesn't need.
Key Takeaways
- TBT sums the over-50 ms portions of long main-thread tasks between First Contentful Paint and Time to Interactive.
- It's a lab proxy for real-user responsiveness, now measured in the field by INP.
- Task clumping, not total work, is what TBT punishes, so splitting long tasks helps even when total JavaScript stays the same.
- Third-party scripts are the most common oversized contributor, check them before rewriting app code.
Sources
- Total Blocking Time (TBT) - web.dev (checked 2026-08-12)
- Interaction to Next Paint (INP) - web.dev (checked 2026-08-12)
- Long Tasks API - MDN (checked 2026-08-12)
Related Articles

What are Core Web Vitals? SEO Guide for Beginners
Learn what Core Web Vitals mean in SEO, why they matter, and how to use them to improve your search rankings.

What Is Core Web Vitals? SEO Glossary
Learn what Core Web Vitals means in SEO, why it matters, and how to improve them for better search rankings.

What is a gTLD? Domain Extensions Explained
Learn what a generic top-level domain is, how gTLDs differ from ccTLDs, what the 2012 expansion added, and whether your extension affects rankings.