Hero Image Optimization Techniques
Tags: pagespeed, programming, tutorial, responsive
Published: 2023-01-17 06:17:55

Page speed is essential in determining a website's user experience. If a user can’t experience the content, they’ll bounce. A site's ideal complete load time is below 2 seconds. Studies show that most users will abandon the page within 3 seconds. You can also expect a 1.3% increase in that abandonment for every additional 100ms. For this reason, Google rates page speed quite heavily for SEO, and Google's Search Console provides a report on LCP, which can help website owners understand and improve the loading performance of their pages.

Reasons why page speed needs to be a key KPI:

- you want your page to rank well in organic searches
- you want your ads to perform
- you don’t want users abandoning your page out of frustration

Fortunately, a lot of low-hanging fruit can make a big difference in getting started. Following are some issues that I see a lot and have pretty straightforward ways to address.

## Measuring page speed

One of the key metrics used to measure page speed is the [Largest Contentful Paint (LCP)](https://web.dev/lcp/). The LCP measures the time it takes for the largest content element visible in the viewport to load and render. Therefore, optimizing the hero image can improve LCP and web page speed. Your goal is to have LCP occur as quickly as possible. Google has defined this as [within 2.5 seconds](https://support.google.com/webmasters/answer/9205520?hl=en#status_bucket) or faster measured from the start of page load.

We should always strive to set the hero image src in the initial HTML payload to reduce the length of the critical request chain. Some frameworks will add the src via Javascript or CSS. However, this will always take additional time.


## The file size
One way to speed up the hero image is to reduce its file size through compression. You could also use a tool like [ImageOptim](https://imageoptim.com/), or [NextJS’s Image Component](https://nextjs.org/docs/api-reference/next/image). Additionally, a next-gen image format like [WebP](https://web.dev/serve-images-webp/), available for all modern browsers, can significantly reduce the file size without sacrificing quality.

## A content delivery network
Another way to improve the LCP is to use a Content Delivery Network (CDN) to serve the hero image. A CDN is a network of servers distributed around the world. It can significantly reduce the time it takes for file delivery by serving it from a geographically closer server.

## Specify native height and width
Images should always have both height and width tags to allow the browser to calculate the aspect ratio. These should be the native size of the image while allowing CSS to set the actual rendered size. Adding the height and width allows the browser to hold this space open for the image; therefore, the page will not shift when it loads, allowing the measurement to take place more quickly.

_Example of using the height and width:_
```html
<img
    src="hero-image.jpg"
    height=”400”
    width=”400”
    alt="Hero Image."
/>
```

## The srcset and sizes attributes
A more responsive image optimization is to use the srcset and sizes attributes. These attributes allow you to provide different versions of an image for different screen sizes and resolutions and can significantly reduce the amount of data on smaller devices or lower-resolution screens.

_Example of using the srcset and sizes:_
```html
<img
    src="hero-image.jpg"
    height=”400”
    width=”400”
    srcset="
        hero_400px.jpg 400w,
        hero_800px.jpg 800w,
        hero_1600px.jpg 1600w
    " 
    sizes="(max-width: 600px) 100vw, 50vw" 
    alt="Hero Image."
/>
```

## The loading attribute
The loading attribute can prevent or encourage the browser’s loading order. The loading attribute can be set to lazy or eager, depending on the use case. “Lazy” loads the image when it becomes visible in the viewport, while eager loads the image immediately when the page is loaded, whether or not it’s in the viewport.

_Example of using the loading attribute:_
```html
<img
    src="hero-image.jpg"
    height=”400”
    width=”400”
    loading="eager"
    alt="Hero Image."
/>
```
You can add the loading attribute with a value of “lazy” to other images on your page when they should not load early. Slowing these items down helps speed up the rest of the assets. Lazy images are requested immediately if they are within the viewport. Outside the viewport, they are delayed and only fetched when approaching it.

## The link tag with preload
A link tag with the preload attribute tells the browser about critical resources before encountering them in HTML. So, for example, you can use preload to increase the download priority of late-discovered Hero images, especially if they load via Javascript or CSS.

_Example of using the link tag:_
```html
<link rel="preload" as="image" href="hero-image.jpg" />
```

If you are already using the srcset in your hero’s image tag, you can also use that here in the link tag and ensure that the correct size image is selected.

_Example of using the link tag with a responsive image:_
```html
<link
    rel="preload"
    as="image"
    href="hero-image.jpg"
    imagesrcset="
        hero_400px.jpg 400w,
        hero_800px.jpg 800w,
        hero_1600px.jpg 1600w
    " 
    imagesizes="(max-width: 600px) 100vw, 50vw"
/>
```

## The fetchpriority attribute
You can use a fetchpriority attribute to do the same thing as a link preload, although you will have to wait for the processor to discover the image tag. A priority hint can adjust the loading order of assets such as images, CSS, iframes, scripts, and fonts. So the Hero can be requested before other lower-priority assets. 

_Example of using the fetchpriority attribute:_
```html
<img
    src="hero-image.jpg"
    height=”400”
    width=”400”
    fetchpriority="high"
    alt="Hero Image."
/>
```

## Putting it all together
Using all the resources we have learned, we can apply them all to receive an optimal loading path.

_Example of using all the tools:_
```html
<head>
    <link
        rel="preload"
        as="image"
        href="hero-image.jpg"
        imagesrcset="
            hero_400px.jpg 400w,
            hero_800px.jpg 800w,
            hero_1600px.jpg 1600w
        " 
        imagesizes="(max-width: 600px) 100vw, 50vw"
    />
</head>
<body>
    <img
        src="hero-image.jpg"
        height=”400”
        width=”400”
        srcset="
            hero_400px.jpg 400w,
            hero_800px.jpg 800w,
            hero_1600px.jpg 1600w
        " 
        sizes="(max-width: 600px) 100vw, 50vw" 
        alt="Hero Image."
        loading="eager"
        fetchpriority="high"
    />
</body>

```

Optimizing the hero image is essential in improving the LCP and web page speed. Applying the above techniques can get your site dramatically closer to that 2.5 seconds goal!