Total Blocking Time (TBT)
What TBT measures, the 50ms long-task math, why it's the lab proxy for INP (not a Core Web Vital), and how to fix a red score — from a technical SEO.
Total Blocking Time (TBT) is the sum of the blocking portion — the time above 50 ms — of every long task between First Contentful Paint and Time to Interactive. It's a lab-only metric, the single largest weight (30%) in the Lighthouse Performance score, and the lab proxy for the Core Web Vital INP (it used to proxy FID). It is NOT a Core Web Vital and never shows up in Search Console or CrUX. Lighthouse mobile thresholds: good ≤200 ms, poor >600 ms. You fix it the same way you fix INP — break up long JS tasks, code-split, defer or remove unused JS, and cut third-party script cost. My honest take: do it for users and conversions, not for a ranking bump.
TL;DR — Total Blocking Time (TBTTotal Blocking Time — the sum of the blocking portion (time above 50 ms) of every long task between First Contentful Paint and Time to Interactive. It's a lab-recommended metric and the lab proxy for INP, not a Core Web Vital.) measures how long your page is frozen — unable to respond to a click or tap — while it loads. A lab tool like LighthouseLighthouse is Google's free, open-source tool that audits a page under simulated lab conditions and scores it 0–100 across Performance, Accessibility, Best Practices, and SEO. It's lab data — useful for debugging, not a ranking signal. adds up all the time the main thread is blocked between the first paint and when the page becomes interactive. Under 200 ms is good. It’s a lab-only number, it’s not a Core Web Vital, and it won’t show up in Search ConsoleA free Google service that reports how a site performs in Google Search and surfaces problems with how Google crawls, indexes, and serves it. It's first-party data straight from Google — but you don't need it to appear in results..
What TBT is
When a page loads, the browser has one main thread doing the heavy lifting — running JavaScript, building the page, reacting to your clicks. It can only do one thing at a time. If a chunk of JavaScript hogs that thread for too long, the page goes momentarily unresponsive: you tap a button and nothing happens until the script finishes.
Total Blocking Time is a measurement of exactly that frozen time during load. A testing tool like Lighthouse loads your page in a controlled environment, watches the main thread, and adds up all the time it was blocked from responding to input.
The 50ms rule
Not every bit of work counts. The browser can handle short tasks without you noticing. The line is 50 milliseconds: any task that runs longer than that is a “long taskAny main-thread task over 50 ms — the primary cause of INP regressions.,” and only the part above 50 ms counts as blocking time.
So a task that runs for 70 ms adds 20 ms to your TBT. A task that runs for 40 ms adds nothing. TBT is the sum of all those “above 50 ms” slivers while the page is loading.
Evidence for this claim TBT sums the portion above 50 milliseconds of long main-thread tasks between FCP and Time to Interactive. Scope: Lighthouse lab metric definition; not a field Core Web Vital. Confidence: high · Verified: Chrome Developers: Total Blocking TimeWhat’s a good score?
In LighthouseLighthouse is Google's free, open-source tool that audits a page under simulated lab conditions and scores it 0–100 across Performance, Accessibility, Best Practices, and SEO. It's lab data — useful for debugging, not a ranking signal., on mobile:
- Good: 200 ms or less
- Needs improvement: up to 600 ms
- Poor: over 600 ms
The thing most people get wrong
TBT is not a Core Web Vital. The three Core Web VitalsGoogle's three real-user UX metrics — LCP (loading), INP (responsiveness), and CLS (visual stability) — used by Google's ranking systems, with no official weight attached, measured on field data. are LCPLargest Contentful Paint — render time of the largest visible image or text block, relative to when the page started loading. ≤2.5 s (at the 75th percentile) is good., INPInteraction to Next Paint — the input-to-paint latency at the 75th percentile of a page's interactions. ≤200 ms is good., and CLSCumulative Layout Shift — a unitless score for unexpected visual movement, taken from the largest burst (session window) of layout shifts, not the lifetime sum. ≤0.1 is good.. TBT is a lab tool that helps predict your Interaction to Next Paint (INPInteraction to Next Paint — the input-to-paint latency at the 75th percentile of a page's interactions. ≤200 ms is good.) — the real-user metric Google actually uses. You won’t find TBT in Google Search ConsoleA free Google service that reports how a site performs in Google Search and surfaces problems with how Google crawls, indexes, and serves it. It's first-party data straight from Google — but you don't need it to appear in results. or in field dataPerformance metrics captured from real users, not lab tests., because it’s measured by simulating a page load, not by watching real visitors.
Want the full mechanics — the worked example, why TBT carries the most weight in Lighthouse, the TBT-vs-INP difference, and how to actually fix it? Switch to the Advanced tab.
Evidence for this claim Lighthouse classifies mobile TBT at 200 milliseconds or less as good and above 600 milliseconds as poor. Scope: Lighthouse mobile TBT scoring guidance; desktop scoring differs. Confidence: high · Verified: Chrome Developers: Total Blocking TimeTL;DR — TBTTotal Blocking Time — the sum of the blocking portion (time above 50 ms) of every long task between First Contentful Paint and Time to Interactive. It's a lab-recommended metric and the lab proxy for INP, not a Core Web Vital. is the total amount of time, between First Contentful PaintFirst Contentful Paint — the time from when a page starts loading to when any part of its content (text, image, SVG, or non-white canvas) first renders. Good is ≤1.8 s at the 75th percentile. It's a diagnostic metric, not a Core Web Vital. and Time to InteractiveTime to Interactive — a retired Lighthouse lab metric marking the point a page's main sub-resources have loaded and it can reliably respond to input. It was removed from the Lighthouse Performance score in Lighthouse 10 (2023) for being too volatile, was never a Core Web Vital, and still defines the end of the Total Blocking Time measurement window., that the main thread was blocked long enough to prevent input responsiveness. It sums the blocking portion (duration − 50 ms) of every long taskAny main-thread task over 50 ms — the primary cause of INP regressions. (any main-thread task over 50 ms). It’s a lab metric — the single largest weight (30%) in the LighthouseLighthouse is Google's free, open-source tool that audits a page under simulated lab conditions and scores it 0–100 across Performance, Accessibility, Best Practices, and SEO. It's lab data — useful for debugging, not a ranking signal. 10 score and the lab proxy for INPInteraction to Next Paint — the input-to-paint latency at the 75th percentile of a page's interactions. ≤200 ms is good. — but it is not a Core Web Vital and never appears in CrUXChrome User Experience Report — Google's public dataset of real-world (field) performance data from eligible Chrome users. It's the official field-data source behind the Core Web Vitals program. or Search ConsoleA free Google service that reports how a site performs in Google Search and surfaces problems with how Google crawls, indexes, and serves it. It's first-party data straight from Google — but you don't need it to appear in results.. Mobile thresholds: good ≤200 ms, poor >600 ms. Fix it like you’d fix INPInteraction to Next Paint — the input-to-paint latency at the 75th percentile of a page's interactions. ≤200 ms is good.: break up long JS tasks, code-split, defer/remove unused JS, tame third-party scripts. My honest take: fix it for users, not for a ranking bump.
What TBT actually measures
Google’s definition is the place to start. TBT is “the total amount of time after First Contentful Paint (FCPFirst Contentful Paint — the time from when a page starts loading to when any part of its content (text, image, SVG, or non-white canvas) first renders. Good is ≤1.8 s at the 75th percentile. It's a diagnostic metric, not a Core Web Vital.) where the main thread was blocked for long enough to prevent input responsiveness.” The browser’s main thread processes one task at a time; while it’s busy with a long chunk of work, it can’t react to a click, a tap, or a keypress. TBT quantifies how much of your page-load window is spent in that blocked state.
Two definitions do all the work here:
- A long task is “a task that runs on the main thread for more than 50 milliseconds.”
- The blocking portion of a task is its duration minus 50 ms. Tasks at or
under 50 ms contribute exactly
0 ms.
TBT is the sum of those blocking portions between FCP and Time to Interactive (TTI). So First Contentful Paint is the start line: nothing before the first paint counts, because there’s nothing on screen to interact with yet.
Evidence for this claim TBT sums the portion above 50 milliseconds of long main-thread tasks between FCP and Time to Interactive. Scope: Lighthouse lab metric definition; not a field Core Web Vital. Confidence: high · Verified: Chrome Developers: Total Blocking TimeThe worked example
Google’s own table is the clearest illustration. Imagine five tasks run on the main thread between FCP and TTI:
| Task duration | Blocking time (duration − 50 ms) |
|---|---|
| Task one: 250 ms | 200 ms |
| Task two: 90 ms | 40 ms |
| Task three: 35 ms | 0 ms |
| Task four: 30 ms | 0 ms |
| Task five: 155 ms | 105 ms |
| Total Blocking Time | 345 ms |
Tasks three and four are under the 50 ms line, so they contribute nothing. Task one
blocks for 250 − 50 = 200 ms, task five for 155 − 50 = 105 ms. Add the blocking
portions — 200 + 40 + 0 + 0 + 105 — and you get 345 ms of TBT. That’s a
“needs improvement” score, driven almost entirely by two heavy tasks.
This is the counter-intuitive part worth internalizing: “A small number of tasks on the main thread doesn’t necessarily mean low blocking time. Conversely, a large number of tasks doesn’t necessarily lead to tons of blocking time.” (That framing is NitroPack’s, relayed here — reverified against the live source 2026-07-18.) What matters is whether individual tasks cross 50 ms, not how many tasks there are.
The measurement window: FCP to TTI
The window ends at Time to Interactive — “the time from when the page starts loading to when its main sub-resources have loaded and it is capable of reliably responding to user input quickly.” In LighthouseLighthouse is Google's free, open-source tool that audits a page under simulated lab conditions and scores it 0–100 across Performance, Accessibility, Best Practices, and SEO. It's lab data — useful for debugging, not a ranking signal., TTI is foundA 302 (\"Found\") is a temporary redirect: it forwards users to a new URL while telling search engines the original URL should stay in the index. It's a weak canonicalization signal, not the zero-equity dead end of SEO folklore. by searching forward for a five-second “quiet window” with no long tasks and no more than two in-flight network requests.
Worth noting: TTI itself was removed from Lighthouse 10 because it proved overly sensitive to outlier network requests and long tasks, producing high variability. TBT survived and became the primary interactivity metric. As Philip Walton put it, “Newer, alternative, metrics like Largest Contentful PaintLargest Contentful Paint — render time of the largest visible image or text block, relative to when the page started loading. ≤2.5 s (at the 75th percentile) is good. (LCPLargest Contentful Paint — render time of the largest visible image or text block, relative to when the page started loading. ≤2.5 s (at the 75th percentile) is good.), Total Blocking Time (TBT), and Interaction to Next Paint (INP) are usually better metrics to use in place of TTI.” TBT didn’t replace TTI as the window’s endpoint — it’s a better single number for the same underlying problem. And TTI’s disappearance from the Lighthouse report UI isn’t the same claim as TTI no longer bounding Lighthouse’s default navigation window — the window itself is still measured that way under the hood.
One more scoping note: “FCP to TTI” describes Lighthouse’s default navigation audit specifically. Other tools, or Lighthouse itself running a timespan trace instead of a full page-load navigation, can total a different measured window — the 50 ms long-task math doesn’t change, but the start and end points of what gets summed are tool- and trace-mode-specific, not a universal law of the metric.
Is TBT a Core Web Vital? No.
This is the most common misconception, so let’s be blunt about it. The three Core Web VitalsWeb Vitals is Google's initiative (launched May 2020) for unified page-experience quality signals. Core Web Vitals — LCP, INP, and CLS — are the subset used in ranking; the rest (TTFB, FCP, TBT, Speed Index) are diagnostic, not ranking factors. are LCP, INP, and CLSCumulative Layout Shift — a unitless score for unexpected visual movement, taken from the largest burst (session window) of layout shifts, not the lifetime sum. ≤0.1 is good.. TBT is not one of them. Google’s own wording: “Total Blocking Time (TBT) is a lab metrics is vital in catching and diagnosing potential interactivity issues that can impact INP. However, it is not part of the Core Web VitalsGoogle's three real-user UX metrics — LCP (loading), INP (responsiveness), and CLS (visual stability) — used by Google's ranking systems, with no official weight attached, measured on field data. set because they are not field-measurable, nor do they reflect a user-centric outcome.” (The grammar in that sentence is theirs, not mine.)
So where does TBT show up, and where doesn’t it?
- Where you see it: Lighthouse, PageSpeed Insights’ lab tab, and Chrome DevTools — all simulated/lab environments.
- Where you don’t: Google Search ConsoleA free Google service that reports how a site performs in Google Search and surfaces problems with how Google crawls, indexes, and serves it. It's first-party data straight from Google — but you don't need it to appear in results.’s Core Web Vitals reportThe Google Search Console report (under Experience) that shows how your indexed URLs perform on the Core Web Vitals — LCP, INP, and CLS — using real-user field data from CrUX, grouped by device, status, and clusters of similar-performing URLs., CrUXChrome User Experience Report — Google's public dataset of real-world (field) performance data from eligible Chrome users. It's the official field-data source behind the Core Web Vitals program., or any field dataPerformance metrics captured from real users, not lab tests.. Those only carry LCP, INP, and CLS.
If someone tells you they’re “watching TBT in Search ConsoleGoogle's free tool for monitoring crawling, indexing, and search performance.,” they’re mistaken — GSC reports field data, and TBT isn’t a field metric.
One correction worth being precise about: TBT being lab-recommended isn’t the same as TBT being field-impossible. You can technically compute a TBT-style total in the field with the Long Tasks API — Google says so directly: “It is possible to measure TBT in the field, but we don’t recommend this as user interaction can affect your page’s TBT in ways that lead to lots of variance in your reports.” That’s a recommendation against it, not a technical wall. What’s actually true without exception is narrower: CrUX and Search Console’s Core Web Vitals report never carry TBT, full stop — those pipelines only ever collect LCP, INP, and CLS.
TBT is the lab proxy for INP
Here’s why TBT exists at all. Lab tools load a page in a simulated environment with no real user, so they can’t measure Interaction to Next Paint — INP needs actual clicks and taps. TBT fills that gap: “the Total Blocking Time (TBT) metric is lab-measurable and is a proxy for INP.”
The two are mechanically related: “Although INP and TBT are calculated differently, they are both reflections of a blocked main thread during the bootstrap process. When the main thread is blocked, the browser is delayed in responding to user interactions.” And empirically, “A low TBT often correlates with a low Interaction to Next Paint (INP).”
But “proxy” is not “substitute.” Google is explicit: “Total Blocking Time (TBT) may be a reasonable proxy metric for INP, but it’s not a substitute for INP in and of itself.” They diverge in real ways:
- High TBT, fine INP. TBT measures blocking during load. If your users don’t actually try to interact during that blocked window — they wait for the page to look finished first — their INP can be fine even with an ugly TBT.
- Fine TBT, poor INP. INP also covers slow event handlers and renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM. work that fire after load, plus things like the browser’s 300 ms tap delay on non-mobile-optimized pages — none of which TBT sees.
When the lab and field disagree, trust the field. INP (the real-user number) takes priority over TBT (the lab estimate).
One historical note that trips people up: TBT used to be the lab proxy for First Input Delay (FID). INP replaced FID as a Core Web Vital on March 12, 2024, so TBT is now INP’s proxy. The underlying mechanism never changed — it’s always been about a blocked main thread during load — but any older article calling TBT “FID’s proxy” predates that switch.
Why TBT dominates the Lighthouse score
TBT carries the largest single weight in the Lighthouse Performance score — 30%, a weighting introduced in Lighthouse 10 and, verified live against Chrome’s scoring docs on 2026-07-18, still unchanged through the current Lighthouse 13:
| Metric | Weight |
|---|---|
| First Contentful Paint | 10% |
| Speed IndexSpeed Index measures how quickly content is visually displayed during page load — the average time at which visible parts of the page appear, scored in seconds (lower is better). It's a lab-only Lighthouse metric, not a Core Web Vital and not a ranking factor. | 10% |
| Largest Contentful Paint | 25% |
| Total Blocking Time | 30% |
| Cumulative Layout Shift | 25% |
Treat that table as version-and-date-scoped, not a permanent constant — Lighthouse has changed its weights before and can again. Re-verify against Lighthouse performance scoring before quoting it in an audit deck.
This is the practical reason TBT matters for SEO audits even though it isn’t a ranking signal: a poor TBT has an outsized effect on that big Lighthouse number everyone screenshots. Addy Osmani’s worked example makes it concrete — removing one Intersection Observer polyfill cut TBT from 400 ms to 300 ms and lifted the Lighthouse Performance score from 63 to 70. One fix, seven points, because of the 30% weight.
One more nuance: the “Good ≤200 ms” category threshold and the Lighthouse score are different scales. To score 90+ on the TBT subscore you need roughly ≤300 ms on mobile, and to hit 100 you need ≤100 ms. (Those subscore figures are DebugBear’s documentation of the scoring curve, reverified against the live source 2026-07-18.) “Good” and “100” are not the same bar.
Does TBT affect SEO rankings?
Not directly — and I’ll be straighter about this than most.
TBT is not a ranking signal. Google’s interactivity ranking input is INP, a field metric. TBT is a diagnostic that helps you find and fix the long tasks that hurt INP. Improving TBT may improve INP, which might marginally help the Page Experience side of rankings — but that’s two links of “may” away from your positions.
And here’s my actual position on the whole Core Web Vitals question, which I’ve written before in my page speed guide: I don’t think Core Web Vitals have much impact on SEO, and unless you’re extremely slow I generally won’t prioritize them. Do them for users and conversions, not for a ranking bump. That applies doubly to TBT, which is a lab proxy for a field metric for a small ranking input. Fix it because a frozen page loses you customers — not because you’re chasing a position.
What causes high TBT
It’s almost always JavaScript:
- Unnecessary JavaScript loading, parsing, or execution — the Lighthouse audit’s own words. Shipping a big bundle the page doesn’t need at load is the classic cause.
- Inefficient JavaScript statements — heavy synchronous work that monopolizes the main thread.
- Third-party scripts — tag managers, chat widgets, analytics, ad scripts. Often the single biggest contributor, and the one you control least.
- Heavy framework bootstrap — React hydrationActivating server-rendered HTML in the browser by attaching JavaScript handlers. and similar can run long tasks during startup.
- Style/layout recalculation and garbage collection — forced synchronous layout, large style recalcs, and GC pauses show up as main-thread tasks too; don’t assume every long task in the trace is JavaScript execution.
Don’t assume bundle transfer size is the whole story, either. Trace attribution has real gaps: cross-origin frames and worker threads have privacy and security limits on what a long-task observer can report about them (see Troubleshooting), so an unattributed task in your trace isn’t proof no third party is involved — it may just mean the attribution API isn’t allowed to tell you.
How to fix high TBT
The fixes are the same family as the INP fixes — both come down to a blocked main thread.
- Find the long tasks. Open the Chrome DevTools Performance panelThe Performance panel is Chrome DevTools' built-in, local profiler for recording and analyzing how a page loads and runs — CPU, main-thread work, rendering, network, and live Core Web Vitals. The recorded trace is local, lab data from your own browser — not what Googlebot sees — though the panel can optionally show real-user CrUX field data alongside it. and look for tasks over 50 ms (they’re flagged with red corners), or run the Lighthouse “Avoid long main-thread tasks” audit.
- Audit third-party scripts first. They’re usually the easiest wins. Use the DevTools Coverage and Network tabs to see what each script costs, and lazy-load heavy embeds (YouTube, maps, chat) behind a facade.
- Break up the long tasks. Yield to the main thread so the browser can handle
input between chunks — “when tasks are broken up, the browser can respond to
higher-priority work much sooner—including user interactions.” The modern API is
scheduler.yield(), with asetTimeout(resolve, 0)fallback (see the Cheat Sheets tab for the pattern). Note that Google no longer recommendsisInputPending()— yield regardless of whether input is pending. - Reduce the JavaScript. Code-split large bundles so less parses and evaluates
at load, remove unused JS (DevTools Coverage tab shows you what), and
defernon-critical scripts. - Move heavy computation off the main thread. Web Workers run CPU-heavy work on a separate thread, leaving the main thread free to respond.
A useful side effect: long tasks that block the main thread can also delay Largest Contentful Paint rendering, so fixing TBT sometimes improves LCP too — especially when render-blocking JS is involved.
Where to go next
TBT lives in the Core Web Vitals family alongside its field counterpart Interaction to Next Paint, the loading metrics Largest Contentful Paint and First Contentful Paint, and the lab tools Lighthouse, PageSpeed Insights, and Speed Index that report them. If you only remember one thing: TBT is the lab warning light for field responsiveness — chase the long tasks, not the number.
AI summary
A condensed take on the Advanced version:
- TBTTotal Blocking Time — the sum of the blocking portion (time above 50 ms) of every long task between First Contentful Paint and Time to Interactive. It's a lab-recommended metric and the lab proxy for INP, not a Core Web Vital. = blocked main-thread time during load. It’s the total time, between FCPFirst Contentful Paint — the time from when a page starts loading to when any part of its content (text, image, SVG, or non-white canvas) first renders. Good is ≤1.8 s at the 75th percentile. It's a diagnostic metric, not a Core Web Vital. and TTITime to Interactive — a retired Lighthouse lab metric marking the point a page's main sub-resources have loaded and it can reliably respond to input. It was removed from the Lighthouse Performance score in Lighthouse 10 (2023) for being too volatile, was never a Core Web Vital, and still defines the end of the Total Blocking Time measurement window., the main thread was blocked long enough to prevent input responsiveness.
- The math: sum of the blocking portion (
duration − 50 ms) of every long taskAny main-thread task over 50 ms — the primary cause of INP regressions. (any main-thread task over 50 ms). Tasks ≤50 ms add0 ms. Google’s worked example: tasks of 250/90/35/30/155 ms → 345 ms TBT. - It’s a lab metric. You see it in LighthouseLighthouse is Google's free, open-source tool that audits a page under simulated lab conditions and scores it 0–100 across Performance, Accessibility, Best Practices, and SEO. It's lab data — useful for debugging, not a ranking signal., PageSpeed InsightsPageSpeed Insights (PSI) is a free Google tool at pagespeed.web.dev that reports two kinds of data for a URL: real-user field data from the Chrome UX Report and a single Lighthouse lab run with the 0–100 Performance score. Only the field Core Web Vitals are what Google uses for ranking.’ lab tab, and DevTools — never in CrUXChrome User Experience Report — Google's public dataset of real-world (field) performance data from eligible Chrome users. It's the official field-data source behind the Core Web Vitals program. or Search ConsoleA free Google service that reports how a site performs in Google Search and surfaces problems with how Google crawls, indexes, and serves it. It's first-party data straight from Google — but you don't need it to appear in results..
- Not a Core Web Vital. The three CWVGoogle's three real-user UX metrics — LCP (loading), INP (responsiveness), and CLS (visual stability) — used by Google's ranking systems, with no official weight attached, measured on field data. are LCPLargest Contentful Paint — render time of the largest visible image or text block, relative to when the page started loading. ≤2.5 s (at the 75th percentile) is good., INPInteraction to Next Paint — the input-to-paint latency at the 75th percentile of a page's interactions. ≤200 ms is good., CLSCumulative Layout Shift — a unitless score for unexpected visual movement, taken from the largest burst (session window) of layout shifts, not the lifetime sum. ≤0.1 is good.. TBT is the lab proxy for INP (historically FID’s proxy; INP replaced FID on March 12, 2024).
- Biggest LighthouseLighthouse is Google's free, open-source tool that audits a page under simulated lab conditions and scores it 0–100 across Performance, Accessibility, Best Practices, and SEO. It's lab data — useful for debugging, not a ranking signal. weight: 30% — the single largest, so a poor TBT tanks the
overall score. Mobile thresholds: good ≤200 ms, needs improvement ≤600 ms, poor
600 ms.
- Rankings: not a direct ranking factor. INP is the field signal; TBT only helps diagnose it. Patrick’s take: fix it for users and conversions, not for a ranking bump.
- Fixes (same family as INP): find long tasks in DevTools, audit third-party
scripts first, break up tasks with
scheduler.yield(), code-split and remove unused JS, offload heavy work to Web Workers. - Caveat: TBT and INP can diverge — high TBT with fine INP (users don’t interact during load) or fine TBT with poor INP (slow event handlers after load). Field data wins.
- “Lab-only” means lab-recommended, not lab-impossible. You can technically compute a TBT-style total from field dataPerformance metrics captured from real users, not lab tests. with the Long Tasks API, but Google advises against it (too much run-to-run variance) — CrUXChrome User Experience Report — Google's public dataset of real-world (field) performance data from eligible Chrome users. It's the official field-data source behind the Core Web Vitals program. and Search ConsoleGoogle's free tool for monitoring crawling, indexing, and search performance. simply never carry it either way.
- Trace attribution has real gaps. Cross-origin frames and worker threads have privacy/security limits on what a long-task observer can report, so an unattributed task means “cause unknown,” not “no third party involved.”
Official documentation
Primary-source documentation on TBTTotal Blocking Time — the sum of the blocking portion (time above 50 ms) of every long task between First Contentful Paint and Time to Interactive. It's a lab-recommended metric and the lab proxy for INP, not a Core Web Vital. from Google and the Chrome team.
web.dev / Chrome
- Total Blocking Time (TBT) — Philip Walton & Barry Pollard: the canonical definition, the 50 ms long-task rule, and the worked example.
- TBT Lighthouse audit — the audit page, with the mobile/desktop scoring thresholds and cited causes.
- Lighthouse performance scoring — the metric weights, where TBT’s 30% comes from.
- Web Vitals — why TBT is not a Core Web Vital and how it relates to the set.
- Interaction to Next Paint (INP) — the field metric TBT proxies, and the “proxy, not substitute” caveat.
- Optimize long tasks — Jeremy Wagner & Brendan Kenny on breaking up tasks,
scheduler.yield(), and whyisInputPending()is no longer recommended. - Time to Interactive (TTI) — the metric that defines the end of the TBT window, and why it was removed from LighthouseLighthouse is Google's free, open-source tool that audits a page under simulated lab conditions and scores it 0–100 across Performance, Accessibility, Best Practices, and SEO. It's lab data — useful for debugging, not a ranking signal. 10.
- Lab and field data differences — the limits of TBT as an INPInteraction to Next Paint — the input-to-paint latency at the 75th percentile of a page's interactions. ≤200 ms is good. stand-in.
Quotes from the source
On-the-record statements from Google’s documentation. Each link is a deep link that jumps to the quoted passage.
Definition and mechanics
- “the total amount of time after First Contentful PaintFirst Contentful Paint — the time from when a page starts loading to when any part of its content (text, image, SVG, or non-white canvas) first renders. Good is ≤1.8 s at the 75th percentile. It's a diagnostic metric, not a Core Web Vital. (FCPFirst Contentful Paint — the time from when a page starts loading to when any part of its content (text, image, SVG, or non-white canvas) first renders. Good is ≤1.8 s at the 75th percentile. It's a diagnostic metric, not a Core Web Vital.) where the main thread was blocked for long enough to prevent input responsiveness.” — web.dev, Total Blocking Time. Jump to quote
- “a task that runs on the main thread for more than 50 milliseconds” — the definition of a long taskAny main-thread task over 50 ms — the primary cause of INP regressions.. Jump to quote
- “To provide a good user experience, sites should strive to have a Total Blocking Time of less than 200 milliseconds when tested on average mobile hardware.” Jump to quote
- “A low TBTTotal Blocking Time — the sum of the blocking portion (time above 50 ms) of every long task between First Contentful Paint and Time to Interactive. It's a lab-recommended metric and the lab proxy for INP, not a Core Web Vital. often correlates with a low Interaction to Next PaintInteraction to Next Paint — the input-to-paint latency at the 75th percentile of a page's interactions. ≤200 ms is good. (INPInteraction to Next Paint — the input-to-paint latency at the 75th percentile of a page's interactions. ≤200 ms is good.).” Jump to quote
Status: not a Core Web Vital
- “Total Blocking Time (TBT) is a lab metrics is vital in catching and diagnosing potential interactivity issues that can impact INP. However, it is not part of the Core Web VitalsGoogle's three real-user UX metrics — LCP (loading), INP (responsiveness), and CLS (visual stability) — used by Google's ranking systems, with no official weight attached, measured on field data. set because they are not field-measurable, nor do they reflect a user-centric outcome.” — web.dev, Web VitalsWeb Vitals is Google's initiative (launched May 2020) for unified page-experience quality signals. Core Web Vitals — LCP, INP, and CLS — are the subset used in ranking; the rest (TTFB, FCP, TBT, Speed Index) are diagnostic, not ranking factors. (Philip Walton). (Grammar is verbatim from the source.) Jump to quote
TBT as the INP proxy
- “In such cases, Total Blocking Time (TBT) may be a reasonable proxy metric for INP, but it’s not a substitute for INP in and of itself.” — web.dev, Interaction to Next Paint. Jump to quote
Long tasks and fixing them
- “The main thread can only process one task at a time. Any task that takes longer than 50 milliseconds is a long task.” — web.dev, Optimize long tasks. Jump to quote
- “When tasks are broken up, the browser can respond to higher-priority work much sooner—including user interactions.” Jump to quote
- On
isInputPending(): “We no longer recommend using this API, and instead recommend yielding regardless of whether input is pending or not.” Jump to quote
TTITime to Interactive — a retired Lighthouse lab metric marking the point a page's main sub-resources have loaded and it can reliably respond to input. It was removed from the Lighthouse Performance score in Lighthouse 10 (2023) for being too volatile, was never a Core Web Vital, and still defines the end of the Total Blocking Time measurement window. and why TBT replaced it as the key interactivity number
- “Newer, alternative, metrics like Largest Contentful PaintLargest Contentful Paint — render time of the largest visible image or text block, relative to when the page started loading. ≤2.5 s (at the 75th percentile) is good. (LCPLargest Contentful Paint — render time of the largest visible image or text block, relative to when the page started loading. ≤2.5 s (at the 75th percentile) is good.), Total Blocking Time (TBT), and Interaction to Next Paint (INP) are usually better metrics to use in place of TTI.” — web.dev, Time to Interactive (Philip Walton). Jump to quote
TBT triage checklist
A quick pass when LighthouseLighthouse is Google's free, open-source tool that audits a page under simulated lab conditions and scores it 0–100 across Performance, Accessibility, Best Practices, and SEO. It's lab data — useful for debugging, not a ranking signal. hands you a red (or orange) Total Blocking Time:
- Confirm you’re reading lab data — TBTTotal Blocking Time — the sum of the blocking portion (time above 50 ms) of every long task between First Contentful Paint and Time to Interactive. It's a lab-recommended metric and the lab proxy for INP, not a Core Web Vital. is in LighthouseLighthouse is Google's free, open-source tool that audits a page under simulated lab conditions and scores it 0–100 across Performance, Accessibility, Best Practices, and SEO. It's lab data — useful for debugging, not a ranking signal. / PageSpeed Insights’ lab tab / DevTools, not the field or Search ConsoleA free Google service that reports how a site performs in Google Search and surfaces problems with how Google crawls, indexes, and serves it. It's first-party data straight from Google — but you don't need it to appear in results..
- Open the DevTools Performance panel and find the long tasksAny main-thread task over 50 ms — the primary cause of INP regressions. (over 50 ms, red-cornered) between first paint and interactive.
- List your third-party scripts and what each costs (Coverage + Network tabs) — start here; it’s usually the biggest, easiest win.
- Lazy-load heavy embeds (YouTube, maps, chat) behind a facade.
- Run the Lighthouse “Avoid long main-thread tasks” and “Reduce unused JavaScript” audits and work the list.
- Code-split large bundles so less JS parses/evaluates at load.
- Defer non-critical scripts; dynamic-
import()what isn’t needed immediately. - Break up remaining long tasks with
scheduler.yield()(setTimeout fallback). Don’t reach forisInputPending(). - Move CPU-heavy computation to a Web Worker.
- Cross-check the field: pull INPInteraction to Next Paint — the input-to-paint latency at the 75th percentile of a page's interactions. ≤200 ms is good. from CrUXChrome User Experience Report — Google's public dataset of real-world (field) performance data from eligible Chrome users. It's the official field-data source behind the Core Web Vitals program. / real-user monitoring. If INPInteraction to Next Paint — the input-to-paint latency at the 75th percentile of a page's interactions. ≤200 ms is good. is fine, don’t over-invest in chasing the lab number.
TBT cheat sheet
The math, in one line
TBT = Σ (taskDuration − 50 ms) for every task > 50 ms between FCPFirst Contentful Paint — the time from when a page starts loading to when any part of its content (text, image, SVG, or non-white canvas) first renders. Good is ≤1.8 s at the 75th percentile. It's a diagnostic metric, not a Core Web Vital. and
TTITime to Interactive — a retired Lighthouse lab metric marking the point a page's main sub-resources have loaded and it can reliably respond to input. It was removed from the Lighthouse Performance score in Lighthouse 10 (2023) for being too volatile, was never a Core Web Vital, and still defines the end of the Total Blocking Time measurement window.. Tasks ≤ 50 ms contribute 0 ms.
Worked example (Google’s)
| Task | Duration | Blocking time |
|---|---|---|
| 1 | 250 ms | 200 ms |
| 2 | 90 ms | 40 ms |
| 3 | 35 ms | 0 ms |
| 4 | 30 ms | 0 ms |
| 5 | 155 ms | 105 ms |
| Total | 345 ms |
LighthouseLighthouse is Google's free, open-source tool that audits a page under simulated lab conditions and scores it 0–100 across Performance, Accessibility, Best Practices, and SEO. It's lab data — useful for debugging, not a ranking signal. thresholds
| Verdict | Mobile | Desktop |
|---|---|---|
| Good (green) | ≤ 200 ms | ≤ 150 ms |
| Needs improvement (orange) | ≤ 600 ms | ≤ 350 ms |
| Poor (red) | > 600 ms | > 350 ms |
(Thresholds vs. the LighthouseLighthouse is Google's free, open-source tool that audits a page under simulated lab conditions and scores it 0–100 across Performance, Accessibility, Best Practices, and SEO. It's lab data — useful for debugging, not a ranking signal. subscore curve differ: 90+ ≈ ≤300 ms mobile, 100 ≈ ≤100 ms mobile — DebugBear’s documented figures, reverified live 2026-07-18.)
TBTTotal Blocking Time — the sum of the blocking portion (time above 50 ms) of every long task between First Contentful Paint and Time to Interactive. It's a lab-recommended metric and the lab proxy for INP, not a Core Web Vital. vs. INPInteraction to Next Paint — the input-to-paint latency at the 75th percentile of a page's interactions. ≤200 ms is good. — the cheat sheet
| TBT | INPInteraction to Next Paint — the input-to-paint latency at the 75th percentile of a page's interactions. ≤200 ms is good. | |
|---|---|---|
| Type | Lab | Field |
| Core Web Vital? | No | Yes |
| Measures | Main-thread blocking during load | Real interaction latency across the whole visit |
| Window | FCPFirst Contentful Paint — the time from when a page starts loading to when any part of its content (text, image, SVG, or non-white canvas) first renders. Good is ≤1.8 s at the 75th percentile. It's a diagnostic metric, not a Core Web Vital. → TTI | Every click/tap/key, at the 75th percentile |
| Seen in | Lighthouse, PSIPageSpeed Insights (PSI) is a free Google tool at pagespeed.web.dev that reports two kinds of data for a URL: real-user field data from the Chrome UX Report and a single Lighthouse lab run with the 0–100 Performance score. Only the field Core Web Vitals are what Google uses for ranking. lab, DevTools | CrUXChrome User Experience Report — Google's public dataset of real-world (field) performance data from eligible Chrome users. It's the official field-data source behind the Core Web Vitals program., Search ConsoleA free Google service that reports how a site performs in Google Search and surfaces problems with how Google crawls, indexes, and serves it. It's first-party data straight from Google — but you don't need it to appear in results., RUM |
| Ranking signal? | No | Yes (Page ExperienceGoogle's three real-user UX metrics — LCP (loading), INP (responsiveness), and CLS (visual stability) — used by Google's ranking systems, with no official weight attached, measured on field data.) |
| Relationship | Lab proxy for INP (was FID’s proxy pre-2024) | The thing TBT estimates |
Yield-to-main pattern (the fix)
function yieldToMain () {
if (globalThis.scheduler?.yield) {
return scheduler.yield();
}
return new Promise(resolve => {
setTimeout(resolve, 0);
});
}Use scheduler.yield() where available, fall back to setTimeout. Don’t use
isInputPending() — Google now recommends yielding regardless of whether input is
pending.
Patrick's relevant free tools
- Page Speed Test & Core Web Vitals Checker — One sentence tells you whether a page passes Core Web Vitals and what to fix first — real Chrome user data (CrUX) with a Lighthouse lab fallback, mobile and desktop side by side, loudly-labeled data sources, and prioritized diagnostic fixes. Plus a bulk origin scorecard with CSV export.
- Hosting Checker — Find a domain's public IP network, CDN or edge platform, DNS and mail-host evidence, and response transfer facts without pretending a proxy reveals the origin.
- Core Web Vitals History & Competitor Comparison — Chart 40 weeks of real-Chrome-user Core Web Vitals — p75 LCP, INP, CLS, FCP, and TTFB from the Chrome UX Report — and compare up to 5 origins or URLs on one chart. Plus a competitor Leaderboard that ranks curated groups of SEO and page-speed tools on each metric. Pass/fail scorecards, mobile vs desktop, shareable links, CSV export.
Tools for measuring and fixing TBT
- PageSpeed InsightsPageSpeed Insights (PSI) is a free Google tool at pagespeed.web.dev that reports two kinds of data for a URL: real-user field data from the Chrome UX Report and a single Lighthouse lab run with the 0–100 Performance score. Only the field Core Web Vitals are what Google uses for ranking. — read TBTTotal Blocking Time — the sum of the blocking portion (time above 50 ms) of every long task between First Contentful Paint and Time to Interactive. It's a lab-recommended metric and the lab proxy for INP, not a Core Web Vital. in the lab data section (it’s not in the field-data section, because TBT isn’t a field metric).
- LighthouseLighthouse is Google's free, open-source tool that audits a page under simulated lab conditions and scores it 0–100 across Performance, Accessibility, Best Practices, and SEO. It's lab data — useful for debugging, not a ranking signal. (Chrome DevTools → LighthouseLighthouse is Google's free, open-source tool that audits a page under simulated lab conditions and scores it 0–100 across Performance, Accessibility, Best Practices, and SEO. It's lab data — useful for debugging, not a ranking signal. panel, or the CLI) — the source of the TBT number and the “Avoid long main-thread tasks” / “Reduce unused JavaScript” audits.
- Chrome DevTools — Performance panelThe Performance panel is Chrome DevTools' built-in, local profiler for recording and analyzing how a page loads and runs — CPU, main-thread work, rendering, network, and live Core Web Vitals. The recorded trace is local, lab data from your own browser — not what Googlebot sees — though the panel can optionally show real-user CrUX field data alongside it. — record a load and find the long tasksAny main-thread task over 50 ms — the primary cause of INP regressions. (over 50 ms, flagged with red corners) that make up your TBT.
- Chrome DevTools — Coverage tab — see how much of each script is actually used, to target unused JavaScript and heavy third parties.
- WebPageTestWebPageTest is a free, open-source, lab-based website performance testing tool — created by Patrick Meenan in 2008 and acquired by Catchpoint in 2020 — that runs pages on real browsers from distributed locations and produces deep diagnostics (waterfalls, filmstrips, connection views, Core Web Vitals). It's a diagnostic tool, not a Google ranking input. — lab testing with detailed main-thread and CPU breakdowns.
- Long Animation Frames (LoAFLong Animation Frames API — browser API for diagnosing the long tasks behind slow interactions.) API — a modern, field-side complement to TBT, not a replacement for its lab load-window calculation: it attributes long animation frames across a whole visit, which is closer to how INPInteraction to Next Paint — the input-to-paint latency at the 75th percentile of a page's interactions. ≤200 ms is good. problems actually surface, rather than TBT’s single FCPFirst Contentful Paint — the time from when a page starts loading to when any part of its content (text, image, SVG, or non-white canvas) first renders. Good is ≤1.8 s at the 75th percentile. It's a diagnostic metric, not a Core Web Vital.-to-TTITime to Interactive — a retired Lighthouse lab metric marking the point a page's main sub-resources have loaded and it can reliably respond to input. It was removed from the Lighthouse Performance score in Lighthouse 10 (2023) for being too volatile, was never a Core Web Vital, and still defines the end of the Total Blocking Time measurement window. load window.
- Field-side TBT via the Long Tasks API — technically possible (sum
duration − 50 msfor observed long tasks in production, same as the Scripts tab snippet), but Google recommends against it for RUM: real user interaction timing makes the number too variable to compare run over run. Reach for INPInteraction to Next Paint — the input-to-paint latency at the 75th percentile of a page's interactions. ≤200 ms is good. or LoAF for field responsiveness instead. - Where you won’t find it: Google Search ConsoleA free Google service that reports how a site performs in Google Search and surfaces problems with how Google crawls, indexes, and serves it. It's first-party data straight from Google — but you don't need it to appear in results.’s Core Web Vitals reportThe Google Search Console report (under Experience) that shows how your indexed URLs perform on the Core Web Vitals — LCP, INP, and CLS — using real-user field data from CrUX, grouped by device, status, and clusters of similar-performing URLs. and CrUXChrome User Experience Report — Google's public dataset of real-world (field) performance data from eligible Chrome users. It's the official field-data source behind the Core Web Vitals program. carry LCPLargest Contentful Paint — render time of the largest visible image or text block, relative to when the page started loading. ≤2.5 s (at the 75th percentile) is good., INP, and CLSCumulative Layout Shift — a unitless score for unexpected visual movement, taken from the largest burst (session window) of layout shifts, not the lifetime sum. ≤0.1 is good. only — never TBT, regardless of what’s technically possible to compute yourself.
TBT mistakes that produce the wrong fix
- Calling TBTTotal Blocking Time — the sum of the blocking portion (time above 50 ms) of every long task between First Contentful Paint and Time to Interactive. It's a lab-recommended metric and the lab proxy for INP, not a Core Web Vital. a Core Web Vital. TBT is a lab diagnostic and useful proxy for main-thread contention; INPInteraction to Next Paint — the input-to-paint latency at the 75th percentile of a page's interactions. ≤200 ms is good. is the real-user Core Web Vital. Report them separately.
- Counting the whole long taskAny main-thread task over 50 ms — the primary cause of INP regressions. as blocking time. Only the portion beyond 50 milliseconds counts. A 70-millisecond task contributes 20 milliseconds, not 70.
- Optimizing outside the measurement window. LighthouseLighthouse is Google's free, open-source tool that audits a page under simulated lab conditions and scores it 0–100 across Performance, Accessibility, Best Practices, and SEO. It's lab data — useful for debugging, not a ranking signal. TBT sums blocking between FCPFirst Contentful Paint — the time from when a page starts loading to when any part of its content (text, image, SVG, or non-white canvas) first renders. Good is ≤1.8 s at the 75th percentile. It's a diagnostic metric, not a Core Web Vital. and TTITime to Interactive — a retired Lighthouse lab metric marking the point a page's main sub-resources have loaded and it can reliably respond to input. It was removed from the Lighthouse Performance score in Lighthouse 10 (2023) for being too volatile, was never a Core Web Vital, and still defines the end of the Total Blocking Time measurement window.. Work before or after that window may matter to users, but it is not part of that TBT value.
- Removing first-party code while ignoring the largest third party. Use the trace and request initiators to attribute long tasks before choosing an owner or fix.
- Splitting code without reducing work. Many smaller tasks can improve responsiveness, but shipping the same unnecessary JavaScript still costs parsing, compilation, and execution. Remove unused work as well as yielding it.
- Assuming a good lab TBT proves good field INPInteraction to Next Paint — the input-to-paint latency at the 75th percentile of a page's interactions. ≤200 ms is good.. Real users interact after load on varied devices. Confirm the outcome with field responsiveness data.
TBT is high but the network looks fast
Symptom: Resources download quickly, yet LighthouseLighthouse is Google's free, open-source tool that audits a page under simulated lab conditions and scores it 0–100 across Performance, Accessibility, Best Practices, and SEO. It's lab data — useful for debugging, not a ranking signal. reports heavy blocking.
Likely cause: JavaScript parsing, compilation, execution, hydrationTurning HTML, CSS, and JavaScript into the final visual page and DOM., or third-party work monopolizes the main thread after the bytes arrive.
Fix and confirmation: Record a Performance trace, sort long tasksAny main-thread task over 50 ms — the primary cause of INP regressions. by duration and owner, then remove unused code, defer noncritical work, or split the largest task. Confirm the blocking portion falls in repeated matched runs.
A large bundle is deferred but TBT stays high
Symptom: Adding defer changes download/execution order without materially moving
TBTTotal Blocking Time — the sum of the blocking portion (time above 50 ms) of every long task between First Contentful Paint and Time to Interactive. It's a lab-recommended metric and the lab proxy for INP, not a Core Web Vital..
Likely cause: The same expensive code still executes inside the FCPFirst Contentful Paint — the time from when a page starts loading to when any part of its content (text, image, SVG, or non-white canvas) first renders. Good is ≤1.8 s at the 75th percentile. It's a diagnostic metric, not a Core Web Vital.-to-TTITime to Interactive — a retired Lighthouse lab metric marking the point a page's main sub-resources have loaded and it can reliably respond to input. It was removed from the Lighthouse Performance score in Lighthouse 10 (2023) for being too volatile, was never a Core Web Vital, and still defines the end of the Total Blocking Time measurement window. window.
Fix and confirmation: Profile functions inside the long task. Code-split by route or interaction, reduce hydrationActivating server-rendered HTML in the browser by attaching JavaScript handlers., or remove unused/duplicate work; then verify that execution time, not merely request start time, declines.
Lighthouse TBT is good while field INP is poor
Symptom: Navigation lab tests look responsive, but CrUXChrome User Experience Report — Google's public dataset of real-world (field) performance data from eligible Chrome users. It's the official field-data source behind the Core Web Vitals program. or RUM reports slow interactions.
Likely cause: The problematic task occurs after initial load or only after a real interaction that standard LighthouseLighthouse is Google's free, open-source tool that audits a page under simulated lab conditions and scores it 0–100 across Performance, Accessibility, Best Practices, and SEO. It's lab data — useful for debugging, not a ranking signal. navigation does not exercise.
Fix and confirmation: Collect interaction traces for the poor INPInteraction to Next Paint — the input-to-paint latency at the 75th percentile of a page's interactions. ≤200 ms is good. pages and devices, reproduce the action locally, and optimize the event handling and next paint.
A long task shows up with no clear owner
Symptom: DevTools or a Long Tasks API observer flags a blocking task, but the attribution is blank, generic, or labeled something like “unknown” / “cross-origin.”
Likely cause: This is a known coverage gap, not a measurement error. The Long Tasks API’s own specification bounds what it will report across execution contexts — cross-origin ancestor tasks are deliberately not reported (“this is not reported because of security”), and a deeply embedded cross-origin iframeHTML element that displays one webpage inside another — how embeds work. “does not receive any information” about a long task in a cross-origin ancestor. Work happening in a Web Worker or the browser’s compositor thread can also fall outside what the attribution surfaces you.
Fix and confirmation: Don’t conclude “no third party is involved” just because nothing is named. Cross-check with the Network panel’s initiator column, the Coverage tab, and (where you control the script) first-party instrumentation inside iframes you own. Treat an unattributed task as “cause unknown,” not “cause absent.”
TBT varies sharply between runs
Symptom: One run is green and the next is poor with no deployment.
Likely cause: Variable third-party execution, server timing that changes the work window, cache state, or test-machine contention.
Fix and confirmation: Match settings, run several cold tests, and compare the long task owners and median result rather than selecting one score.
Turn a trace into an ownership plan
Review this Lighthouse/DevTools trace for Total Blocking Time. For every long task
between FCP and TTI, calculate only duration above 50 ms as blocking time, attribute
the task to first-party code, framework/hydration, or a named third party, and rank
owners by blocking contribution. Propose remove, reduce, defer, split, or yield actions
with a validation test for each. Do not treat TBT as field INP or a direct ranking
factor. Compare two performance traces
Compare these before/after traces under matched settings. Report FCP, TBT, the largest
long tasks, their initiators, and whether work moved outside the measurement window or
was actually removed. Flag regressions hidden by the aggregate score. Return a verdict,
confidence limits from the supplied runs, and the next smallest experiment. Do not
invent missing timings.Review a third-party script decision
Given this script's business purpose, loading pattern, request initiator, and main-
thread tasks, decide whether to keep, delay, conditionally load, replace, or remove it.
Separate network cost from execution/blocking cost. Include consent and functionality
constraints, owner, implementation step, TBT validation, field-INP follow-up, and
rollback trigger. Observe long tasks during a reproduction
Run this early in DevTools Console, reproduce the load or interaction, and inspect each task’s blocking portion:
let observedBlocking = 0;
const observer = new PerformanceObserver(list => {
for (const task of list.getEntries()) {
const blocking = Math.max(0, task.duration - 50);
observedBlocking += blocking;
console.log({ start: task.startTime, duration: task.duration, blocking });
}
console.log('Observed blocking total:', observedBlocking);
});
observer.observe({ type: 'longtask', buffered: true });This is a debugging total for the period you observe, not LighthouseLighthouse is Google's free, open-source tool that audits a page under simulated lab conditions and scores it 0–100 across Performance, Accessibility, Best Practices, and SEO. It's lab data — useful for debugging, not a ranking signal.’s official TBTTotal Blocking Time — the sum of the blocking portion (time above 50 ms) of every long task between First Contentful Paint and Time to Interactive. It's a lab-recommended metric and the lab proxy for INP, not a Core Web Vital. unless you deliberately reproduce the same FCPFirst Contentful Paint — the time from when a page starts loading to when any part of its content (text, image, SVG, or non-white canvas) first renders. Good is ≤1.8 s at the 75th percentile. It's a diagnostic metric, not a Core Web Vital.-to-TTITime to Interactive — a retired Lighthouse lab metric marking the point a page's main sub-resources have loaded and it can reliably respond to input. It was removed from the Lighthouse Performance score in Lighthouse 10 (2023) for being too volatile, was never a Core Web Vital, and still defines the end of the Total Blocking Time measurement window. window and test conditions.
Flag scripts with the most main-thread evaluation time
After recording a DevTools Performance trace, use the Bottom-up view grouped by URL. For a quick network inventory alongside it, this Console snippet lists transferred JavaScript from largest to smallest:
performance.getEntriesByType('resource')
.filter(r => r.initiatorType === 'script')
.map(r => ({ script: r.name, transferred: r.transferSize, duration: r.duration }))
.sort((a, b) => b.transferred - a.transferred);Large transfer size is only a lead; the Performance trace is what attributes parsing and execution time to TBT.
Long-task reduction
Test to run: Capture several matched LighthouseLighthouse is Google's free, open-source tool that audits a page under simulated lab conditions and scores it 0–100 across Performance, Accessibility, Best Practices, and SEO. It's lab data — useful for debugging, not a ranking signal./Performance traces before and after the JavaScript change and compare long tasksAny main-thread task over 50 ms — the primary cause of INP regressions. between FCPFirst Contentful Paint — the time from when a page starts loading to when any part of its content (text, image, SVG, or non-white canvas) first renders. Good is ≤1.8 s at the 75th percentile. It's a diagnostic metric, not a Core Web Vital. and TTITime to Interactive — a retired Lighthouse lab metric marking the point a page's main sub-resources have loaded and it can reliably respond to input. It was removed from the Lighthouse Performance score in Lighthouse 10 (2023) for being too volatile, was never a Core Web Vital, and still defines the end of the Total Blocking Time measurement window..
Expected result: The targeted task disappears, shortens, or yields into smaller tasks, and median TBTTotal Blocking Time — the sum of the blocking portion (time above 50 ms) of every long task between First Contentful Paint and Time to Interactive. It's a lab-recommended metric and the lab proxy for INP, not a Core Web Vital. improves without delaying FCPFirst Contentful Paint — the time from when a page starts loading to when any part of its content (text, image, SVG, or non-white canvas) first renders. Good is ≤1.8 s at the 75th percentile. It's a diagnostic metric, not a Core Web Vital. or breaking functionality.
Failure interpretation: Work moved to another bundle/task, still executes in the same window, or normal run variance is larger than the change.
Monitoring window: Test immediately in mobile and desktop lab profiles and watch field INPInteraction to Next Paint — the input-to-paint latency at the 75th percentile of a page's interactions. ≤200 ms is good. during the next reporting window.
Rollback trigger: Roll back if critical interactions break, errors rise, or a repeatable FCP/LCPLargest Contentful Paint — render time of the largest visible image or text block, relative to when the page started loading. ≤2.5 s (at the 75th percentile) is good./INPInteraction to Next Paint — the input-to-paint latency at the 75th percentile of a page's interactions. ≤200 ms is good. regression outweighs the TBT improvement.
Third-party deferral
Test to run: Compare a cold trace with the third party in its current position and with it delayed until consent, idle time, or the relevant interaction.
Expected result: Its long tasks leave the initial TBT window while the required business event still fires at the intended time.
Failure interpretation: Another loader injects it early, dependent code blocks the page, or the script’s main-thread work is not the measured bottleneck.
Monitoring window: Validate on every template that loads the script and monitor both performance and the business event after release.
Rollback trigger: Restore the prior loading path if consent, analytics, checkout, ads, or another required function loses valid events.
Field responsiveness follow-up
Test to run: Segment field INP for affected templates/devices after the lab TBT change while keeping the deployment date annotated.
Expected result: Field responsiveness stays stable or improves; a lab-only win is not reported as a user outcome until field evidence supports it.
Failure interpretation: Real interaction work occurs outside initial load or the optimized cohort is too small to move the aggregate.
Monitoring window: Review through the full field-data reporting window and during high-value interactions.
Rollback trigger: Investigate or roll back if field INP or critical interaction success regresses consistently after the release.
Test yourself: Total Blocking Time
Five quick questions on TBTTotal Blocking Time — the sum of the blocking portion (time above 50 ms) of every long task between First Contentful Paint and Time to Interactive. It's a lab-recommended metric and the lab proxy for INP, not a Core Web Vital. math and diagnosis. Pick an answer for each, then check.
Resources worth your time
Official
- Total Blocking Time (TBT) — the canonical definition and worked example.
- Optimize long tasks — the practical fixing guide (
scheduler.yield(), batching, why notisInputPending()). - Web Vitals — where TBTTotal Blocking Time — the sum of the blocking portion (time above 50 ms) of every long task between First Contentful Paint and Time to Interactive. It's a lab-recommended metric and the lab proxy for INP, not a Core Web Vital. sits relative to the Core Web VitalsGoogle's three real-user UX metrics — LCP (loading), INP (responsiveness), and CLS (visual stability) — used by Google's ranking systems, with no official weight attached, measured on field data..
- Optimizing Web Vitals using Lighthouse — Addy Osmani; includes the polyfill-removal worked example (TBT 400→300 ms, score 63→70).
From others (verify before quoting)
- DebugBear — Total Blocking Time — strong technical depth on the TBT↔INPInteraction to Next Paint — the input-to-paint latency at the 75th percentile of a page's interactions. ≤200 ms is good. mechanism and the LighthouseLighthouse is Google's free, open-source tool that audits a page under simulated lab conditions and scores it 0–100 across Performance, Accessibility, Best Practices, and SEO. It's lab data — useful for debugging, not a ranking signal. scoring curve.
- NitroPack — What is Total Blocking Time? — the “task count ≠ blocking time” insight.
- BrowserStack — TBT guide and Catchpoint — TBT — tool/monitoring-oriented overviews.
- web.dev — User-centric performance metrics — Philip Walton’s framework classifying TBT as a lab/load-responsiveness metric vs. field metrics; useful framing for explaining why TBT doesn’t appear in CrUXChrome User Experience Report — Google's public dataset of real-world (field) performance data from eligible Chrome users. It's the official field-data source behind the Core Web Vitals program..
- web.dev — Getting started with measuring Web Vitals — covers how TBT serves as the lab proxy for INPInteraction to Next Paint — the input-to-paint latency at the 75th percentile of a page's interactions. ≤200 ms is good. when real-user measurement isn’t possible in simulated environments.
- WebPageTest — free lab testing tool that reports TBT alongside detailed main-thread and CPU breakdowns; useful for diagnosing which tasks are driving a high score.
- Search Engine Journal — Core Web Vitals coverage — ongoing industry reporting on CWV updates, TBT’s role in audits, and how practitioners interpret lab vs. field gaps.
Stats worth citing
- TBTTotal Blocking Time — the sum of the blocking portion (time above 50 ms) of every long task between First Contentful Paint and Time to Interactive. It's a lab-recommended metric and the lab proxy for INP, not a Core Web Vital. is 30% of the LighthouseLighthouse is Google's free, open-source tool that audits a page under simulated lab conditions and scores it 0–100 across Performance, Accessibility, Best Practices, and SEO. It's lab data — useful for debugging, not a ranking signal. Performance score — the single largest weight of any metric (LCPLargest Contentful Paint — render time of the largest visible image or text block, relative to when the page started loading. ≤2.5 s (at the 75th percentile) is good. and CLSCumulative Layout Shift — a unitless score for unexpected visual movement, taken from the largest burst (session window) of layout shifts, not the lifetime sum. ≤0.1 is good. are 25% each; FCPFirst Contentful Paint — the time from when a page starts loading to when any part of its content (text, image, SVG, or non-white canvas) first renders. Good is ≤1.8 s at the 75th percentile. It's a diagnostic metric, not a Core Web Vital. and Speed IndexSpeed Index measures how quickly content is visually displayed during page load — the average time at which visible parts of the page appear, scored in seconds (lower is better). It's a lab-only Lighthouse metric, not a Core Web Vital and not a ranking factor. 10% each). Introduced in LighthouseLighthouse is Google's free, open-source tool that audits a page under simulated lab conditions and scores it 0–100 across Performance, Accessibility, Best Practices, and SEO. It's lab data — useful for debugging, not a ranking signal. 10, live-reverified 2026-07-18 as unchanged through Lighthouse 13. Source
- The “good” bar is ≤200 ms on mobile (≤150 ms desktop); “poor” is >600 ms mobile (>350 ms desktop) — Lighthouse audit docs. Source
- One polyfill = seven points. Removing a single Intersection Observer polyfill cut TBT from 400 ms to 300 ms and lifted the Lighthouse Performance score from 63 to 70 — a clean illustration of the 30% weight. Source
- A 250 ms task contributes 200 ms of blocking time — the blocking portion is
always
duration − 50 ms. Google’s worked example totals 345 ms across five tasks. Source
TBT
Total Blocking Time — the sum of the blocking portion (time above 50 ms) of every long task between First Contentful Paint and Time to Interactive. It's a lab-recommended metric and the lab proxy for INP, not a Core Web Vital.
Related: INP, Lighthouse, FCP
TBT
Total Blocking TimeTotal Blocking Time — the sum of the blocking portion (time above 50 ms) of every long task between First Contentful Paint and Time to Interactive. It's a lab-recommended metric and the lab proxy for INP, not a Core Web Vital. (TBT) measures the total amount of time after First Contentful PaintFirst Contentful Paint — the time from when a page starts loading to when any part of its content (text, image, SVG, or non-white canvas) first renders. Good is ≤1.8 s at the 75th percentile. It's a diagnostic metric, not a Core Web Vital. (FCPFirst Contentful Paint — the time from when a page starts loading to when any part of its content (text, image, SVG, or non-white canvas) first renders. Good is ≤1.8 s at the 75th percentile. It's a diagnostic metric, not a Core Web Vital.) where the main thread was blocked for long enough to prevent the page from responding to input. It sums the “blocking portion” of every long taskAny main-thread task over 50 ms — the primary cause of INP regressions. — any main-thread task that runs for more than 50 ms — between FCP and Time to InteractiveTime to Interactive — a retired Lighthouse lab metric marking the point a page's main sub-resources have loaded and it can reliably respond to input. It was removed from the Lighthouse Performance score in Lighthouse 10 (2023) for being too volatile, was never a Core Web Vital, and still defines the end of the Total Blocking Time measurement window. (TTI). The blocking portion of a task is its duration minus 50 ms, so a 250 ms task contributes 200 ms to TBT and a 40 ms task contributes nothing.
TBT is a lab-recommended metric. You see it in LighthouseLighthouse is Google's free, open-source tool that audits a page under simulated lab conditions and scores it 0–100 across Performance, Accessibility, Best Practices, and SEO. It's lab data — useful for debugging, not a ranking signal., PageSpeed InsightsPageSpeed Insights (PSI) is a free Google tool at pagespeed.web.dev that reports two kinds of data for a URL: real-user field data from the Chrome UX Report and a single Lighthouse lab run with the 0–100 Performance score. Only the field Core Web Vitals are what Google uses for ranking.’ lab data, and Chrome DevTools — not in CrUXChrome User Experience Report — Google's public dataset of real-world (field) performance data from eligible Chrome users. It's the official field-data source behind the Core Web Vitals program., and not in the Search Console Core Web VitalsThe Google Search Console report (under Experience) that shows how your indexed URLs perform on the Core Web Vitals — LCP, INP, and CLS — using real-user field data from CrUX, grouped by device, status, and clusters of similar-performing URLs. report, which only carry LCPLargest Contentful Paint — render time of the largest visible image or text block, relative to when the page started loading. ≤2.5 s (at the 75th percentile) is good., INPInteraction to Next Paint — the input-to-paint latency at the 75th percentile of a page's interactions. ≤200 ms is good., and CLSCumulative Layout Shift — a unitless score for unexpected visual movement, taken from the largest burst (session window) of layout shifts, not the lifetime sum. ≤0.1 is good.. (You can technically compute a TBT-style total from field dataPerformance metrics captured from real users, not lab tests. with the Long Tasks API, but Google advises against it for production monitoring because real user interaction timing makes the number too variable to compare run over run.) TBT is not a Core Web Vital; the three Core Web VitalsGoogle's three real-user UX metrics — LCP (loading), INP (responsiveness), and CLS (visual stability) — used by Google's ranking systems, with no official weight attached, measured on field data. are LCP, INP, and CLS. TBT’s job is to be the lab proxy for INP (it was historically the proxy for FID), because lab tools load a page without a real user and so can’t measure actual interactions.
TBT carries the largest single weight in the LighthouseLighthouse is Google's free, open-source tool that audits a page under simulated lab conditions and scores it 0–100 across Performance, Accessibility, Best Practices, and SEO. It's lab data — useful for debugging, not a ranking signal. Performance score — 30%, a weighting introduced in Lighthouse 10 and confirmed unchanged through Lighthouse 13 (verified 2026-07-18) — so a poor TBT drags the whole number down hard. Lighthouse’s mobile thresholds: Good ≤ 200 ms, Needs improvement ≤ 600 ms, Poor > 600 ms. You lower it the same way you lower INP: break up and reduce long JavaScript tasks, code-split, defer or remove unused JS, and cut the cost of third-party scripts.
Related: INP, Lighthouse, FCP
Build-time retrieval analysis plus live signals for this exact article. The automatic chunk report includes a deterministic readiness score and is ready without a model download.
Search Console
sampleGA4 traffic (28d)
sampleCloudflare traffic (7d)
sampledCrUX field data (28d, phone)
sampleGoogle NLP entities
localChangelog
Updated Jul 19, 2026.
Editorial summary and recorded change details.Summary
Fixed a dead outbound citation: Ahrefs restructured its blog and the page-speed guide URL now 404s.
Change details
-
Replaced the dead link to Ahrefs' page-speed guide (ahrefs.com/blog/page-speed/, now 404) with Ahrefs' current live page-speed glossary entry (ahrefs.com/seo/glossary/page-speed).
Full comparison unavailable — no prior snapshot was archived for this revision.
Updated Jul 18, 2026.
Editorial summary and recorded change details.Summary
Live-reverified the field-measurement, Lighthouse-weight, and long-task-attribution claims against current Google/W3C sources, and corrected the article's blanket 'never field-measurable' framing to match what web.dev actually says: field TBT calculation is technically possible but discouraged, not impossible.
Change details
-
Clarified that TBT is lab-recommended rather than lab-impossible — the Long Tasks API can technically compute a field-side TBT total, but Google advises against it for RUM due to interaction-driven variance; CrUX/Search Console still never carry it either way.
-
Scoped the FCP-to-TTI measurement window to Lighthouse's default navigation audit specifically, noting other tools or timespan traces can total a different window.
-
Named the verification date (2026-07-18) and version range (Lighthouse 10 through 13, confirmed unchanged) for the 30% TBT scoring weight instead of presenting it as a permanent fact tied only to Lighthouse 10.
-
Added a 'What causes high TBT' bullet on style/layout recalculation and garbage collection, and a new Troubleshooting entry explaining why some long tasks show up with no clear attributed owner (cross-origin frame and worker privacy/security limits in the Long Tasks API spec).
Full comparison unavailable — no prior snapshot was archived for this revision.