Skip to main content

Measure And Optimize Total Blocking Time (TBT)

Total Blocking Time (TBT) measures how responsive your site is to user input. Long-running CPU tasks block the page main thread, and the work required to respond to user interaction can't happen right away.

JavaScript execution is the most common type of long-running CPU task, but parsing HTML or updating the page layout can also block user interaction.

TBT makes up 25% of the overall Lighthouse Performance score. It's often used as an alternative to First Input Delay when running lab-based tests.

How is Total Blocking Time defined?

Total Blocking Time measures the amount of time where a CPU task is taking longer than 50ms to finish. For example, if a task takes 120ms that will add 70ms to overall TBT.

Long CPU tasks before the First Contentful Paint don't count as blocking, since without a visible user interface there's no user interaction that would be blocked.

CPU tasks after the Time to Interactive milestone also don't contribute to the Total Blocking Time metric.

This picture shows an example main thread timeline. To show how blocking time affects user experience, the picture also shows a user clicking on a button, and when that click event is handled.

Slow Total Blocking Time example

Because of the long main thread tasks, the page takes a long time to respond to user input. The time it takes to respond to user input is called First Input Delay. We'll look at how that metric relates to TBT further down in this article.

Several shorter CPU tasks have a smaller impact on the user experience. Tasks under 50ms do not increase Total Blocking Time. That means TBT better captures user impact than looking at the total main thread CPU time.

Fast Total Blocking Time example

What's a good Total Blocking Time?

Ideally, TBT should be under 300ms on mobile and under 100ms on desktop. Total Blocking Time determines 25% of the overall Lighthouse Performance score.

While Total Blocking Time is not one of the Core Web Vitals metrics that impact Google rankings, TBT does have a big impact on Interaction to Next Paint (INP) which does affect rankings.

This table shows how different TBT values lead to different Lighthouse scores.

LCP subscoreMax TTB (Mobile)Max TTB (Desktop)
1000.1s0.05s
900.3s0.1s
500.6s0.3s
101.2s0.8s

Total Blocking Time vs First Input Delay

First Input Delay can only be measured if the user interacts with the page. Synthetic performance tools like Lighthouse don't involve any user interaction, and therefore use Total Blocking Time as a proxy metric.

First Input Delay also depends on the type of user input that's made, for example what button the user decided to click on. So an increase in FID could mean there was a code change that made the site slower, but it could also mean users are increasingly using a slower feature.

User input delays are larger when the main thread is blocked. Therefore a high TBT value means there are many times during the page load process where the page would respond slowly if the user tried to interact with it.

How does Total Blocking Time affect Lighthouse scores?

As of version 10.0.1 (February 2023) Total Blocking Time determines 30% percent of the overall Lighthouse Performance score.

The performance subscore for Total Blocking Time is visible in DebugBear for example:

Performance score breakdown in DebugBear

How to optimize Total Blocking Time

To improve Total Blocking time you can collect a performance profile in DevTools and optimize your application code. You can also review the impact of third-party scripts and split up long blocking tasks into smaller ones.

Identify the cause of CPU activity

Look at a CPU timeline recording, for example in Chrome DevTools. What parts of your code are causing the long tasks?

Review third-party scripts

Third-party code like chat widgets or A/B testing tools can add a large amount of CPU processing to your page. Consider if some of them can be removed, or if they can be lazy loaded when they are needed.

Split up long tasks

Instead of running all JavaScript updates in one, consider doing the work in stages.

For example, if you're rendering a chart and a map, you could first render the chart and then wait 50ms before rendering the map. This way user input can be handled in the gap between the two rendering steps, and the page stays responsive throughout.

Speed up your code

One way to reduce blocking time is to make your JavaScript code run faster. This will not only improve TBT, but also make your page load faster in general.

How to measure Total Blocking Time

Many different tools can help you measure and optimize TBT:

  • Chrome DevTools
  • Google's Lighthouse and PageSpeed Insights tools
  • DebugBear's speed test
  • Using the Long Tasks API

Long Tasks and Total Blocking Time in Chrome DevTools

Create a recording in the Chrome DevTools Performance tab to view long tasks and Total Blocking Time.

Long tasks are marked by a triangle in the top right corner of the task marker. Blocking time is indicated using red stripes.

Total Blocking Time in Chrome DevTools

You can find the Total Blocking Time for the page in the bottom right corner.

Click on each task to view what code caused it to take a long time.

Total Blocking Time in Lighthouse and PageSpeed Insights

TBT is one of the main metrics shown at the top of each Lighthouse report. You can run Lighthouse on PageSpeed Insights, or in the Chrome DevTools Lighthouse tab.

Total Blocking Time metric in Lighthouse

Each Lighthouse report also includes a list of long tasks, and what source file they can be attributed to.

Long Tasks in Lighthouse

Total Blocking Time in the DebugBear speed test

You can use the DebugBear website speed test to check TBT and other metrics on your website.

After running the test you can click on the Total Blocking Time metric to view additional details and find opportunities to improve page speed.

Total Blocking Time in the DebugBear test result

Long Tasks API

The Long Tasks API allows you to access long tasks from JavaScript running on the page.

Here's how you can calculate total blocking time:

var totalBlockingTime = 0;
var observer = new PerformanceObserver(function (list) {
let perfEntries = list.getEntries();
for (const perfEntry of perfEntries) {
totalBlockingTime += perfEntry.duration - 50;
}
console.log({ totalBlockingTime });
});
observer.observe({ type: "longtask", buffered: true });

The console output will show the blocking time in milliseconds. (If buffered: true isn't working for you, try using a newer version of Chrome. Chrome 90 always works for me.)

{ totalBlockingTime: 317 }

You can use this to capture real-user metrics about your page.

The full performance entry data looks something like this.

[
{
"name": "self",
"entryType": "longtask",
"startTime": 826.6750000184402,
"duration": 115,
"attribution": [
{
"name": "unknown",
"entryType": "taskattribution",
"startTime": 0,
"duration": 0,
"containerType": "window",
"containerSrc": "",
"containerId": "",
"containerName": ""
}
]
},
{
"name": "same-origin-descendant",
"entryType": "longtask",
"startTime": 17693651.6000001,
"duration": 67,
"attribution": [
{
"name": "unknown",
"entryType": "taskattribution",
"startTime": 0,
"duration": 0,
"containerType": "iframe",
"containerSrc": "",
"containerId": "intercom-frame",
"containerName": ""
}
]
}
]

Monitoring Total Blocking Time

DebugBear can keep track of Total Blocking Time, page speed, and Core Web Vitals.

The page Overview tab shows longer term trends for your website as well as a detailed analysis.

TBT overview

You can also find Total Blocking Time in the project dashboard.

TBT trendlines

Start a free 14-day trial today.