Web Performance Optimization - Images (1)

CNHur HyeonBin (Max)
Reponses  01month ago( Both Korean and English Version )

Image Optimization Methods for Web Performance

One of the key factors in determining web page performance is images. They significantly impact FCP (First Contentful Paint) and LCP (Largest Contentful Paint), which influence user experience and bounce rates. So, how can we optimize images?

Image optimization methods can be broadly divided into two categories.

 

1️⃣ Image Optimization Techniques

  • Lazy Loading

  • Preloading

  • Progressive Loading

2️⃣ Reducing the Size of Loaded Images

This article focuses on the second method—reducing the actual size of images.

 


 

Reducing Image Size?

Using smaller images speeds up loading times and improves performance. However, one question might come to mind:
"Won’t reducing image size lower its quality?"

That’s true, but consider this analogy:

Imagine Hyunbin orders 10 servings of beef at a restaurant but only eats 2 servings, leaving the other 8 untouched. Ordering 10 servings was a waste of money. When we dine out, we don’t order excessive amounts just because we can—we order based on what we can actually eat.

The same principle applies to images. If a large image is downloaded but isn’t fully displayed on the screen, unnecessary data is loaded, increasing page load time. That’s why we should resize images to the optimal size that fits the current screen.

 


 

How to Optimize?

There are two ways to properly reduce image size:

1️⃣ Responsive Image Loading

  • Use attributes to serve images based on screen size.

  • Load smaller images on mobile and larger images on desktops.

2️⃣ Using the Right File Format

  • Use WebP instead of JPEG to reduce file size while maintaining quality.

  • If transparency is needed, convert PNG to WebP.

Finally, responsive image loading + modern formats are the key.
This approach leads to faster loading speeds, a better user experience, and lower bounce rates.

 

Determining the Optimal Image Size for the Current Screen

To set the optimal image size, you need to consider the target service and predefined breakpoints (responsive thresholds). Each service has different breakpoints, which determine the necessary image sizes.

For example, in a React project with breakpoints at 480px, 800px, and 1400px, you would need three different image sizes. Serving the appropriate image for each screen size is the most optimized approach.

Before optimization, the results of loading a generalized image across different viewports are as follows:

 

react.png

 

 

thumbnail.png

 

Each viewport requires a different image size, but all of them download the same image, resulting in poor LCP (Largest Contentful Paint) performance.

 

Creating Responsive Images + Changing File Formats

(There is an automated way to do this. You don't need to follow the manual steps. 😀)

Using tools that help resize images to the desired size is very convenient.

Link: https://www.responsivebreakpoints/

 

도구를 사용한 이미지 분리.png

 

After optimizing the images, you can save them in the project's public/images and public/resized folders.

 

images folder structure.png

 

To automatically load the image that fits the current screen size, you need to set the srcSet and sizes attributes.

srcSet and sizes are attributes of the img tag that display the appropriate image based on the size.

 <img
          srcSet="
          /image/image-test_small.webp 480w,
          /image/image-test_medium.webp 800w,
          /image/image-test_large.webp 1400w"
          sizes="
          (max-width: 480px) 100vw,
          (max-width: 800px) 100vw,
          70vw"
          src="/images/image-test-1.jpg"
          alt="image test 1"
        />

 

 

srcSet and sized example.png

 

Once the images are separated according to the viewport, you should use a tool to change the file extension. The common image extensions on the web are jpeg, jpg, png, and webp.

Each of these has its own characteristics, usage purposes, and considerations.

 
 
 

 

image format table.png

 

To sum up, WebP is the most efficient in terms of file size and functionality, so it should be prioritized. However, since there might be browsers that don’t support WebP, JPG and PNG can be used as backups depending on the use case.

Now, let's use a tool to convert the file extensions.

Link: https://bigconvert.11zon.com/ko/jpg-to-webp/

 

 

 

image resize with webp.png

 

Simply by changing the file extension, you can see that the image size has been reduced by about 30%.

Finally, after implementing all images responsively, you can check the Network tab and measure the performance to see a significant difference. Different images are loaded for each viewport, and an improvement of over 63% in LCP was observed.

 

image optimization result.png

 


 

Can It Be Automated?

Understanding how to create responsive images, convert file extensions, and optimize the images for loading based on breakpoints and services is important. However, when creating a webpage, a large number of images are used. Manually using tools to create multiple versions of each image and converting file extensions can become a cumbersome and repetitive task. As a developer, performing repetitive tasks over and over is not efficient. Fortunately, there is a way to automate this process.

Depending on the bundler, library, or framework you're using, there is a solution available. For example, in Npm + Vite, there is a library called Sharp. This library automatically regenerates images in the desired size and version, and it also converts the extensions to your preferred format. Here's how to use it:

1. Download Library

npm i sharp

2. Create the script

sharp folder structure.png

 

 

import sharp from "sharp";
import fs from "fs";
import path from "path";

// Folder containing the original images
const inputDir = "./public/images/";
// Folder to save the converted images
const outputDir = "./public/generated/";
// List of image sizes to generate
const sizes = [480, 800, 1400];

// Create the output folder if it doesn't exist
if (!fs.existsSync(outputDir)) {
  fs.mkdirSync(outputDir, { recursive: true });
}

// Get all image files in the folder
fs.readdir(inputDir, (err, files) => {
  if (err) {
    console.error(`Directory read error: ${err.message}`);
    return;
  }

  // Execute conversion for all images
  files.forEach((file) => {
    const inputPath = path.join(inputDir, file);
    const ext = path.extname(file).toLowerCase();

    // Convert only supported extensions (jpg, png, jpeg)
    if ([".jpg", ".jpeg", ".png"].includes(ext)) {
      const baseName = path.basename(file, ext);

      sizes.forEach((size) => {
        const outputPath = path.join(outputDir, `${baseName}-${size}.webp`);

        sharp(inputPath)
          .resize(size) // Resize the image
          .webp({ quality: 80 }) // Convert to WebP format
          .toFile(outputPath)
          .then(() => console.log(`${outputPath} conversion complete!`))
          .catch((err) => console.error(`Conversion error: ${err.message}`));
      });
    }
  });
});

 

3. Apply the Script

 

  
//in pakage.json

"scripts": {
    "gi": "node scripts/generate-images.js",
    "dev": "vite",
    "build": "tsc -b && vite build"
  },

 

5. Use Script

 

npm run gi

 

6. Result

 

after using sharp.png

 

 

Using this method, you can generate responsive images and change the file extensions for all images within your project. By following the steps mentioned earlier, you can optimize the images, which will significantly improve the performance of your project. This automated process ensures that the images are properly resized, converted to more efficient formats like WebP, and optimized for faster loading times.

By reducing image sizes and using appropriate formats for different screen sizes, you can enhance FCP (First Contentful Paint) and LCP (Largest Contentful Paint), improving overall user experience and reducing bounce rates.

CNHur HyeonBin (Max)
Reponses  0