DEV Community

Devops Makeit-run
Devops Makeit-run

Posted on • Originally published at make-it.run

Optimizing Images for Faster Web Performance in Laravel

Images are often the heaviest assets on a website.

Modern pages commonly ship hundreds of kilobytes (or even megabytes) of images, significantly slowing load times.

For example, the Web Almanac (page weight 2022) shows that images are the largest contributor to page weight—with median image payload around 1,000 KB on desktop and 811 KB on mobile.

In other words, a handful of full-resolution photos can easily stretch page weight by several megabytes. This affects performance: slow-loading images frustrate users, increase bounce rates, and hurt SEO.

Large, unoptimized images are major culprits for slow loading. To make pages fast, it’s crucial to optimize images aggressively—shrinking a 5 MB upload to a few hundred kilobytes or less before display.


How to do this in PHP/Laravel? Key steps: choose the right dimensions and format, compress with smart algorithms, and remove extra data.

This means (1) resizing/downscaling huge photos to display size, (2) encoding to efficient formats (WebP/JPEG with quality) instead of raw files, (3) stripping metadata, and (4) optionally enabling progressive loading. We’ll break these down and see how Laravel code can help, often transparently.


Resize to needed dimensions. Most web pages don’t need 4,000×3,000 images. If a user uploads a 5 MB (4000×3000) photo, shrink it (e.g. to 1200×900) to cut pixels and file size. In Laravel, libraries like Intervention Image can resize on upload.

$image = Image::make($request->file('photo')->getRealPath());
$image->resize(1200, null, function ($constraint) {
    $constraint->aspectRatio();
    $constraint->upsize();
});
$image->save($pathToOutput);
Enter fullscreen mode Exit fullscreen mode

This sets width to 1200px (height auto), preserves aspect, prevents upscaling, and dramatically reduces file size. Adjust dimensions per your layout (banners, thumbnails, etc.). Resizing at upload ensures images aren’t unnecessarily large when served.


Encode with compression. After resizing, compress the image data. For JPEG, adjust quality level (lossy) or use special compressors.

$image->encode('jpg', 75)->save($outputPath);
Enter fullscreen mode Exit fullscreen mode

Lower quality = smaller size.

Chain into WebP as:

Image::make($file)->encode('webp', 80)->save($outputPath.'.webp');
Enter fullscreen mode Exit fullscreen mode

Laravel packages like Spatie’s laravel-image-optimizer can automate this:

ImageOptimizer::optimize($pathToOriginal, $pathToOptimized);
Enter fullscreen mode Exit fullscreen mode

This uses jpegoptim, pngquant, etc. under the hood, stripping metadata and optimizing size.


Strip metadata & enable progressive/JPEG options. Photos have EXIF data, camera info, etc. not needed for display.

EXIF datacamera info

Optimizers (jpegoptim/pngquant) remove these.

jpegoptimpngquant

In Intervention Image, save() can accept flags (e.g. \$image->save('image.jpg', 80, true)) to strip metadata. Explicitly, toJpeg(\$quality, \$progressive = true, \$strip = true).

Spatie’s Media Library uses --strip-all and makes JPEGs progressive.

--strip-all
Enter fullscreen mode Exit fullscreen mode

Progressive JPEG loads in layers for better perceived speed.

Progressive JPEG images load in layers, providing faster perceived loading speed for users.

Many tools enable progressive mode and metadata-stripping by default.


Choose efficient formats (WebP/AVIF) when possible.

WebP/AVIF are supported in most modern browsers.

In Laravel, simply encode to .webp or .avif using Intervention:

encode('webp'), encode('avif')
Enter fullscreen mode Exit fullscreen mode

Generate fallback JPEG/PNG for older browsers.

Middleware or Blade can detect the user's Accept header to serve the best format.

Serving small, modern formats drastically reduces network bandwidth.


Automate with packages. You don’t have to write all these from scratch.

Libraries like Spatie’s Laravel Media Library define image conversions and optimize versions automatically using jpegoptim, pngquant, etc. Intervention’s Imagecache generates and caches resized images on the fly.

Spatie’s Laravel Media LibraryjpegoptimpngquantIntervention’s ImagecacheCloudinaryImageKit

CDNs/services like Cloudinary and ImageKit can do this externally, but purely in PHP/Laravel, just process at upload or in background jobs: immediately optimize the file, then store it.

Cloudinary blog shows ImageOptimizer::optimize(\$source, \$dest) after upload as best practice.


Practical tips in code: In your Laravel controller/job: (a) accept the upload; (b) load it, e.g. \$img = Image::make(\$filePath); then resize, encode, and save. Example:

use Intervention\Image\Facades\Image;
...
$file = $request->file('photo');
$filename = time() . '.jpg';
$img = Image::make($file->getRealPath());
$img->resize(1200, null, function ($constraint) {
    $constraint->aspectRatio();
    $constraint->upsize();
});
$img->encode('jpg', 75);
$img->save(storage_path('app/public/photos/'.$filename));
Enter fullscreen mode Exit fullscreen mode

For WebP:

$img->encode('webp', 80)->save(...);
Enter fullscreen mode Exit fullscreen mode

With Spatie’s image package:

\Spatie\Image\Image::load($file->getRealPath())->optimize()->save(storage_path('app/public/optimized/'.$filename));
Enter fullscreen mode Exit fullscreen mode

Tutorials for Laravel 11 and more show this pattern after upload.


To hit ~50–100 KB often means lower quality or smaller dimensions. Experiment with quality settings; sometimes saving at 50 quality is fine for previews.

WebP/AVIF look good even at moderate quality.

Use responsive images (multiple sizes, srcset in HTML) so browsers pick smaller files on mobile. Use lazy loading (loading="lazy") so offscreen images wait. These frontend tricks supplement your PHP back-end optimization.


Server-side performance and caching: Compressing large images is CPU-intensive.

For “on the fly” resizing, avoid reprocessing every request: cache the output on disk after first generation.

Intervention Imagecache or logic in your routes can check for cached versions and serve them. Spatie’s Media Library also caches conversions.

Don’t recompress on every page load—process on upload, or first requested size.

Strategies are described in Medium posts and package docs.


External services (optional): Services like Cloudinary (with a Laravel SDK) can offload all image optimization and deliver via CDN.

They apply transformations via URLs, require little code, and deliver fast images globally.

But you can achieve a lot with purely local PHP/Laravel libraries, per the original question focus.


To turn multi-megabyte uploads into fast images in Laravel: resize to needed dimensions, set quality, strip metadata, use efficient formats (WebP/AVIF). Do this at upload or before saving, using Intervention Image, Spatie/Image, or similar. This cuts file size from MB to tens of KB with little visual loss.

This transforms heavy uploads into light, web-ready images for a fast user experience.


Integrate image processing at upload (or first request) in Laravel.

Resize, compress, and convert formats using PHP libraries.

Web Almanac and other sources stress that unoptimized images still slow modern sites—automated, library-driven optimization is essential.

Using packages like Intervention/Image and Spatie’s tools, a 5 MB upload can become a 100 KB or smaller site image, making pages far snappier to load.


Sources: Based on industry analysis and documentation, including 2022 Web Almanac, Cloudinary, Twilio, Intervention Image docs, and various Laravel-focused tutorials (Spatie, serveravatar.com, ItSolutionStuff).

Emphasizes resizing, compressing, stripping metadata, and modern formats as best practices.

Top comments (0)