Optimizing website? Careful with lazy loading!
Tags: seo, ux, webdev, webperf
Published: 2022-05-05 10:02:30

A few weeks ago I was asked if Accesto could help to **optimize a popular online store** selling natural cosmetics. Of course we can! I thought. That is what we do for a living, we improve existing web applications like SaaS, marketplaces, or eCommerce sites. Thus I thought it would be an optimization like every other. But it wasn’t.

## Quick wins for website speed

Although every online product is unique, they usually struggle with similar **web performance pitfalls**. Non-optimal database queries, poor caching, too large images/resources, or unused imports, to name a few. Usually, there are **a few things that can be fixed relatively quickly** and will result in quite a speed boost. Our CTO recently gathered such tweaks for you in his blogpost on [top 5 hacks to fix slow web applications](https://accesto.com/blog/top-5-hacks-to-fix-slow-web-applications/). 

Top performance, which will hold the exponential growth of users, cannot be achieved overnight. But if your website is slowing down, and you haven't yet put a lot of effort into its optimization, there is a high chance that it can be refined in a quite reasonable time. Like in one of our [recent stories](https://accesto.com/blog/my-homepage-is-slowing-down/) where we managed to **decrease website loading time by 97% in just 4 hours of work**.<br>

![Initial PageSpeed results](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tfeniuf04lw58o9bt6k0.jpeg) 

<center><i style="font-weight: 200;">Initial PageSpeed results for online store selling natural cosmetics</i></center><br>

The case of natural cosmetics eCommerce seemed similar. The store owner sent me an email on Friday morning with the Google PageSpeed Insights report. It **evaluated the overall site performance** on <span style="color:#F3A73B">61</span>/100 for desktop, and <span style="color:#ED5C4C">42</span>/100 for mobile. Not a tragedy, but indeed a lot of room for improvement. Great! We will apply a few quick tweaks that will speed up the website and I will have good news for a customer even before the weekend!

## Let’s start with a website audit & checking Core Web Vitals

We already knew the **overall score** for this website - our starting point for optimization. This score is a **composition of 6 metrics evaluated by PageSpeed**, which for that particular site presented like this:

](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/50jualml4g4hqdi74z7f.jpeg)
 

Quick look at the metrics and we see that **4 out of 6 metrics look fine** (<a href="https://web.dev/vitals/" target="_blank" rel="nofollow">Web Vitals</a>), but the remaining two: _Speed Index_ and _Largest Contentful Paint (LCP)_ seem way too high. Understanding these metrics helps to **decide where we shall start our optimization**, how much we should improve, and whether we can find some low-hanging fruits. Each of these **metrics has a different weight** (importance). To see how exactly they influence the overall score you can use the <a href="https://googlechrome.github.io/lighthouse/scorecalc/" target="_blank" rel="nofollow">scoring calculator</a>. 

![Lighthouse scoring calculator](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sapdl8ov2n0ya5u81n8n.jpeg)
 

Although PageSpeed evaluated both SI and LCP as poor ones, **LCP has a higher weight** (25%), so improving it **will have the highest impact on the overall score**. LCP is one of 3 important metrics introduced by Google, called **Core Web Vitals**. Ok, but what exactly is this LCP? In short - it is the **time at which the largest visible part of website content is painted**. This content could be an image, a large block of text, or any other element that occupies a significant part of the screen when the website loads. And the faster this element is displayed to the user, the better. 

Knowing that, we could assume that perhaps some product image or banner is too large, not scaled properly, or maybe not compressed. Or maybe images are served by PHP and not cached? Few basic checks should show us what is going on.

We used a Lighthouse tool built-in Chrome web browser to **profile the website**. We were looking for any performance pitfalls, but the audit results were… surprisingly good! **The site wasn’t performing that bad at all!** Server response time was quite decent, images were served in a modern format and with proper sizing. All the site assets were properly optimized and served with proper cache policy. They even used some of the Progressive Web App capabilities to make the site work smoothly. <br><br>

![Lighthouse page speed optimization tool in Google Chrome](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p6lbxotaowietgkp75hb.jpeg)
<center><i style="font-weight: 200;">Lighthouse built in Google Chrome Developer Tools can be used to audit the website performance</i></center><br>

