Blog Engineering Total Blocking Time - The metric to know for faster website performance
Published on: February 14, 2023
6 min read

Total Blocking Time - The metric to know for faster website performance

Learn how to identify and fix some root causes for high Total Blocking Time.

tbt_cover_image.jpg

Our world overwhelms us with information that is more accessible than ever. The increasing rates of content production and consumption are gifts that keep on giving. We can't seem to keep up with the information thrown at us. We're limited by our cognitive limitations and time constraints, and a recent study concluded the result is a shortening of attention spans. Websites are no exception.

Users who interact with your website want feedback, and want it fast. Preferably immediately! Website performance has become an important factor in keeping users engaged. But how do you measure how unresponsive a page is before it becomes fully interactive?

Many performance metrics exist, but this blog post focuses on Total Blocking Time (TBT).

What is Total Blocking Time?

TBT measures the total amount of time tasks were blocking your browser's main thread. This metric represents the total amount of time that a user could not interact with your website. It's measured between First Contentful Paint (FCP) and Time to Interactive (TTI), and represents the combined blocking time for all long tasks.

What is a long task?

A long task is a process that runs on the main thread for longer than 50 milliseconds (ms). After a task starts, a browser can't interrupt it, and a single long-running task can block the main thread. The result: a website that is unresponsive to user input until the task completes.

After the first 50 ms, all time spent on a task is counted as blocking time. This diagram shows five tasks, two of which block the main thread for 140 ms:

A diagram containing five tasks, two of which are blocking the main thread. The TBT for these tasks adds up to 140 ms.

How can we measure TBT?

Many tools measure TBT, but here we’ll use Chrome DevTools to analyze runtime performance.

As an example: We recently improved performance on GitLab's View Source page. This screenshot, taken before the performance improvement, shows eight long-running tasks containing a TBT of 2388.16 ms. That's more than two seconds:

A screenshot indicating that there are eight long-running tasks. The TBT of these tasks adds up to 2388.16 ms.

How can we improve TBT?

As you might have guessed by now, reducing the time needed to complete long-running tasks reduces TBT.

By selecting one of the tasks from the previous screenshot, we can get a breakdown of how the browser executed it. This Bottom-Up view shows that much time is spent on rendering content in the Document Object Model (DOM):

A screenshot of the Bottom-Up view of one of tasks from the previous screenshot. It indicates that most of the time is being spent on rendering content in the DOM.

This page has a lot of content that is below the fold – not immediately visible. The browser is spending a lot of resources upfront to render content that is not even visible to the user yet!

So what can we do? Some ideas:

  • Change the UX.
    • Add a Show More button, paging, or virtual scrolling for long lists.
  • Lazy-load images. (example)
    • Lazy-loading images reduces page weight, allowing the browser to spend resources on more important tasks.
  • Lazy-load long lists. (example)
    • Similar to lazy-loading images, this approach allows the browser to spend resources on more important tasks.
  • Reduce excessive HTML. (example)
    • For example, when loading large pages consider removing unnecessary content. Or, consider rendering some content (like icons) with CSS instead.
  • Defer rendering when possible.

Frameworks such as VueJS and React are already heavily optimized. However, be mindful of how you use these frameworks to avoid expensive tasks.

Change VueJS usage to improve TBT

This screenshot shows the Bottom-Up view of a task. Much of the task time is spent on activities from third-party code in the VueJS framework:

A screenshot of the Bottom-Up view of one of tasks. It indicates that a lot of the time is being spent on activities in the third-party VueJS framework.

What improvements can we make?

  • Use Server-side rendering (SSR) or streaming for pages that are sensitive to page load performance.
  • If you don't need Vue, don't use it. Component instances are a lot more expensive than using plain DOM nodes. Try to avoid unnecessary component abstractions.
  • Optimize component props. Child components in Vue update when at least one of their received props are being updated. Analyze the data that you pass to components. You may find that you can avoid unnecessary updates by making changes to your props strategy.
  • Use v-memo to skip updates.
    • In Vue versions 3.2 and later, v-memo enables you to cache parts of your template. The cached template updates and re-renders only if one of its provided dependencies changes.
  • Use v-once for data that does not need to be reactive after the initial load. (example)
    • v-once ensures the element and component are only rendered once. Any future updates will be skipped.
  • Reduce expensive tasks in your Vue components. Even a small script may take a long time to finish if it’s not optimized enough. Some suggestions:

Results and methods

By using three of the methods suggested above, we reduced TBT from about 3 seconds to approximately 500 ms:

A chart indicating a drop in TBT from ~3 seconds to ~500 milliseconds.

What did we do?

Remember, the size of the decrease always depends on how optimized your app already is to begin with.

There is a lot more we can do to improve TBT. While the specific approach depends on the app you're optimizing, the general methods discussed here are very effective at finding improvement opportunities in any app. Like most things in life, a series of the smallest changes often yield the biggest impact. So let's iterate together, and adapt to this ever-changing world.

“Adaptability is the simple secret of survival.” – Jessica Hagedorn

Cover image by Growtika on Unsplash

We want to hear from you

Enjoyed reading this blog post or have questions or feedback? Share your thoughts by creating a new topic in the GitLab community forum. Share your feedback

Ready to get started?

See what your team could do with a unified DevSecOps Platform.

Get free trial

Find out which plan works best for your team

Learn about pricing

Learn about what GitLab can do for your team

Talk to an expert