Image Optimization Best Practices

Maintain fast and responsive websites on tablets, mobiles, and desktops by tailoring image sizes to adjust based on a device’s screen resolution. This section includes best practices to ensure images on your customer’s store are responsive, load faster, and have no layout shifts.

Switch Resolution Based on the Browser Size 

Ensure your customer’s browser picks responsive and optimized images based on their device screen size. When you build custom components, implement attributes, srcset and sizes, in the img element.

srcset defines a set of images based on the device’s screen size and resolution. The srcset attribute helps you define multiple image sources of different widths, separated by a comma. Browser picks the most appropriate image, based on the screen size and resolution. The attribute sizes define the size of the image element. You can use any length value to represent the size, but not percentages. For example, the size can represent the absolute width (480 px) or a width relative to the viewport (50 vw).

For example, consider an image with these attributes:

1<img
2  srcset="product-480w.jpg 480w, product-800w.jpg 800w"
3  sizes="(max-width: 600px) 480px,800px"
4  src="product-800w.jpg"
5  alt="Product Image">

From the example,

  • (product-480w.jpg) represents the image filename and type, and(480w)represents the image’s intrinsic width in pixels.
  • (max-width: 600px)480px represents that if the viewport width is up to 600 px, each image takes up 480-px width.

You can also provide a better user experience for customers using stores by specifying the srcset in the picture element to include a higher resolution version of the image. For example, consider a picture element where the srcsetattribute has x-descriptors and thesizes attribute isn’t defined.

1<picture>
2  <source srcset="product.png?width=400, product.png?width=800 2x">
3  <source media="(max-width: 800px)" srcset="product.png?width=200, product.png?width=400 2x">
4  <img src="product.png" alt="Product Image">
5</picture>

If the device accessing the page has a standard or a low-resolution display, with one device pixel representing each CSS pixel, the product.png?width=400 image is displayed. Whereas if the device has a high resolution of two device pixels per CSS pixel or more, the product.png?width=800 image is displayed.

Avoid Cumulative Layout Shifts 

Ensure that your customer’s browser can reserve the appropriate amount of space in the layout before the images are fully loaded, thus preventing any disruptive shifts. Define the image’s aspect ratio, which is the ratio of width to height. This example shows how width and height are defined for an image.

1<img
2  src="product.png"
3  width="800px" height="800px"
4  alt="Product Image">

This example shows the width and aspect ratio attributes added to the image.

1//html
2<img
3  src="product.png"
4  alt="Product Image">
5
6//css
7img {
8  width: 800px;
9  aspect-ratio: 1/1;
10}

Improve Image Loading Time 

Ensure images have a high quality and small size, for a quicker loading time. Leverage the built-in image scaling CDN (Content Delivery Network) and CMS (Content Management System) capabilities. Automatically scale images, instead of uploading the same image in different sizes. By using the resource resolver from experience/resourceResolver, component developers can leverage a URL resolver that works for both CDN and CMS.
Here’s an example of how to scale images to the appropriate sizes for the various devices and screen resolutions.

1import { resolve } from 'experience/resourceResolver';
2
3// External URL && Cloudflare
4const externalUrl = resolve('https://www.imageserver/product.png', true, { width: 800, height: 800 });
5console.log(externalUrl)
6// {storeHostname}/cdn-cgi/images/width=800&height=800/https://www.imageserver/product.png
7
8// CMS URL && no CDN
9const cmsUrl = resolve('cms/sfsites/product.png', true, { width: 800, height: 800 });
10console.log(cmsUrl)
11// cms/sfsites/product.png?width=800&height=800

Enhance Image Using the Experience-Picture Component 

If you prefer to customize an image with appropriate source elements, and not create the attributes srcset and sizes, use the experience-picture component. This component allows you to define multiple sources for the image based on factors such as device resolution, viewport size, and pixel density.

The component exposes these properties

