Ensure Responsive Image Design for Faster Delivery

responsive image design

Images are essential for building engaging web applications and websites. However, with all the advancements in technology, images on the web have become complicated to manage due to the variety of sizes, formats, performance types, and resolutions available.

To make images responsive and performant on the web, developers traditionally use the srcset and sizes native img element attributes. This approach provides multiple image sources with sizes and hints to help the browser pick the most appropriate one:

    <img
        sizes='100vw'
        srcset='width-400.jpg 400w,
             width-800.jpg 800w,
             width-1600.jpg 1600w'
        src='cat_picture.jpg'
        alt='My image'
    />

Challenges with this approach:

  • The requirement of creating multiple image sizes.
  • A limited browser support.
  • A bloated codebase due to multiple image sources.

In this article, you will learn how to implement a responsive image design to ensure improved performance across different devices and screen sizes.

“Optimise

A responsive approach with Cloudinary

Cloudinary is a visual media platform used to upload, store, manage, transform, and deliver images and videos for websites and applications. The platform also offers a vast collection of SDKs for frontend frameworks and libraries.

One of the cool features of Cloudinary is its ability to provide responsive image design; automatically resizing and optimizing images for faster delivery and a better user experience.

We will use React to develop our application; however, the approach covered in this article can also be applied to other JavaScript-based frontend frameworks and libraries.

To use Cloudinary you’ll need to create an account. Signup is completely free.

Sandbox

We completed this project in a CodeSandbox. Fork and run it to quickly get started.

 

    <CodeSandbox id="confident-poincare-5pdvgt" title="How to do responsive image design" />

 

Github link here.

Getting Started

Step 1. Create a React project by navigating to the desired directory and running the command below in a terminal:

npx create-react-app resp_image && cd resp_image

The command creates a React project called ‘resp_image’ and navigates to the project directory.

* Due to a recent upgrade in the React version (“^18.0.0”), you might need to downgrade your application to a compatible version. Do this by deleting the generated node_modules folder.

Step 2. Modify the package.json file as shown below:

    {
      "name": "resp_image",
      "version": "0.1.0",
      "private": true,
      "dependencies": {
        "@cloudinary/react": "^1.2.2",
        "@cloudinary/url-gen": "^1.7.0",
        "@testing-library/jest-dom": "^5.16.4",
        "@testing-library/react": "^12.1.4",
        "@testing-library/user-event": "^13.5.0",
        "react": "^17.0.0",
        "react-dom": "^17.0.0",
        "react-scripts": "5.0.0",
        "web-vitals": "^2.1.4"
      },
      "scripts": {
        "start": "react-scripts start",
        "build": "react-scripts build",
        "test": "react-scripts test",
        "eject": "react-scripts eject"
      },
      "eslintConfig": {
        "extends": [
          "react-app",
          "react-app/jest"
        ]
      },
      "browserslist": {
        "production": [
          ">0.2%",
          "not dead",
          "not op_mini all"
        ],
        "development": [
          "last 1 chrome version",
          "last 1 firefox version",
          "last 1 safari version"
        ]
      }
    }

