Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/nucliweb/image-element

Repository to collect best practices for web images 🏞
https://github.com/nucliweb/image-element

Last synced: 7 days ago
JSON representation

Repository to collect best practices for web images 🏞

Awesome Lists containing this project

README

        

# Best practices for images

Repository to collect best practices for web images

## Responsive images

### With media

We can use `media` to define a media query as a breakpoint to load a responsive image.

```html




Awesome image

```

> In the above code, the browser loads the `image.jpg` in mobile version, the `image-wide.jpg` in tablets resolutions or bigger, and the `image-ultrawide.jpg` will be loaded in screen resolutions bigger than 1200px.
> NOTE: Browser finds the first matching condition and ignores everything after.

### With sizes

We can use [`sizes`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/sizes), that allows you to specify the layout width of the image for a list of media conditions.

```html
Awesome image
```

> In the above code (like with `media`), the browser loads the `image.jpg` in mobile version, the `image-wide.jpg` in tablets resolutions or bigger, and the `image-ultrawide.jpg` will be loaded in screen resolutions bigger than 1200px.

## Serve modern image formats

> Usually, the next-gen image formats like [`WebP`](https://developers.google.com/speed/webp), [`AVIF`](https://aomediacodec.github.io/av1-avif/) or [`JPEG XL`](https://jpeg.org/jpegxl/), can optimize image weight while maintaining good image quality.

With the HTML tag `` we can specify the `type` in the `` tag. The type is the image format, and we can use it to serve modern image formats. The browser will use the first image format that it supports.

```html



Awesome image

```

> In the above code, the browser loads the first image format that it can render. E.g. Internet Explorer 11 nor Safari 13 can't load the [WebP](https://developers.google.com/speed/webp) image format (a next-gen image format), so they will load the `JPEG` image.

```html





Awesome image

```

> In the above code, we list all the modern image formats, from "more optimized" to "less optimized". The browser will show the first image that it can load and render.

## Serve responsive and modern image formats

We can combine both approaches to serve modern image formats and responsive images to load the best image on each device.

```html






Awesome image

```
> In the above code, we have a combination of all modern image formats and the sizes needed. This is an example, as every site or project needs different sizes.

## Improve the Web Performance

We can use several attributes to improve the Web Performance, aka **user experience**.

- [`loading`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/loading) provides a hint to the user agent on how to handle the loading of the image which is currently outside the window's visual viewport. We can set it to `eager` (default value) which tells the browser to load the image as soon as the `` element is processed, or `lazy` that tells the user agent to hold off on loading the image until the browser estimates that it will be needed imminently.
- [`decoding`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/decoding) represents a hint given to the browser on how it should decode the image. The values are `sync` to decode the image synchronously for atomic presentation with other content, `async` to decode the image asynchronously and reduce delay in presenting other content, and `auto` (default mode) which indicates no preference for the decoding mode. The browser decides what is best for the user.
- [`fetchpriority`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/fetchPriority) represents a hint given to the browser on how it should prioritize the fetching of the image relative to other resources. The values are `high` to fetch the image at a high priority relative to other images, `low` to fetch the image at a low priority relative to other images, and `auto` (default mode) which indicates no preference for the fetch priority. The browser decides what is best for the user. By default images are initially `low`, until the browser has done layout and knows what images are in the viewport. These are then boosted to `high` priority. You can make this boost happen earlier for an important image (e.g. LCP image) you know has a high probability of being in the viewport by using `fetchpriority="high"`. Similarly you can deprioritize less important images that are technically in the viewport, but not viewable (e.g. second and third carousel images) by using `fetchpriority="low"`. Typically you would not need to use fetchpriority on off-screen images as the browser default (low until in viewport) is optimal there.

### Now we will use this attributes to improve the user experience of our images

```html






Awesome image

```

> In the above code, we have a better code for all the images below the fold (outside the viewport) and the browser does not load these images (according to the [threshold](https://github.com/chromium/chromium/blob/main/third_party/blink/renderer/core/frame/settings.json5#L936-L968))

### Improve the image detected as [LCP](https://web.dev/lcp) element of the Core Web Vitals

The previous code covers the scenario for all images outside of the viewport. Usually, the [LCP](https://web.dev/lcp) metric refers to an image element, so we can iterate to improve it.

```html






Awesome image

```

> In the above code, we changed the attribute `decoding` to `sync` to priorize the decoding, removed the attribute `loading` because the default behavior is `eager`, so we don't need it, and we add the attribute `fetchpriority="high"` to indicate to the browser to load the image as soon as possible.

> By the way, we don't need to add these attributes to all `` tags, only to `` tags.

If an image is not immediately discoverable in the HTML, a preload link tag, with `fetchpriority="high"` to boost the priority, can also allow it to be loaded as soon as possible. See [Optimize when the resource is discovered #](https://web.dev/optimize-lcp/#optimize-when-the-resource-is-discovered)

## Use a CDN Image Service

We see that we need a lot of code to deliver the best user experience 🙈.

We can use a CDN Image Service like [Cloudinary](https://cloudinary.com/) to remove the part of code that references the image format, as these services serve the best image format supported by the browser.

The browser sends in the [HTTP Headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers) the [`accept`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept) header value to indicate which content types, expressed as [MIME types](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types).

![Accept Header](images/accept.png)

> In the screenshot above we see that my current version browser supports `image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;`, so with a service of automatic image format, the service will send me an `avif` image format in response.

```html

Awesome image

```

> Now we don't need to define the type because this is transparent to us. The service sends the best image format supported by the browser. Notice that the image in the samples is an `PNG` image, yet the browser will load an `avif` image format.


## Acknowledgement

- [Addy Osmani](https://github.com/addyosmani), for this [image](images/image-addy-osmani.jpg) and for all the tips that he are sharing with the community.