Total Blocking Time (TBT): what it is, how to lower it
Total Blocking Time adds up how long JavaScript kept a page unresponsive while it loaded. Good is under 200 ms on mobile. What causes it and how to cut it.
In this guide
What TBT measures
A browser has one main thread for running JavaScript, calculating styles and drawing the page. While it is busy with a task it cannot respond to a tap or a keypress, and it cannot be interrupted. A short task goes unnoticed. A long one makes the page feel stuck.
Any task that runs longer than 50 milliseconds is called a long task. Its blocking time is the part over 50 milliseconds: a 70 millisecond task has 20 milliseconds of blocking time. Total Blocking Time is the sum of the blocking time of every long task between First Contentful Paint (FCP) and the point where Lighthouse considers the page reliably interactive.
Here is an example with made-up numbers: five tasks during a page load.
| Task | Duration | Blocking time (over 50 ms) |
|---|---|---|
| 1 | 80 ms | 30 ms |
| 2 | 45 ms | 0 ms |
| 3 | 220 ms | 170 ms |
| 4 | 60 ms | 10 ms |
| 5 | 35 ms | 0 ms |
| Total | 440 ms | 210 ms |
The tasks added up to 440 milliseconds of work, but only 210 milliseconds of that counts as blocking. Notice how one long task (task 3) is most of it. Ten tasks of 51 milliseconds each add up to only 10 milliseconds of TBT, while a single one-second task adds 950. The metric punishes one long block much more than many short ones, which matches how it feels to a visitor.
What counts as good
Google's guidance is a TBT under 200 milliseconds when tested on average mobile hardware. Lighthouse uses two control points to turn the time into a score:
| Test setting | Scores 90 at | Scores 50 at |
|---|---|---|
| Mobile | 200 ms | 600 ms |
| Desktop | 150 ms | 350 ms |
In the report, a mobile TBT of up to 200 milliseconds is green, 200 to 600 is orange, and over 600 is red.
Why it weighs so much
Of the five metrics in Lighthouse's performance score, TBT has the largest weight: 30 of the 100 points. The score guide lists the other four and shows how they combine. That makes JavaScript work the biggest single lever on the lab score. It also stands in for something real. A page that blocks the main thread during loading is a page that ignores taps during loading.
TBT is a lab number, INP is the field number
TBT is measured in a lab test, where Lighthouse loads the page by itself and nobody touches it. Web.dev advises against measuring it on real visitors: what people do during a visit changes the result too much. Real responsiveness is measured by Interaction to Next Paint (INP), a Core Web Vital that looks at how long the page takes to respond to real taps, clicks and key presses across the whole visit.
The two are related, because both come from a busy main thread, but they are not the same number. A page with a low TBT can still have a poor INP if a heavy click handler runs later. A page with a high TBT might never be tapped during the loading window. Use TBT to find JavaScript that makes loading heavy, and INP to judge what users experience.
What causes a high TBT
- Too much JavaScript. Code the page does not need to start, downloaded, parsed and run anyway: whole frameworks, plugins, sliders, animation libraries. The Chrome documentation calls unnecessary loading, parsing and execution a much bigger opportunity on most sites than anything else.
- Third-party scripts. Tag managers, ad and analytics tags, chat widgets and social embeds each run their own code on your main thread.
- Inefficient code. A script that selects thousands of elements on load, or forces the browser to recalculate layout again and again, can block for a long time on a few lines.
- Large pages. A very large document, thousands of elements, makes every style and layout calculation slower (see DOM size and rendering). Lighthouse's test also slows the CPU down by a factor of four to imitate a slower phone, so work that takes 80 milliseconds on your laptop can take over 300 in the test.
How to bring it down
- Find the long tasks. Record a page load in the Performance panel of Chrome DevTools and look at the main thread. The long tasks stand out, and clicking one shows which script ran. Lighthouse also lists them in its diagnostics. See breaking up long tasks and where main-thread time goes.
- Remove what you do not need. Delete unused plugins and scripts. Every script you remove is work the main thread never does.
- Load the rest later. Add
deferto scripts the first screen does not need, and load widgets only when a visitor scrolls to them or clicks them. - Split large bundles. Send each page only the code it uses. See bundle size and code splitting and critical CSS and render-blocking resources for the loading side of this.
- Cut third-party weight. Check what each tag costs and remove the ones that do not earn their place.
- Break up long tasks you cannot remove. Work that must run can be split into smaller pieces so the browser can respond between them.
Check your own page
Run the free audit and look at Total Blocking Time. If it is over 200 milliseconds, the report's diagnostics on JavaScript execution time, main-thread work and third-party code point at where the time goes. Start with the single biggest script.
Sources
- Total Blocking Time on web.dev: the definition, the worked example and the 200 millisecond guidance.
- Total Blocking Time in the Lighthouse documentation: how it is scored and the usual causes.
- Lighthouse performance scoring: the weights of the five metrics.
Start here
Free website audit
Live Google data for any public page: mobile and desktop.
Mobile + desktop · Lighthouse lab test · Real-user Chrome data when Google has it
Rather have this done for you? Core Web Vitals · Book a call