Select a language
List of Core Web Vitals Recommendations (Part 1)
List of Core Web Vitals Recommendations (Part 1)
After a long search for interesting, and most importantly, understandable information on optimizing a web application, I came across an article written by a developer from Google. It is almost entirely devoted to the most effective ways to optimize Core Web Vitals indicators.
Over the years, the guys from Google have been giving web developers a lot of recommendations to improve performance.
Although each of these recommendations individually can improve performance. For many sites, the full set of recommendations is admittedly too large. And no one person or website can follow them all.
If web performance isn't your daily job, it's probably not obvious which recommendations will have the most positive impact on your site. For example, you may have read that implementing mission-critical CSS can improve loading performance, and you may also have heard that it is important to optimize your images. But if you don't have time to work on both things, how would you decide which one to choose?
The Chrome team has spent the last year trying to answer the question: what are the most important recommendations you can give developers to help them improve performance for their users?
To adequately answer this question, it is necessary to take into account not only the technical advantages of this recommendation, but also the human and organizational aspects that affect the likelihood that developers will actually be able to accept these recommendations. In other words, theoretically some recommendations can be very effective, but very few sites will have the time or resources to implement them. Similarly, some guidelines are crucial, but most websites already follow these practices.
In short, it is necessary that the list of the best web performance recommendations be focused on:
recommendations that will have the greatest impact on the real world;
recommendations that are most relevant and applicable to most sites;
recommendations that are realistic for most developers.
Over the past year, a lot of time has been spent checking the entire set of performance recommendations and evaluating each of them (both qualitatively and quantitatively) according to the three above criteria.
This post outlines the main recommendations for improving performance for each of the Core Web Vitals metrics. If you are new to web performance or trying to decide what will give you the most return on the money spent, then these recommendations are the best place to get acquainted.
Largest Contentful Paint (LCP)
The first set of recommendations refers to the Largest Contentful Paint (Loading the main content) (LCP), which is an indicator of loading performance. Of the three Core Web Vitals LCP indicators, this is the one that the largest number of sites are struggling with — only about half of all sites on the internet today meet the recommended threshold — so let's start with it.
Make sure that the LCP element can be detected from the HTML source.
According to the web almanac of 2022, prepared by HTTP Archive, 72% of mobile pages have an image as an LCP element, which means that in order to optimize LCP, most sites need to ensure that these images are loaded quickly.
What may not be obvious to many developers is that the time it takes to load an image is only part of the problem. Another important part is the time before the image is uploaded, and the HTTP archive data shows that in fact many sites do not comply with the norms.
In fact, of the pages where the LCP element was an image, 39% of these images had original URLs that could not be detected from the source of the HTML document. In other words, these URLs were not found in standard HTML attributes (such as <img src="..."> or <link rel="preload" href="...">), which would allow the browser to quickly detect them and immediately start downloading.
As a rule, if your LCP element is an image, then the URL should always be discoverable from the HTML source. Here are some tips on how to make this possible:
Upload an image using the <img> element with the src or srcset attribute. Don't use non-standard attributes like data-src that require JavaScript to render, as it will always be slower. 9% pages hide their LCP image behind data-src.
Try using server-side processing (SSR) rather than client-side processing (CSR), since SSR implies that the full page markup (including the image) is present in the HTML source code.
If your image needs to be referenced from an external CSS or JS file, you can still include it in the HTML source code using the <link rel="preload"> tag. Please note that images referenced by embedded styles cannot be detected by the browser's preload scanner, so even if they are found in the HTML source code, their detection may be blocked when loading other elements, so preloading may help in these cases.
To help you understand if there are problems with detecting your LCP element, Lighthouse will release an updated version 10.0 (expected in January 2023).
Detecting an LCP element from an HTML source can lead to measurable improvements, and also opens up additional opportunities for determining the priority of the element, which is the next recommendation.
LCP Priority
Make sure that the LCP element can be detected from the HTML source code - this is the first important step in ensuring that the LCP element can start loading earlier, but another, equally important step is to make sure that loading this element takes priority and is not queued for a bunch of other, less important elements.
For example, even if your image is present in the HTML source code using the standard <img> tag, if your page includes many <script> tags in the <head> of your document before this <img> tag, then it may take a long time before the image starts.
The easiest way to solve this problem is to give the browser a hint about which elements have the highest priority by setting a new fetchpriority="high" attribute in the <img> or <link> tag that loads your LCP image. This tells the browser to load it earlier rather than waiting for these scripts to finish.
According to the web almanac, only 0.03% of sites use this new API. This means that most sites on the internet have many opportunities to improve LCP with minimal effort. Although the fetchpriority attribute is currently only supported in Chromium-based browsers, this API is a progressive enhancement that other browsers simply ignore, so we strongly recommend developers to use it now.
For browsers other than Chromium, the only way to ensure the priority of the LCP element over other elements is to specify it earlier in the document. Again using the example of a site with a lot of <script> tags in the <head> of the document. If you want your LCP element to have priority, then you can add <link rel="preload"> before any of these scripts, or move these scripts below <img>, later to <body>. Although it works, it's less convenient than using fetchpriority, so we hope other browsers will add support soon.
Another important aspect of prioritizing the LCP element is the absence of any actions that may lead to a decrease in its priority, for example, adding the loading="lazy" attribute. Today 10% pages actually set loading="lazy" on their image. Beware of image optimization solutions that indiscriminately apply the delayed loading behavior to all images. If they provide a way to override this behavior, be sure to use it for the LCP element.
Delaying non—critical elements is another way to increase the relative priority of an LCP element. For example, scripts that do not control the user interface, such as analytics scripts or social media widgets, can be postponed until the 'load’ event is triggered. This ensures that they will not compete with other critical elements (such as LCP images).
To summarize, you should follow these guidelines to ensure the earliest possible loading of the LCP element and its high priority:
- Add fetchpriority="high" to the <img> tag, which is an LCP element. If the LCP element is loaded via the <link rel="preload"> tag, don't worry, because you can also set fetchpriority="high" for it!
- Never set loading="lazy" in the <img> tag of your LCP element. This will reduce the priority of the image and delay the start of its loading.
- If possible, postpone non-critical elements. This is done by moving them to the end of the document (using the built-in lazy loading of images or frames) or by loading them asynchronously via JavaScript.
Use CDN to optimize documents and TTFB elements
The previous two recommendations focused on ensuring that your LCP element is detected early and prioritized so that it can start loading immediately. The last part of this puzzle is to ensure that the initial response to the document is received as quickly as possible.
The browser cannot start loading any elements until it receives the first byte of the initial response of the HTML document, and the sooner this happens, the sooner everything else will start happening.
This time is known as Time to First Byte (TTFB), and the best way to reduce TTFB is:
Transmit content as close to your users as possible (geographically)
Cache this content so that the recently requested content can be downloaded quickly again.
The best way to do both of these things is to use CDN. CDNs distribute your resources to edge servers scattered around the world, thereby limiting the distance that these resources must travel across the network to your users. CDNs also often have detailed caching controls that can be customized and optimized for the needs of your site.
Many developers are familiar with using CDNs to host static resources, but CDNs can also serve and cache HTML documents, even those that are created dynamically.
According to the web almanac, only 29% requests for HTML documents were served via CDN, which means that sites have significant opportunities for additional savings.
Here are some tips for setting up a CDN:
Consider increasing the content caching time (for example, is it really important that the content is always fresh?).
Consider also caching content indefinitely and then clearing the cache if/when you do an update.
Find out if you can move the dynamic logic currently running on the source server to the periphery (a function of most modern CDNs).
In general, any time you can serve content directly from the periphery (avoiding going to the source server), it wins in performance. And even in cases where you need to go all the way to the source server, CDNs are usually optimized to make it much faster, so that's a plus anyway.
This was the first part of our immersion in the issue of optimizing a web application. In the next part, we'll talk about Cumulative Layout Shift (CLS), back/forward cache, animations/transitions in CSS, First Input Delay (FID), refactoring unused JavaScript.