Measuring performance with Web Vitals and React

JavaScript React

In this blog, we’ve discussed measuring and improving our performance using the Lighthouse audits. Google continued by introducing new tools that emphasize performance. Some time ago, they introduced the Web Vitals standard. In this article, we go through it and provide examples of measuring the Web Vitals metrics with React.

Introducing Web Vitals

There are many factors Google takes into account when indexing our page. Measuring performance is becoming a part of Search Engine Optimization more and more. The goal of Web Vitals is to provide clear guidance on what metrics matter and how to measure them.

The idea behind Web Vitals is that we can measure them on real users interacting with the page. The results can vary based on the network conditions or the device’s capabilities. Even if we develop our website on the latest hardware, our users might still use old phones and computers, and it is essential to accommodate that when performing our tests.

The way our users perceive the performance is not limited to the loading time. It seems to load faster if a page renders content even before the loading is finished. Also, a page not responsive when the user interacts with it gives an impression of poor performance and user experience.

The Web Vitals standard aims to measure all of the above. We can divide its metrics into two groups.

Core Web Vitals

Google marks the crucial parts of the Web Vitals standard as the Core Web Vitals. They currently focus on three aspects of the user experience: loading, interactivity, and visual stability.

Largest Contentful Paint (LCP)

The largest contentful paint reports the render time of the largest image or text block visible in the viewport. We should aim to have an LCP of 2.5 seconds or less.

Cumulative Layout Shift (CLS)

The cumulative layout shift detects sudden changes to the webpage. If a text or a link moves unexpectedly, we can end up clicking on something else by accident.

A layout shift occurs every time a visible element changes its position. CLS measures the largest burst of layout shifts where layout shifts occur rapidly, one after another. Google states that we should optimize our website for a CLS score of 0.1 or less.

First Input Delay (FID)

First input delay is the moment between the user first interacting with the page and the browser beginning to process the event handler in response. In simpler terms, FID measures the delay in the event processing.

Google wants us to aim for the first input deal of 100 milliseconds or less.

Other Web Vitals

Besides the above crucial metrics, there are other parts of the Web Vitals standard that we should mention.

Time to First Byte (TTFB)

The time to the first byte measures the delay between the moment a user requests our page and when the first byte of the response arrives.

First Contentful Paint (FCP)

The first contentful paint measures the delay between when the page starts loading and when any part of the content is visible. Again, we should strive to have an FCP of 1.8 seconds or lower.

Measuring Web Vitals with Create React App

Google developed a web-vitals library to help us with measuring Web Vitals. When we create an application with Create React App, it uses web-vitals out of the box. Let’s use CRA so that we can investigate it.

When we do the above, we end up with an file that calls the function.


When we look into the file, we can see that it accepts a function.


Using the web-vitals library

An interesting part about the above code is that it loads the web-vitals library asynchronously only if we pass a function to . It means that even though Create React App uses web-vitals by default, it won’t increase the JavaScript bundle code we serve to our users if we don’t care about the metrics.

The web-vitals is very compact though and weights about 1K when served.

In the type, we can see that when we pass a function to , we get a bunch of information about the metric.

Creating a report handler

Create React App suggests that we start by using to view the reports.



The web-vitals library calls our every time a new metric value is available. Although, some of the metrics are not reported at the very beginning. For example, first input delay (FID) is not reported until the user interacts with the page.

Sending the metrics result

There are quite a few approaches we can choose from when it comes to gathering metrics. One way would be to create an endpoint that stores the metrics to analyze them later.


Above, we use instead of . It does not wait for a response and can send a POST request even if the user is navigating away from the website.

If you worry about browser compatiblity, you can first check if is available and use as a fallback.

Instead of creating our backend solution for metrics, we can use Google Analytics.


Above, we use the flag because our events don’t directly indicate that the user performed an action. Therefore, it doesn’t affect bounce rates that tell us if the user performed some actions before leaving our website.

The web-vitals library also suggests using the Google Tag Manager

The web-vitals library under the hood

Behind the scenes, the web-vitals library creates instances of the PerformanceObserver. We shouldn’t call the Web Vitals functions such as and more than once because the observer takes care of the metrics for the entire lifetime of our application.

After looking at, we see that the old browsers do not support the PerformanceObserver. If that concerns you, you can use a polyfill prepared by the authors of the web-vitals library. To do that, we need to import instead of and attach the contents of the into the section of our website.


In this article, we’ve gone through the Web Vitals initiative and explained various metrics that it involves. It includes the Core Web Vitals and metrics such as the first contentful paint. We’ve also inspected the code Create React App generates for us out of the box and how to handle the Web Vitals metrics. Finally, after studying how the web-vitals library works under the hood, we’ve concluded that we might need a polyfill if we care about the browsers such as the Internet Explorer.

With the changes Google makes to its algorithms, the performance of our page is getting more significant for SEO. Also, it is always a good thing to care about the user experience, and the performance is an integral part of how the users perceive our application. Because of that, it is worth exploring the Web Vitals standard.

Notify of
Inline Feedbacks
View all comments