Why should you even bother with UX as an engineer, isn't that what designers are paid for?
Today the user experience lies at the forefront and is the biggest defining quality for the value of a product. You can't have a product that is slow to load, with constant layout shifting and unstable elements, as these hurt the user's overall experience. So to address these problems we have to monitor and optimize for certain metrics during the whole lifecycle of the product. To monitor these metrics we use core web vitals
What are Web Vitals
Web Vitals is an initiative by Google to provide unified guidance for quality signals essential to delivering a great user experience on the web.
Google provides several tools, usable directly from your Chromium browser or other external tools., that can help identify the metrics that matter the most, which are known as core web vitals
The core web vitals include:
LCP (Largest Contentful Paint): It gives us the time taken to render the largest object/image/text block on the page(visible in the viewport), since the time, the user navigated to the page.
CLS (Content Layout Shift): It gives us the value of the largest change in layout that occurs during the entire lifecycle of the page
INP (Interaction to Next Paint): INP asses the overall responsiveness to user interaction( not screen size problem), observing the latency of mouse/keyboard clicks and other user interactions, the interaction with the worst latency defines the value of INP
Let's discuss about two of these metrics, LCP and CLS one by one in detail
But how do you calculate these web vitals?🧐
If it is a web app you can directly use chrome’s lighthouse tool, to calculate values of web vitals, or else you can use this javascript library for ‘web-vitals’, for apps like which are being run inside an iframe or any other kind of sandboxed environment inside a browser.
Largest Contentful Paint (LCP)?
For this first we need to understand what LCP is, LCP reports the render time of the largest image or text block visible in the viewport, relative to when the user first navigates to the page. A good LCP score is when your LCP is 2.5 seconds or less. Technically LCP score is the 75th percentile of page loads, across all devices.
Elements considered for LCP
<image> (element inside svg)
<img>
<video>
url() (css being used for loading image in background)
block-level elements loading texts or inline texts
Optimizing for LCP -
While there's no single approach, these fundamental techniques can be useful:
Using Lazy Loading: Helps in delaying the downloading of the media not present in the viewport
Utilizing a CDN (Content Delivery Network) for static assets significantly improves LCP (Largest Contentful Paint) by reducing the time it takes to deliver assets. CDNs distribute content across multiple servers, allowing assets to be loaded from a server geographically closer to the user, reducing latency. Webp-based images are a superpower as they are small in size.
Use Hashes in File Names with Cache-Control By using hashed file names with cache control headers, you ensure that assets are only re-downloaded when changes are made. This reduces unnecessary requests and ensures that users always get the most up-to-date resources, improving LCP by minimizing revalidation. Big Companies like shopify use this to make sure the fastest delivery and only the latest version gets delivered to the user Example - You are to serve a style.css file from your server, make sure its name is not style.css but style<some_hash>.css, which changes after each file update, this is done so that every time the file updates, a new hash is created, which makes it a new file name for browser, and it doesn't use the previously cached on ( though our typical react/next builds, automatically create hashed files for our static files).
Investigate and Optimize Network Requests Analyzing the network terminal helps identify slow or redundant requests. Reducing or optimizing these requests can decrease the time needed for the browser to render the page's largest content, directly improving LCP.
Remove Unnecessary Frontend Requests Removing or deferring non-essential frontend requests reduces the overall load on the network, allowing critical resources to load faster. This prioritization enhances LCP by ensuring that the main content is rendered promptly.
Optimize Database Queries Streamlining database queries can drastically reduce server response times. Efficient queries ensure that the server can deliver necessary data faster, which contributes to a quicker LCP as the page can render its largest element sooner.
Increase Inline Requests from Frontend Increasing inline critical CSS and JavaScript within the HTML reduces the number of render-blocking resources. With fewer external requests, the browser can render the page faster, improving LCP.
Run Background Tasks for Non-Essential Operations Ensuring that the server focuses solely on delivering the web page while offloading other tasks to background processes prevents delays in page rendering. This prioritization ensures that the LCP is not hindered by non-critical server tasks.
Content Layout Shift(CLS)?
First, we need to understand what CLS is, CLS is a measure of the largest burst of layout shift scores for every unexpected layout shift that occurs during the entire lifecycle of a page.
A layout shift occurs any time a visible element changes its position from one rendered frame to the next.
For a good user experience, sites should strive to have a CLS score of 0.1 or less. To ensure you're hitting this target for most of your users, a good threshold to measure is the 75th percentile of page loads, segmented across mobile and desktop devices.
Simply put, CLS occurs when divs jump unexpectedly, To calculate the layout shift score, the browser looks at the viewport size and the movement of unstable elements in the viewport between two rendered frames. The layout shift score is a product of two measures of that movement: the impact fraction and the distance fraction.
What causes these movements in div👁️👁️:
Dynamic pages take some time to load the content, and the div in which the content is loaded also does not have a fixed size. You can use skeletons, but even they will have a layout shift if they are not of the exact size as that of the resultant div. Screen size changes also affect this variedly
Optimizing for CLS
There are no steps or paths to follow for CLS at least in my experience till now, or some practices, what you need to do is iteratively work on decreasing the delta in change of layout
First principle Techniques you can use
Using a skeleton, to be closest to the resultant layout, your design should also allow, the first page of the app, to have a fixed layout at least for the viewport, so that you can give a much better skeleton for it.
Using Loaders, these should be used rather carefully, as they will result in a definite layout shift, it's just that they indicate the user of the loading state. a smart way to use loader is to use it on secondary pages/states, like when clicking on a button requires a redirection to another page/state which requires an API call to render information, rather than using a skeleton on a secondary page/state, make a loader on the button you pressed, give the loading state to current page, make the API call get the data, and when the page is ready only then redirect user, and since the final page will be loaded directly there will be no layout shift.
Make sure there is no element on the page, which is unstable and moves with the viewport
The size(aspect ratio) of image and other media should be constant, they should not change with time, or when it gets completely loaded, affects the layout shift adversely.
Additional Tips -
Optimization for web vitals is an iterative process, and heavily context-dependent, you can also take the help of softwares like mixpanel, etc, to know which page is visited most often and can optimize your APIs and design systems while keeping that in mind
Do not do regular deployments of frontend applications, as you are usually serving your application pages from CDN, but they need to be invalidated due to regular deployments. A new asset needs to be served, which will require your server to deliver the page, this interference from the server can increase LCP. Reasoning: Even if your files are hashed, and you do very frequent deployments the first time the static files are called on the browser they will take more time then cached ones, and all of users will be required to download the latest files, maybe with just more planned product lifecycle you can avoid these very frequent deployments and save some time there.
Try testing your pages on slow network speed (you can do this directly on chrome from network tools), will help you discover key breakages in your app, which usually get missed since we are working with good internet
Make sure your artifacts are the smallest possible in size, as it always helps to have a lighter page
Conclusion
Maintaining these metrics within specific thresholds is essential, to make sure your application’s SEO score is good and it ranks high and also from the perspective of general user experience
If you are an app developer, who develops apps for platforms like, app store, play store, shopify app store, then this is something you must be careful about, as they take these metrics under consideration not only while reviewing your app for publishing but also for giving it badges and featuring it on their platforms.
There is a lot more to discuss regarding the two of these, but that will need a separate blog of its own, so till then stay tuned 🤗