Ok, so maybe it was a **traffic related issue**? Maybe site speed is good as long as the number of users using it is low? Worth a try. It is quite a common situation, many websites are tested only on a small number of users. **When the user base grows website starts to clog**. More on that topic you can read in my post on [why new users can kill you web application](https://accesto.com/blog/why-new-users-can-kill-your-web-application/). I did a few checks with the website load testing tool <a href="https://k6.io/" target="_blank" rel="nofollow">k6.io</a>, but nothing, still a decent response time. 

We also dug into the code to do some checks, but it only confirmed what was already obvious to us. Someone already **did a great job to optimize this website**. We weren't asked just to do the basics, they know how to do that themselves. We were asked because none of the popular tweaks worked. Great, finally some challenge! 

## Profiling the website performance

It was a time to dive deeper and do a step by step analysis. First of all, we had to figure out **which site element was taken to calculate the LCP**. Performance tool built-in Google Chrome shows a precise timeline of all the elements requested, loaded, and painted. It also **indicates moments when LCP and other metrics are measured**. 

![Chrome Developer tools - performance timeline](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9k9q8mu2a2ni2d23k51s.jpeg)
 

Analysis of this timeline confirmed our assumptions - the Largest Contentful Paint element was **one of the product images on the homepage**. Why is this image displayed so late to the user? We checked the image format and size, and all looked good. Actually, the **image itself was loaded in just 122 milliseconds**. So why did this image appear after almost 6 seconds if it loads in just a fraction of that?

![Chrome Developer tools - network - timing](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s4zi3r79p1m3uxywsvo5.jpeg)
 

We analyzed the timing of that particular image, and what surprised us was that **it started to load after 5.7s since the website was requested**. But why? Server response time was decent and all images should begin to load as soon as the browser receives the HTML from the server, right? Well…

## Lazy loading done wrong

The title of this article already revealed the diagnosis - yes, **it was a lazy loader that delayed fetching that image**. But why? Isn’t the lazy loader one of the most common mechanisms that **improve the website speed**?

![Lazy loader in action](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xghlnkuxx0ndgmx1idve.jpeg)
 
Lazy loader prevents images from being fetched if they are not in the current viewport. This **minimizes the amount of data transferred** in situations when only part of the site is seen by the user (eg. user views only the top of the page). Usually, it is good and makes the website load visibly faster. Usually...

Unfortunately, it also **has a side effect** that not every web developer is aware of. The lazy loader is simply a javascript code, that checks the image position and calculates whether it is in the current viewport. But this means that before the image is fetched, the web browser has to fetch the Javascript code and run it. The **user won’t see the image until Javascript decides** that he should see it. And that causes a delay.  

And of course, there are many ways to implement the lazy loader so that delay is minimized. But in our case, the code responsible for lazy loading used an external, third-party javascript library that had to be fetched first. And what is more, this code was implemented in an _onload_ event handler, which means that it was **executed only after all website elements finished loading** - including styles, fonts, scripts etc. And that all took 5.7s. It's quite a long time to decide if an image should be downloaded or not, isn't it?



## Results of website optimization

There are many ways to solve this problem. We could get rid of the dependency on the external library or execute the lazy loader earlier than in _onload_. But the quick fix was to simply **switch off the lazy loader for images that are always seen above the fold** (the portion of the webpage that is visible without scrolling). This simple solution took just one line of code and did a job. Just see how the website speed improved:

![Final results of site speed optimization](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/auz1b9r6uq0jb9m03h78.jpeg)

It took us a few hours to find the cause of the poor LCP and finally add this single line of code. Website optimization is usually not about coding, it is analytical work of searching, digging, and investigating. Of course, this wasn’t the end of the optimization, still room for improvement. But we were surprised **how much Core Web Vitals score improved with a simple fix in a lazy loader**. This made me curious so I also checked other popular eCommerce websites and I was surprised. Many of them did have the same issue! Seems that lazy loader is seen as a great, out of the box solution for optimization, but **very often added carelessly**. And adding it too quickly (too lazy?) may actually harm the overall site speed. **So be careful and don’t add stuff to your site just because everyone does it!**


![Email after successful website optimization](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5ycwy143jw7dmz8tbsxo.jpg)