Skip to content

Instantly share code, notes, and snippets.

@g3tr1ght
Created November 13, 2025 00:19
Show Gist options
  • Select an option

  • Save g3tr1ght/c03fd3f629b8f3de2103ba5c42d110aa to your computer and use it in GitHub Desktop.

Select an option

Save g3tr1ght/c03fd3f629b8f3de2103ba5c42d110aa to your computer and use it in GitHub Desktop.
Images optimization with webpack

Images optimization with webpack

To prebuild images for various breakpoints using webpack and implement them with responsive design, you should use build-time tools to generate the different image sizes and then use HTML's srcset and picture elements for implementation, as using CSS media queries to change image sources is less efficient. [1, 2, 3, 4]

1. Prebuilding Images with Webpack

Use a webpack plugin and image processing library to automatically generate multiple image sizes during the build process. A common combination is the image-minimizer-webpack-plugin with sharp. [5, 6]

Webpack Configuration Example (webpack.config.js):

const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
const path = require('path');

// ... other webpack config ...

module.exports = {
  // ...
  optimization: {
    minimizer: [
      new ImageMinimizerPlugin({
        generator: [{
          type: 'asset',
          implementation: ImageMinimizerPlugin.sharpGenerate,
          options: {
            // Define your breakpoints and filenames
            presets: [{
              width: 400,
              name: 'small',
              suffix: '-small',
            }, {
              width: 800,
              name: 'medium',
              suffix: '-medium',
            }, {
              width: 1200,
              name: 'large',
              suffix: '-large',
            }],
          },
        }],
      }),
    ],
  },
  // Use asset modules to handle image imports
  module: {
    rules: [{
      test: /\.(jpe?g|png|gif|svg)$/i,
      type: 'asset/resource',
    }],
  },
  // ...
};

This configuration uses sharp via image-minimizer-webpack-plugin to generate several versions of your source images (e.g., image-small.jpg, image-medium.jpg, image-large.jpg). [5, 7, 8, 9, 10]

2. Implementing with HTML srcset and picture

Instead of relying solely on CSS media queries to swap image sources (which can lead to all image files being downloaded regardless of screen size), use the HTML5 picture element and the img element's srcset attribute. The browser will automatically select and load the most appropriate image based on the user's viewport and resolution. [1, 11, 12, 13, 14]

HTML Implementation Example:

<picture>
  <!-- Define different image sources for specific media queries -->
  <source srcset="path/to/your-image-large.jpg" media="(min-width: 1025px)">
  <source srcset="path/to/your-image-medium.jpg" media="(min-width: 481px)">
  <!-- Fallback img element for smaller screens and older browsers -->
  <img src="path/to/your-image-small.jpg" alt="Description of image">
</picture>

The media attribute in the element works exactly like a CSS media query condition, allowing you to specify the screen widths at which the corresponding srcset image should be considered. The browser evaluates the source elements in order and uses the first one that matches the current viewport conditions. The element is a required fallback for browsers that don't support the element. [11, 15, 16, 17, 18]

3. Using CSS for Background Images

If you need responsive images for CSS background-image properties (e.g., for large hero sections), you can use CSS media queries in your stylesheets: [19]

.hero-section {
  background-image: url('./path/to/your-image-small.jpg');
}

/* Use a different background image for medium screens and up */
@media screen and (min-width: 481px) {
  .hero-section {
    background-image: url('./path/to/your-image-medium.jpg');
  }
}

/* Use the largest image for large screens */
@media screen and (min-width: 1025px) {
  .hero-section {
    background-image: url('./path/to/your-image-large.jpg');
  }
}

Webpack will resolve the url() statements in your CSS during the build process, replacing them with the correct, versioned file paths. [20, 21, 22]


[1] https://stackoverflow.com/questions/22668535/responsive-design-different-images-for-different-screen-sizes
[2] https://stackoverflow.com/questions/69335456/responsive-images-via-picture-element-and-media-queries-via-css
[3] https://medium.com/@asierr/the-picture-html-tag-responsive-images-made-easy-e76eeb7cc185
[4] https://blog.pixelfreestudio.com/how-to-use-webp-images-for-faster-load-times/
[5] https://stackoverflow.com/questions/54903292/webpack-4-generate-responsive-images
[6] https://github.com/FatehAK/vite-plugin-image-optimizer
[7] https://webpack.js.org/plugins/image-minimizer-webpack-plugin/
[8] https://github.com/FatehAK/vite-plugin-image-optimizer
[9] https://francoischalifour.com/medium-image-zoom/
[10] https://itnext.io/angular-2-progressive-image-loader-a1b053195d14
[11] https://stackoverflow.com/questions/27853884/media-queries-and-image-swapping
[12] https://www.sitepoint.com/how-to-build-responsive-images-with-srcset/
[13] https://amp.dev/documentation/guides-and-tutorials/develop/style_and_layout/art_direction/
[14] https://chromatichq.com/insights/responsive-images-drupal-using-srcset/
[15] https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_media_queries/Using_media_queries
[16] https://cloudinary.com/documentation/responsive_html
[17] https://elad.medium.com/a-complete-guide-for-responsive-images-b13db359c6c7
[18] https://www.codeguage.com/v1/courses/html/images-the-picture-element
[19] https://cloudinary.com/guides/responsive-images/5-techniques-and-examples-for-creating-responsive-images-in-css
[20] https://stackoverflow.com/questions/35369419/how-to-use-images-in-css-with-webpack
[21] https://webpack.js.org/configuration/module/
[22] https://symfonycasts.com/screencast/javascript-webpack/file-loader-images

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment