DEV Community

Cover image for Optimizing Image Upload with Cropping and Compression in Next.js Projects
Evanrobby Macharia
Evanrobby Macharia

Posted on

Optimizing Image Upload with Cropping and Compression in Next.js Projects

As a frontend developer, there's a high chance that you have been or are currently working on a project that involves posting and displaying images. If you haven't, well, you will soon. So, recently, after we finished working on our project, we found ourselves in a hitch when it came to displaying the images provided by the users.

How It All Unraveled
The biggest problem was how to handle the dimensions, more so the height versus width of the images. Setting the image to object-fit: cover seemed like the perfect solution for filling up the image container. But this introduced other problems. Users were uploading images of different dimensions; some were scaling and others were cropping into the same container. The result of such inconsistencies was not-so-appealing UI, especially when users' profile pictures cropped in such a way that they were less visible.

The Solution
I decided to find a better solution. Emulating how social media platforms handle image uploads, I thought it good to give users the ability to crop and preview the images before uploading. A little research, and I finally found the react-image-crop package. This package provides users with the ability to crop their images in real time, thus solving part of the issue.

While testing the cropping functionality, I noticed that the size of the image I was working with was 9.5MB in size. That's when it struck me: why not compress the image on the client side before uploading? Even though the backend handles this, too, the ability to have an optimization of the image a step earlier saves bandwidth and improves upload times.

This brought me to another handy package: browser-image-compression. Merging this with react-image-crop allowed me now to both crop and compress images on the fly, and to great effect.

Trade-offs
This solution isn't without a couple of trade-offs. First of all, you're going to have to add two more packages to your project; also, images coming in under 30KB are actually going to end up larger due to the compression overhead.

I also styled it using Shadcn UI components and the react-dropzone package so as to let users click to select or drag and drop their images.

Using Next.js Image Component
For even better performance, this solution can be combined with the Next.js Image component, which automatically optimizes images. The Next.js Image component helps deliver appropriately sized images, improving loading times and overall performance. By integrating cropping and compression with the power of Next.js image optimization, you can provide users with a smoother and more efficient experience.

Demo and Source Code
You can also try a live demo here

Also here is the source code GitHub repository. Please star if you find it useful! Let me know if you consider using this solution in your project.

Top comments (0)