DEV Community

Cover image for Progressive image loading with Gatsby
Giacomo Lombardi
Giacomo Lombardi

Posted on

Progressive image loading with Gatsby

Images on web pages

If you think about a classic/typical website there are some components that surely you imagine like the navbar and the hero.
The hero component typically has a large image that could impacts on the website performances (see Google Web Vitals).

GatsbyJS

GatsbyJS is one of the most famous static site generator that belongs to the JAMStack movement.
It has many plugins (to do almost anything) and one of the most used is the gatsby-image plugin that shipped great performances to handle images, specially when used in combination with gatsby-plugin-sharp.
As GatsbyJS reached the 3rd version, they released a new plugin for images: gatsby-plugin-image.
We will not talk about these changes in this post since my intentions is to show only how Gatsby can automatically handle images preloading and how it's powerful.

Gatsby website configuration

The new gatsby-plugin-image used in combination with the gatsby-plugin-sharp can be really really powerful.
The only thing a website programmer or a content creator should think about is: upload an high quality image prior to the extension and the size.
The sharp plugin can be configured to automatically generate new file extensions that will be handled by the gatsby-plugin-image. Doing this, the client will use the best extension you provide and it will have great performances.

Image placeholders

Placeholders are important for two reasons:

  1. score on tools like Google Lighthouse
  2. UX

The plugin already ship the first point as:

To ensure that the layout does not jump around, a placeholder is displayed before the image loads

By default the placeholder is set to DOMINANT_COLOR but to have a better UX we should need to change it.

Now the question is: what it is the best choice?
There are few options: DOMINANT_COLOR, BLURRED, TRACED_SVG and NONE.

NONE

In my opinion you should not display NONE as placeholder because it could lead to have large empty spaces before the image is loaded. These spaces could be confusing for an user as at first sight seems that the layout is broken.

DOMINANT_COLOR

The default choice is too easy and generates a flat colored area that is not able to communicate what the image will contains.
NOTE: this is a personal opinion, maybe you could love this setting.

BLURRED

It shows the whole image but it is "animated" from blurred to sharpened, gradually. I like this solution because is like focusing a subject with a camera.

TRACED_SVG

It is the most complicated solution but is the one I really love because it generates a sequence of images that lead the user to think that there is a painter that is painting in front of the user: starting from the main shapes of the image.

How to choose

How I should choose between BLURRED and TRACED_SVG?
Even if I put some personal opinions in the previous section, what I really need is rational decision: based on data.

So, I produced a local build of the website and performed some checks with the Lighthouse tab of Google Chrome dev tools.

gatsby build && gatsby serve
Enter fullscreen mode Exit fullscreen mode

I will report only the performance score as the image loading doesn't impact accessibility, best practice or SEO scores.

Results

BLURRED on mobile: 82
TRACED_SVG on mobile: 77
BLURRED on desktop: 99
TRACED_SVG on desktop: 98

Note: each score is calculated as the mean of 10 tests.
Note 2: GatsbyJS serve without HTTP/2 that lowers the score
Note 3: the website is a work in progress and there are other things to touch to have better performances

And the winner is... BLURRED!
It's clear that it has better performances on mobile than the other option.

gatsby-conf.js

module.exports = {
    plugins: [
        // ... some plugins before
        {
            resolve: `gatsby-plugin-sharp`,
            options: {
                defaults: {
                    formats: [
                        `auto`,
                        `webp`,
                        `avif`,
                    ],
                    quality: 100,
                    placeholder: "blurred",
                },
            },
        },
        // ... some plugins after
    ],
}
Enter fullscreen mode Exit fullscreen mode

I choose "blurred" as placeholder but I also explicitly choose to generate AVIF and WEBP images to take advantage of the best possible compression available for the web.

Bonus

All images in the website will have the BLURRED placeholder by default but it can be overwritten if you need.
This is the case of the logo in the navbar: since the image contains only a bird with a background I have chosen to use a TRACED_SVG placeholder. In my opinion this solution is more artistic.

The result

Navbar logo: TRACED_SVG
Main image: BLURRED

Discussion (0)