Home > Posts > Web Page Optimisation for Front-End Developers.

Web Page Optimisation for Front-End Developers.

Mohit Ranjan
Mohit Ranjan
Cover Image for Web Page Optimisation for Front-End Developers.
Mohit Ranjan
Mohit Ranjan

There are a lot of things that we think about when we are building content-based web platforms to ensure that what we create reaches more and more users every day. In fact, some organizations with content-based platforms even track down the algorithms that Google uses to improve search results. In addition to tracking down algorithms, and matching the relevance of the most trending topics on the web, there are many other factors that make sure that our content shows up at the top of Google’s search results. These factors include the server’s response time, the layout shifts, the distances between adjacent DOM elements and much more.

In this article, we’re going to learn about the technical aspects of SEO, and how to significantly improve it, so that Google appreciates us, and as a thank you, shows our content at the top of the search results. My goal is to provide you with an on-point solution.

Let us start with the Web Vital Scores. Web vital scores can be measured using a few tools I am mentioning below.

  1. Lighthouse by Google
  2. PageSpeed
  3. GTMetrix

Now, you are probably thinking that Lighthouse is the best tool to measure your core web vital score because it is created by Google and after all, who are you trying to impress?

Yes, you are right, but inexperienced users often make mistakes and get incorrect readings.

Please note that the dev tool should be disconnected from the window when running the desktop diagnostics tool in chrome.

We do this to ensure that diagnostic runs on the full screen for the website.

Most of us have good internet connections, so we may have a slightly higher web vital score. However, this is not always the case. Therefore, it is recommended that you run diagnostics once you enable 3G throttle.

I personally prefer PageSpeed over GTMetrix when it comes to web page speed testing. I prefer PageSpeed because it provides a full recording of the page loading.

Let's now take a look at each parameter one at a time.

Alt text

These terms may be hard to read from the docs because they refer to a lot of different things. I’ve tried to explain them in the simplest way possible, but if you’re really interested in understanding how they’re calculated by page speed using javascript, you’ll need to check out the docs.

First Contentful Paint: The time for the first content to be visible in the viewport.

Speed Index: How quickly content shows up.

Largest Contentful Paint: Time taken by slowest element to load.

Time to interactive: Time taken by a page to become fully interactive

Total Blocking time: Time taken by third party scripts to load.

Cumulative layout shift: How much elements shift due to late loading of adjacent elements.

All of these parameters are linked with how different elements of a page loads, and some of them are even directly linked to the code in backend. But most of them can be imoproved from front end and we’ll go through it one by one for each parameter.

First Contentful Paint As we know that the FCP measures time taken by first element to show up in viewoport. The elements that could show up are raw html elements and in most cases, the FCP elements are the texts. For texts every website has their own font faces and they are called from several font CDNs and might take time to load in viewport. Until then we must show the user a default font and that could be done by adding a line to your font-face code.