PropertyTypeDefaultDescription
alternativeTextstring | undefinedundefinedThe alternative text for the image. This value is set to empty for decorative images.
loadinglazy | eager | undefinedeagerDetermines how the image is loaded on a webpage.
urlstring | undefinedundefinedThe placeholder image if the specified image isn’t found or unable to load.
imagesImageData[] | undefinedundefinedThe srcSet for each form factor or media query. Either use CustomizedImageData with your own media query or use the PredefinedImageData with the formFactor name and a media query based on the SLDS breakpoints, which is created automatically.

Consider this example that explains how to use the component.

1## Image Types
2type CustomizedImageData =
3{
4  /**
5  * media condition that defines breakpoint
6  * optional - if unset the slds default can be used by setting the formFactor
7  */
8  media?: string;
9
10  /**
11  * defines a set of source sizes, each containing a media condition and a size value
12  * (min-width: 768px) 700px,
13  * (min-width: 1024px) 600px,
14  * 500px
15  */
16  sizes: string;
17
18  /**
19  * defines image sources containing an url followed by a whitespace and either a width descriptor or pixel density
20  * product-small.jpg 700w,
21  * product-medium.jpg 1200w,
22  * product-large.jpg 1600w
23  */
24  srcSet: string;
25};
26
27type PredefinedImageData =
28{
29  /**
30  * used to mimic the slds breakpoints for different screen sizes
31  */
32  formFactor: FormFactor;
33
34  /**
35  * defines a set of source sizes, each containing a media condition and a size value
36  * (min-width: 768px) 700px,
37  * (min-width: 1024px) 600px,
38  * 500px
39  */
40  sizes?: string;
41
42  /**
43  * defines image sources containing an url followed by a whitespace and either a width descriptor or pixel density
44  * product-small.jpg,
45  * product-medium.jpg 2x,
46  * product-large.jpg 3x
47  */
48  srcSet: string;
49};
50
51export type ImageData = PredefinedImageData | CustomizedImageData;
52export type FormFactor = 'mobile' | 'tablet' | 'desktop';

Additionally you can use a utility method from experience/picture to create those srcSets based on the image widths of your component.

1type ImageSizes = Record<FormFactor, number>;
2createImageDataMap(url, [ImageSizes], [devicePixelRatio])

Here’s an example:

1createImageDataMap(
2  'https://example.com/image.jpg',
3  {
4    mobile: 200,
5    tablet: 400,
6    desktop: 600
7  }
8  [1, 2]
9)
10
11--> returns a srcSet for each of the form factors
12[
13  {
14    formFactor: 'mobile'
15    srcSet: 'https://example.com/image.jpg?width=200,
16    https://example.com/image.jpg?width=400 2x'
17  },
18  {
19    formFactor: 'tablet'
20    srcSet: 'https://example.com/image.jpg?width=2=400,
21    https://example.com/image.jpg?width=800 2x'
22  }
23  {
24    formFactor: 'desktop'
25    srcSet: 'https://example.com/image.jpg?width=600,
26    https://example.com/image.jpg?width=800 2x'
27  }
28]
29// The picture component uses these media queries for the different form factors
30export const MEDIA_QUERIES: { mobile: string; tablet: string; desktop: string } =
31{
32  mobile: '(max-width: 47.9375em)',
33  tablet: '(max-width: 64em)',
34  desktop: '(min-width: 64.0625em)',
35};
36<experience-picture
37  alternative-text="Product Image"
38  url="https://example.com/image.jpg"
39  images="{images}"
40></experience-picture>
41
42--> inside the picture component this html is generated
43<picture>
44  <source
45    media="(min-width: 64.0625em)"
46    srcset="https://example.com/image.jpg?width=600, https://example.com/image.jpg?width=800 2x"
47  />
48  <source
49    media="(max-width: 64em)"
50    srcset="https://example.com/image.jpg?width=400, https://example.com/image.jpg?width=800 2x"
51  />
52  <source
53    media="(max-width: 47.9375em)"
54    srcset="https://example.com/image.jpg?width=200, https://example.com/image.jpg?width=400 2x"
55  />
56  <img src="https://example.com/image.jpg" alt="Product Image" />
57</picture>