Optimizing the Core Web Vitals
Web Vitals is Google Project to provide Website Owners, Developers, SEOs with unified guidance for quality signals that are essential to delivering a great user experience on the web.
Web Vitals helps you quantify the experience of your site and identify opportunities to improve them. As of now, Google has announced three Core Web Vitals i.e. LCP (Largest Contentful Paint), FID (First Input Delay), and CLS (Cumulative Layout Shift).
Let us understand these Web Vitals first and then we'll learn to optimize them.
Core Web Vitals:
1. Largest Contentful Paint (LCP):
It measures the Page Loading Performance and marks the point in the page load timeline when the page's main content has likely loaded. In the optimal cases, LCP should occur within 2.5 seconds of when the page first starts loading.
2. First Input Delay (FID):
It measures the Interactivity and quantifies the experience users feel when trying to interact with unresponsive pages. To simplify, FID measures the time from when a user first interacts with a page either by clicking on a link, tapping on a button, or any other JavaScript-based functionality, to the time when the browser is actually able to begin processing event handlers in response to that interaction. In the optimal cases, pages should have an FID of less than 100 milliseconds.
3. Cumulative Layout Shift (CLS):
It measures Visual Stability. CLS measures the sum total of all individual layout shift scores for every unexpected layout shift that occurs during the entire lifespan of the page. A CLS score of less than 0.1 is considered to be optimal.
How to Optimize the Core Web Vitals?
Optimizing the Largest Contentful Paint (LCP):
Improving the LCP Score is all about making your main content render faster.
Some of the common issues that cause low LCP are:
- Slow Server Response Times
- Render-blocking JavaScript and CSS
- Slow Resource Load Times
- Client-Side Rendering
Slow Server Response Times: The page rendering time is in direct proportion to the time it takes a browser to receive content from the server which means the longer it takes a browser to receive content from the server, the longer it takes to render anything on the screen. A faster server response time directly improves every single page-load metric, including LCP and FCP.
The below-mentioned ways can be used to improve LCP by improving the Server Response Times:
- Optimize your server: Analyzing and improving the efficiency of your server-side code will directly improve the time it takes for the browser to receive the data. To speed up this process you can use the performance guidance for the web frameworks (For instance, React) that run on the servers.
- Route users to a nearby CDN: Use Content Delivery Networks(CDNs) to serve the request of the users who are far away from your main server. This ensures that your users won't have to wait unnecessarily for network requests and also, decreases the load of your main server.
- Cache assets: Static HTML pages don't need to be changed on every request, this is where Server-side caching can reduce the LCP and minimize resource usage.
- Establish third-party connections early: Requests to third-party connections also play a major role in impacting the LCP, especially when they're needed to display critical content on the page. Use rel="preconnect" to inform the browser that your page intends to establish a connection as soon as possible. Also, to resolve DNS lookups faster you can use rel="dns-prefetch"
Render-blocking JavaScript and CSS: Browser parses the HTML markup into a DOM tree, before rendering the page content and the parser will pause if it encounters any external stylesheets (<link rel="stylesheet">) or synchronous JavaScript tags (<script src="main.js">).
Make use of the below methods to speed up loading of the main content of your web page:
- Reduce CSS blocking time: Reducing the amount of blocking CSS will always improve the time it takes to fully render the main content of the page (LCP). This can be achieved in many ways:
1. CSS Minification: Minify or remove all the unused or unnecessary CSS files containing characters such as spacing, indentation, or comments, all these are unnecessary for the browser.
2. Defer Non-Critical CSS: Find all the unused CSS on your web page (You can use the Coverage tab in Chrome Dev Tools to find the used CSS). Remove those CSS completely or move it to another stylesheet if used on a separate page of your site. Load files Asynchronously.
- Reduce JavaScript-blocking Time: Serve only those Javascripts which are necessary to the users. You can accomplish this by, Minifying and Compressing JavaScript files, Deferring unused JavaScript, and Minimizing the unused polyfills.
Slow resource load times: Slow resources load time is mostly caused by these elements, <img> elements, <image> elements inside an <svg> element, <video> elements, bg img loaded via the url() function and other inline-level text elements.
To make sure these elements are loaded as fast as possible:
- Optimize and Compress Images
- Preload important resources
- Compress text files
- Deliver different assets based on the network connection (adaptive serving)
- Cache assets using a service worker
Client-Side Rendering: Most of the Javascript-based websites use client-side rendering and this causes serious issues in LCP loading time when the user has to wait for JS elements to be loaded fully and executed on the page.
A client-side rendering based website must do these optimizations to make their LCP Optimal:
- Minimize Critical JavaScript: Reduce as much critical JavaScript elements as possible from the page. User Interaction can be seriously impacted if there is a certain amount of critical Javascript code that needs to be loaded so that the user can interact with the page.
- Use Server-Side Rendering: Make use of server-side rendering. In Server-Side rendering, Server-side sends a fully rendered page to the client and the client's JavaScript bundle takes over and allows the SPA framework to operate.
- Use Pre-Rendering: A Prerender intercepts a page request to see if the user-agent viewing your site is a bot and if the user-agent is a bot, the prerender middleware will send a cached version of your site to show with all JavaScript, Images, etc are rendered statically. If the user-agent is anything but a bot, then everything is loaded as normal, prerendering is only used to optimize the experience for bots only.
Optimizing the First Input Delay (FID):
Improving the FID Score is all about making your User Interactions Faster.
The main reason for poor FID is Heavy Javascript Execution. The more the javascript elements are there on the page the poor will be FID. Optimizing the Javascript compilation, parsing and execution helps in reducing the FID.
To improve FID you can apply the below methods:
- Split up Long Tasks
- Optimize your page for Interaction Readiness
- Use a Web Worker
- Reduce JavaScript Execution Time
Split up Long Tasks: Any piece of code that blocks the main thread for 50 ms or more can be characterized as a Long Task. These long tasks make the UI unresponsive. Breaking down the long tasks into smaller code and asynchronous tasks reduces the input delay on the site and significantly reduces the FID.
Optimize your page for Interaction Readiness: The delay in the interaction is majorly due to the following reasons:
1. First-party script execution: Heavy script execution times and inefficient chunking slows down how soon a page can respond to user input and impact FID. Progressive loading of code and features can help spread this work out and improve interaction readiness. Large scrpts from re-hydration to wire up event listeners may several hundred milliseconds or even few seconds to load, in these cases, consider shifting more logic server-side or generating more content statically during build time.
2. Data-fetching: JavaScript and Data fetches for components can impact interaction latency. We should minimize the reliance on cascading data fetches, so that FID can be improved.
3. Third-party script execution: Third-party tags and analytics can keep the network busy and make the main thread periodically unresponsive, impacting interaction latency. Prioritize loading the elements that offers the greatest value to the users first.
Use a Web Worker: One of the main reason for a poor FID Score is blocking the main thread. In these cases Web workers helps in separating the main thread from the non-UI threads and JS threads. Separating the non-UI operations from the main thread cuts down the blocking time and consequently improve FID.
Reduce JavaScript execution time: Serve only those Javascripts which are necessary to the users. You can accomplish this by, Spillting the Code, Minifying and Compressing JavaScript files, Deferring unused JavaScript, and Minimizing the unused polyfills.
Optimizing the Cumulative Layout Shifts (CLS):
Improving the CLS is associated with optimizing sudden layout shifts to improve user-experience.
The CLS is impacted mostly due to the below reasons:
- Images without dimensions
- Ads without dimensions
- Dynamically injected content
Images without dimensions: Always include the dimensions i.e. height and width size attributes to your Image and Video Elements. Specifying the size attributes ensures that the browser allocates the correct amount of space in the document while the graphics load.
Ads without dimensions: Publishers mostly keep the Ads size dynamic which contributes to the poor CLS. This can be optimized by:
1. Statically reserving the spot for the Ad Slot: Statically style slot DOM elements with the same sizes passed to your tag library. This can help ensure the library doesn't introduce layout shifts when it loads.
2. Avoid placing ads near the top of the viewport: Ads that are at the top have more content as compared to the ones that are at lower down, meaning more elements move when the ad causes a shift. That's why keeping ads near the middle of the viewport will ensure that there are less layout shifts.
Dynamically injected content: Avoid inserting new content above existing content (For eg, "Sign-up to our newsletter" or "Install our [iOS/Android] app", etc.), unless in response to a user interaction. This ensures any layout shifts that occur are expected. If you need to display these types of UI affordances, reserve sufficient space in the viewport for it in advance, so that it doesn't cause any layout shifts.