@font-face {
font-family: 'Pacifico';
font-style: normal;
font-weight: 400;
src: local('Pacifico Regular'), local('Pacifico-Regular'), url(https://fonts.gstatic.com/s/pacifico/v12/FwZY7-Qmy14u9lezJ-6H6MmBp0u-.woff2) format('woff2');
font-display: swap;

The ‘font-display’ property causes your browser to display a ‘default font’ until the ‘font-face’ is loaded.

Render blocking resources are another issue that causes higher FCP. These are scripts that load ahead of DOM and cause users to have to wait for the content to load.

In order to fix this, you need to understand how DOM scripts and links load. For example, you need to make sure that webengage has a lower priority so it can load after rendering DOM, but that scripts like jQuery need to be loaded before the main script.

The third type of warning you may see is the ‘critical chaining’ that font CDNs cause. This is where the requests are chained to a specific link or script. You can fix this by using rel = 'preload' wherever you are calling these scripts or links.

<link rel="preload" as="font" href="https://fonts.gstatic.com/s/roboto/v15/97uahxiqZRoncBaCEI3aWxJtnKITppOI__IvcXXDNrsc.woff2" type="font/woff2" crossorigin />

Speed Index and Time to Interactive This is something that is really frustrating to fix in a large codebase because the only way to fix it from front end is to improve the javascript execution time. So in this case you’ll relate to a famous quote soulfully, “prevention is better than cure”. So think twice or even more while adding up the new code in codebase, if it’ll block the main thread work or affect execution time badly. If you still want to fix it badly, here are the things to consider.

Laregst Contentful Paint As of now we know that LCP is time taken by the slowest element to load up in our website. There are a lot of factors affecting poor LCP scores in web page.

Image Elements The most common reason for poor LCP score is image elements. Ideally, images should be in certain formats for the web page. For example, Webp or SVG should be used. Webp is much better because it is usually 30% compressed than JPG or PNG images. SVG stands for Scalable Vector Graphics, but you can think of it as CSS. Make sure that images are also served after compression. Cloudinary can be used to serve these images.

In addition to using these formats, you should also make sure that images on the web page should only be loaded when they are visible in the viewport. This is known as lazy-loading.

You can achieve this behaviour by using the intersection observer API by using javascript. The intersection observer is similar to the 'The watcher' in Marvel comics. They observe the element, the distance from the viewport, the amount of scrolling, whether or not the element intersects with the viewport, and much more.

I am attaching the code for lazy loading, but you should read more about it.

// HTML element code
<img src="" data-src="image1.jpg" class="lazy-loaded-image lazy" />
<img src="" data-src="image2.jpg" class="lazy-loaded-image lazy" />
// Javascript code
const lazyImages = document.querySelectorAll(".lazy-loaded-image.lazy");
let lazyImageObserver = new IntersectionObserver(function(entries, observer) {
  entries.forEach(function(entry) {
    if (entry.isIntersecting) {
      let lazyImage = entry.target;
      lazyImage.src = lazyImage.dataset.src;
// Asking Intersection observer to observe each image element.
lazyImages.forEach(function(lazyImage) {
  1. **Youtube Iframes : ** Sometimes we add youtube references as iframe elements and that takes up about 500ms to load even on a good network. To fix this we need to think of a way to load the iframes on user interaction. Youtube has an attribute called srcdoc for this. This attribute adds up a facade over the iframe and when user clicks on it, the video loads up. Here is an example.
<iframe width="853" height="480" src="https://www.youtube.com/embed/4PUHBL1vMNY" title="Classical Music for When You’re on a Deadline" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"   srcdoc="<style>*{padding:0;margin:0;overflow:hidden}html,body{height:100%}img,span{position:absolute;width:100%;top:0;bottom:0;margin:auto}span{height:1.5em;text-align:center;font:48px/1.5 sans-serif;color:white;text-shadow:0 0 0.5em black}</style><a href=https://www.youtube.com/embed/4PUHBL1vMNY?autoplay=1><img src=https://img.youtube.com/vi/4PUHBL1vMNY/hqdefault.jpg ><span>▶</span></a>" allowfullscreen>

Total Blocking Time Total blocking time is also mostly affected by javascript code execution but there is more to it. You need to split up the javascript so that only needful code shows up to browser while loading the web page. Besides code management there is one small thing. You need to add a viewport meta tag

<meta name="viewport" content="width=device-width, initial-scale=1" />

Adding this saves you upto 300ms of loading time. Make sure you don’t use inefficient code statements and close eventListeners after usage. Also use querySelectorAll statements effeciently as some of us like to call literally every DOM element by writing poor DOM manipulation objects. Make sure you just call the ones you need to manipulate.

Cumulative Layout Shift This is one of the most obvious issues. Instead of trying to fix this directly, I would recommend throttling the web pages on 2G or record the page and watch it slowly. You need to be able to see the web page to understand what element is changing and what is causing this. Below are a few issues I came across while fixing this:

Client side renders elements dynamically after loading the document or when the user is interacting with the document.

Server side renders all your document along with your content and images. By sending all the elements at once, layout shifts and more are avoided.

Content pages should always use server side rendering.

Images Like other elements, images (especially ads) can push others to the backburner and cause poor CSS C++ scores. Use explicit heights for images as well. However, explicit heights can also cause issues as most of the time images are very responsive. To avoid this, we can use the min-height in CSS to fix the minimum height for the image element while also allowing the maximum height to be anything. In content type pages, make sure that the image dimensions are consistent across all pages.

Advertising In the case of ads which are totally controlled via APIs, we need to fix space so that if they appear after all other elements, they do not push away their adjacent elements. Use media queries if the given height causes extra height and looks ugly in different devices. These were some of the solutions to improve web vital scores, I’ll keep adding as I come up with more. Until then keep hustling.