The snippet above does the following:

  • Line 11: changes the react version to “^17.0.0”.
  • Line 12: changes the react-dom version to “^17.0.0”.
    Step 3. Reinstall the dependencies by running the command below:

        npm install
    

    Step 4. Install the @cloudinary/url-gen and @cloudinary/react dependencies with:

     

        npm i @cloudinary/url-gen @cloudinary/react
    

     

    @cloudinary/url-gen provides all the functionality required to create delivery URLs.

     

    @cloudinary/react contains React-based components for rendering, configuring, and transforming media assets.

    Step 5. Include Cloudinary’s cloud name as an environment variable. To do this, create a .env file in the root directory and in this file, add the snippet below:

        REACT_APP_CLOUDINARY_CLOUD_NAME=/*YOUR CLOUD NAME HERE/*
    

    You can get Cloudinary’s cloud name by logging into the Cloudinary console and viewing any of the highlighted sections as shown below:

    Welcome dashboard Cloudinary

    Image sourcing and upload to Cloudinary

    Step 6. In the Cloudinary dashboard, upload the below sample image by clicking on the Media Library tab, then Upload, select the Web Address option, input the url, then clicking on the Arrow Button

Sample image url:

https://images.unsplash.com/photo-1649486116313-d04e42c24590?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=687&q=80

Image Upload Cloudinary

The uploaded image will be displayed on the console with its Public ID (the unique identifier for an asset stored in Cloudinary). This ID will come in handy when creating a responsive image design:

Image name inside of Cloudinary

Creating a responsive image

Step 7. Modify the App.js file in the src folder to the following:

    import './App.css';
    import { Cloudinary } from '@cloudinary/url-gen';
    import {
      AdvancedImage,
      responsive,
      lazyload,
      placeholder,
      accessibility
    } from '@cloudinary/react';
    function App() {

      //create cloudinary instance
      const cld = new Cloudinary({
        cloud: {
          cloudName: process.env.REACT_APP_CLOUDINARY_CLOUD_NAME,
        },
      });
    
      const myImage = cld.image('YOUR PUBLICID GOES HERE');
    
      return (
        <div className='App'>
          <header>
            <h2>Responsive Image</h2>
          </header>
            <AdvancedImage
              cldImg={myImage}
              plugins={[
                lazyload(),
                responsive({ steps: [200, 400] }),
                accessibility(),
                placeholder(),
              ]}
            />
        </div>
      );
    }

    export default App;

The snippet above:

  • Imports the required dependencies.
  • Creates a cld variable that instantiates Cloudinary and passes in the cloud.
  • Creates a myImage variable that uses the cld instance and Public ID to generate the image URL.
  • Uses the AdvancedImage component to create an image by passing in the generated image URL and plugins. The component can also do the following:
    • Lazyload: enhances performance by telling the browser not to download images that are not yet visible to the user on his screen. Instead, waits until the user scrolls to that image.
    • Responsive: resizes images automatically based on viewports.
    • Accessibility: makes images more accessible to users with disabilities.
    • Placeholder: displays a lightweight version of the image while downloading the main image.Step 8. Once complete, we can start a development server using the command below:
          npm start
      

       

      Responsive image example

      Conclusion

      This post discussed how to implement responsive image design in a web application. Cloudinary supports various SDKs and utilizes multiple techniques to optimize and deliver media assets. Try it out today (it’s free forever!) and supercharge your productivity.

      More from Cloudinary:

QUICK TIPS
Tamas Piros
Cloudinary Logo Tamas Piros

In my experience, here are tips that can help you better design and deliver responsive images for faster performance:

  1. Always generate images at multiple breakpoints
    Define key breakpoints for your layout (e.g., 320px, 480px, 768px, 1024px, and 1440px) and generate different image sizes for each. This prevents loading oversized images on small screens and ensures that every device receives a suitable version of the image.
  2. Use modern image formats like WebP or AVIF
    Newer formats like WebP and AVIF offer better compression than traditional formats like JPEG and PNG. These formats maintain visual quality at smaller sizes, reducing bandwidth usage and speeding up delivery. Use tools like Cloudinary to automatically serve the best format based on the browser’s capabilities.
  3. Optimize image delivery using srcset and sizes
    Use the srcset attribute to define a list of image URLs with their corresponding widths, and the sizes attribute to specify how much space each image should take up relative to the viewport. This setup allows browsers to automatically choose the best resolution for each device, avoiding over- or under-loading images.
  4. Implement lazy loading for below-the-fold images
    Use lazy loading (loading="lazy") for images that are initially off-screen. This defers image loading until they are about to enter the viewport, reducing initial page load times and improving perceived performance, especially on image-heavy pages.
  5. Use the picture element for art direction
    The <picture> element allows you to define different images for various screen sizes or orientations, offering greater flexibility. For example, you can use a wide, landscape-oriented image for desktops and a square crop for mobile devices. This technique ensures that your images maintain their visual impact across devices.
  6. Leverage Cloudinary’s dynamic resizing and transformations
    Cloudinary’s URL-based transformations let you dynamically resize, crop, and optimize images without creating multiple static files. Use parameters like w_auto (width auto) and q_auto (quality auto) to automatically adjust dimensions and compression based on the device, saving time and storage space.
  7. Incorporate responsive placeholders for a smooth visual experience
    Use low-quality image placeholders (LQIP) or blurred placeholders to give users a preview of what’s to come while the full image is being downloaded. This technique, often called “progressive image loading,” makes the user experience feel faster and smoother, reducing perceived loading times.
  8. Prioritize preload for critical images
    For important visuals like hero images, use the <link rel="preload"> attribute in your HTML to signal to the browser to download these images as early as possible. This ensures key images are visible immediately and reduces the time it takes for the above-the-fold content to fully render.
  9. Use Cloudinary plugins to automate responsiveness in React
    If using React, leverage Cloudinary’s React SDK and plugins like responsive() and lazyload() to automate image optimization. This allows you to easily integrate responsive and performance-focused techniques without manually managing every transformation or breakpoint.
  10. Test image performance with Core Web Vitals metrics
    Regularly measure your images’ impact on metrics like Largest Contentful Paint (LCP) and Cumulative Layout Shift (CLS) using tools like Google Lighthouse. Optimize based on these metrics to ensure your responsive images contribute positively to user experience and SEO rankings.

By incorporating these strategies, you can ensure that your images are not only responsive but also optimized for faster delivery and better performance across all devices and network conditions.

Last updated: Oct 1, 2024