Total Blocking Time: the lab number that stands in for INP
Total Blocking Time is the Lighthouse number that stands in for INP. It sums up main thread blocks between first paint and when the page feels ready. If your performance score swings, TBT is likely the lever you can move this week.
By Théophile Louvart, founder of Porteur · Updated 14 September 2026 · Markdown
What Total Blocking Time measures
Total Blocking Time is the sum of the time your main thread was blocked by long tasks while the page loaded. Lighthouse counts every task longer than 50 ms, and for each of those, it adds only the part above 50 ms. A 120 ms task contributes 70 ms. A task under 50 ms adds nothing.
The window is first contentful paint to when the page is interactive. If the thread is busy, the browser cannot run input handlers or paint the next frame quickly. That is why TBT tracks perceived jank and input delay.
Targets as of 2026 are simple in lab data: good up to 200 ms. Poor when it is far above that. You will see the biggest swing in your Lighthouse score from cuts to TBT, because Lighthouse weights TBT at 30 percent of the Performance score.
Lab versus field: where TBT shows and where it does not
TBT is a lab metric. You will not see it in Search Console or the field section of PageSpeed Insights. Field data comes from real Chrome users over the last 28 days and is limited to the Core Web Vitals and a few supporting metrics. TBT is not one of them.
Lighthouse is a single simulated run. By default it uses a mid-range phone on a throttled 4G profile. Scores vary between runs. PageSpeed Insights shows both: the field summary at the top, and a Lighthouse run below it. When they disagree, tune for the field. That is the data Google uses for ranking at the Good thresholds.
Why TBT matters for small sites
You ship pages that run the whole business. One script can slow every visit. You do not need a big budget to fix TBT. You need to remove or move the work that blocks the main thread in the first second. That usually means less JavaScript, smaller bundles, and delaying third parties until after the first paint and first interaction.
A page like "/pricing" with chat, analytics, A/B and a UI framework often spends the first second parsing and hydrating. If you split that up and load chat on click, Lighthouse TBT drops, and real users tap the toggle without delay. Your INP improves too, which is what matters in Search.
How TBT relates to INP
INP replaced First Input Delay as a Core Web Vital in March 2024. INP measures the worst interaction in a visit at the 75th percentile of users. Good up to 200 ms, poor above 500 ms. An interaction has three parts: input delay while the main thread is busy, processing time for your handlers, and presentation delay for the next paint.
Lighthouse cannot click your page. So it cannot measure INP. It uses TBT as a proxy for the input delay part. Long tasks create both high TBT in lab and slow interactions in the field. If you cut long tasks and move heavy work off the main thread, your TBT drops and your INP usually improves on real traffic.
The usual causes of high TBT
- Big JavaScript bundles that parse and compile for hundreds of milliseconds.
- Hydration of large frameworks on page load, especially when many islands mount at once.
- Heavy or synchronous event handlers that run on every scroll, resize or input.
- A large DOM and layout thrash, for example layout reads after writes in tight loops.
- Synchronous scripts in the head and render-blocking CSS that arrive late.
- Third-party scripts: tag managers, analytics, A/B tests, chat, embeds and ad stacks.
PageSpeed Insights will often flag these in the audits: Reduce JavaScript execution time. Minimise main-thread work. Reduce the impact of third-party code. Avoid an excessive DOM size. Eliminate render-blocking resources. Each points to main thread work you can cut or delay.
Find what blocks the main thread
Run PageSpeed Insights on Mobile for the URL that matters
Open pagespeed.web.dev and test "/" or "/pricing". Read the field section first. If INP fails there, fix that. Then scroll to the Lighthouse run and note the TBT value and the top opportunities.
Open the DevTools Performance panel locally
In Chrome, record a performance profile of a hard reload of the page. Look for Long Task bars, each longer than 50 ms. Click them to see which script and function caused the time.
Map tasks to scripts and owners
Group by URL. Is it your app bundle, a hydration script, a tag manager, or an embed like a video? List the top three offenders and the lines where the time is spent.
Check JavaScript and CSS Coverage
In DevTools Coverage, reload the page. If 70 percent of a bundle is unused on the first view, split it. If a CSS file blocks paint and most of it is unused above the fold, inline the critical rules and lazy load the rest.
Repeat in a clean profile and on a mid-range phone
Extensions hide work. Use an incognito window or a clean Chrome profile. If you can, profile on a physical mid-tier Android device over a slow network. The long tasks are easier to see.
Cut TBT fast: a priority list with examples
- Defer non-critical scripts. Add defer or async to scripts that are not needed for first paint or first input. type=module defers by default.
- Break long tasks into microtasks. Yield back to the main thread inside loops and large initialisations so the browser can paint and handle input.
- Code split and lazy load below-the-fold UI. Import only the code needed for the route and for what is visible at first paint.
- Hydrate in islands and on interaction. Do not mount the whole app at once. Defer heavy widgets until the user scrolls them into view or clicks.
- Move heavy work to a Web Worker. Parsing, data transforms, search indexing or JSON processing should not run on the main thread.
- Remove or delay third-party scripts. Load chat, video embeds and social buttons on interaction. Keep the tag manager container small.
- Eliminate render-blocking CSS and synchronous scripts in the head. Inline critical CSS, load the rest with media=print and onload, and defer scripts.
- Reduce the DOM and avoid layout thrash. Batch DOM writes and reads. Avoid forced synchronous layouts in tight loops.
// Break up a long task during startup
// Modern browsers: scheduler.yield is available in many evergreen builds
async function setup() {
// Do a chunk of work
initPartA();
// Yield so the browser can paint and process input
if (window.scheduler && scheduler.yield) await scheduler.yield();
// Next chunk
initPartB();
if (window.scheduler && scheduler.yield) await scheduler.yield();
initPartC();
}
// Fallback when scheduler.yield is not present
function microtaskYield() {
return new Promise(r => setTimeout(r));
}
async function setupFallback() {
initPartA();
await microtaskYield();
initPartB();
await microtaskYield();
initPartC();
}Example: your "/guides/getting-started" page loads a code editor above the fold by default. Replace it with a static preview and a Load editor button. Lazy import the editor module on click. TBT on Mobile drops. The first tap feels instant. INP improves in the field next release cycle.
Third parties without the main-thread tax
Third-party scripts often dominate TBT. Keep only what you need, and load them late or on demand. Use a facade pattern for heavy embeds: show a poster image and a Play button, load the real player on click. For maps and chats, render a static image or badge first. Real users get a fast first tap. Your lab TBT and your field INP both benefit.
- Tag managers: audit tags quarterly. Remove dormant tags. Block vendor templates you do not use.
- Analytics: load after load event. Send the first pageview late. Preconnect only the domains you need.
- A/B testing: prefer server-side or origin trials that do not block paint. If you must run client-side, run after first paint and keep experiments small.
- Embeds: replace iframes with a clickable poster and data attributes that lazy load the iframe on demand.
- Consent tools: render in an overlay, not as a banner that pushes content down later.
Render-blocking resources and fonts
Stylesheets in the head block rendering until they arrive. Synchronous scripts in the head block parsing. Fix both before you fight JavaScript execution time. Shipping fewer critical bytes reduces how long the main thread is busy during the paint window, which lowers TBT too.
- Inline critical CSS. Load the rest with media=print and swap on onload.
- Defer or async scripts. Modules defer by default. Avoid inline scripts that depend on synchronous execution.
- Remove unused CSS. Avoid @import chains.
- Fonts: use font-display swap or optional. Preload only the one font used above the fold with rel=preload as=font and crossorigin. Self-host WOFF2. Subset with unicode-range. Prefer a matched fallback to avoid layout shifts when the font swaps.
A fixed "/" home page has one small critical CSS block in the head, defers all scripts, and preloads one WOFF2 heading font. It paints fast and leaves the main thread free for input and the next frame, which keeps both TBT and INP in line.
Server time still matters
Time to First Byte does not count toward TBT. But a slow server shifts all work later and extends the time window where long tasks will block early input. If TTFB is high, fix that in parallel: cache or pre-render the HTML, use a CDN, and remove redirect chains. Target good up to 0.8 s in lab for TTFB. If the hero image is slow or lazy-loaded, your LCP will slip and your performance score will suffer even if TBT is fine.
Prove the win and keep it
Lock a baseline
Save a PageSpeed Insights run on Mobile for the page you are fixing, with TBT, LCP and CLS. Note the audits that point to main thread work.
Ship one change at a time
Split the bundle. Delay chat. Break a long task. Re-run Lighthouse and record TBT. Small changes keep cause and effect clear.
Check the field after deployment
After a release, wait for the 28-day field window to move. In Search Console’s Core Web Vitals report, watch INP for the URL group. Field wins beat lab wins.
Set a performance budget in CI
Fail builds when the app bundle grows or TBT regresses on your smoke route. Review third-party additions before they go live.
Re-test monthly
Browsers, dependencies and your content change. Re-run PageSpeed Insights on your top templates: home, pricing, blog post. Keep TBT under 200 ms in lab.
Questions
Total Blocking Time is the lab sum of how long your main thread was blocked by long tasks during load. Lighthouse adds the time above 50 ms for each task from first contentful paint to when the page is interactive. Keep it under 200 ms for a solid lab result.
TBT is a Lighthouse metric. Field data comes from the Chrome User Experience Report, which tracks Core Web Vitals over a 28‑day window from real users. Lighthouse cannot measure interactions, so it uses TBT as a proxy for INP in the lab. Search Console and the field section of PageSpeed Insights report INP, LCP and CLS from the field, not TBT.
Lighthouse weights TBT at 30 percent of the Performance score. That is the single largest weight. Cutting TBT often moves your score more than similar work on smaller audits. Scores vary between runs, so confirm over several tests and fix the code paths that are always slow.
Not directly. The Lighthouse score is not a ranking factor. But the same fixes that cut TBT reduce long tasks and improve INP in the field. INP is a Core Web Vital and is used as a ranking signal at the Good threshold, behind relevance and content.
Defer non-critical scripts, split bundles by route, hydrate UI in islands, and delay heavy widgets until interaction. Break long tasks with scheduler.yield or setTimeout, and move parsing or data transforms into a Web Worker. Remove or delay third parties. Inline only critical CSS and defer the rest.
Use PageSpeed Insights for a quick Mobile run. Read the field data, then the Lighthouse section for TBT and audits. For deeper work, use Chrome DevTools Performance and Coverage to find long tasks and unused code. Re-test after each change, and monitor the Core Web Vitals report in Search Console for field INP.
Sources
Check my site, free
Paste your URL to see a 30‑second check of your site, the searches around it and the rivals on them, with three findings you can ship today.
- Free check, no card
- Read-only, your own accounts
- Readable by your agent
Read next
- GuideReading a Lighthouse score on a phone
- ComparisonLighthouse vs PageSpeed Insights: lab and field
- GuideHow to read PageSpeed Insights: field data first, then the score
- GuideHow to improve Interaction to Next Paint
- GuideRender-blocking resources: what blocks the first paint and how to unblock it
- GuideThird-party scripts: the page speed you gave away
- Free toolCore Web Vitals checker
- GlossaryCore Web Vitals