Appearance
Image compression
Image sizes made lighter by the compression tools on the server.
kitloom/media-optimizer · admins: kitloom/media-optimizer-filament, kitloom/media-optimizer-nova
Video lessons
Recorded in the Filament admin; the Nova admin works the same way.
Lighter images: every size the media library cuts — thumbnail, medium, large, your own, the -scaled copy of a big photo — goes through the compression tools on the server before it is written. Pages show the sizes, not the originals, so this is what visitors download: typically a fifth to a half less for photos, more for PNG screenshots and drawings. It is what Smush or EWWW do in WordPress, with the tools on your own server.
Built on spatie/image-optimizer.
What the server needs
The tools are ordinary programs, installed apart from the site. Each one is optional: the site works without any of them, and a format whose tool is missing is stored as before.
| Tool | Format | What it does |
|---|---|---|
jpegoptim | JPEG | removes camera data, rebuilds the file progressive; quality capped at 85 |
pngquant | PNG | reduces the colours to a palette — the biggest gain, slightly lossy |
optipng | PNG | squeezes what pngquant left, losslessly |
gifsicle | GIF | optimises the frames |
cwebp | WebP | encodes again; kept only when smaller |
bash
# Debian, Ubuntu (Forge, Ploi)
sudo apt-get install -y jpegoptim pngquant optipng gifsicle webp
# Alpine (Docker)
apk add --no-cache jpegoptim pngquant optipng gifsicle libwebp-tools
# macOS
brew install jpegoptim pngquant optipng gifsicle webpInstall them on every server that takes uploads: the web servers and the queue workers (a WXR import downloads and cuts images too). PHP has to be allowed to start processes: on shared hosting proc_open is sometimes in disable_functions, and then nothing is compressed.
To see what this server has: Image compression → Status in the admin (kitloom/media-optimizer-filament, kitloom/media-optimizer-nova) — it lists every tool, where it was found, and the install commands when one is missing. From the console:
bash
php artisan media:optimizersThe admin page asks the site itself; run the command as the user the site runs as. PHP-FPM often starts with a short PATH (/usr/bin:/bin), so a tool in /usr/local/bin or /opt/homebrew/bin may be found by your shell and not by the site — name its folder in MEDIA_OPTIMIZE_PATH.
What is compressed
- The sizes and the scaled copy — yes, on every upload: both admins, the visual editors,
Media::upload(),Media::fromUrl(), a WXR import. - The original — no. It is the source every size is cut from again; compressing it with loss would lower the quality of every later regeneration.
- Images already in the library —
php artisan media:regeneratecuts their sizes again from the originals, and the new sizes come out compressed.
A tool's result is kept only when it is smaller than what the tool was given. A tool that fails or takes longer than the time limit leaves the size as it was, with a warning in the log; an upload never fails because of compression.
Compression runs while the file is uploaded: the upload waits for the tools to go over each of the image's four or five sizes.
Turning it off
- The Modules screen: disable «Image compression».
MEDIA_OPTIMIZE=falsein.env— for example on a local machine.- One tool only:
falsein place of its options (below).
Configuration
php artisan vendor:publish --tag=kitloom-media-optimizer-config for config/kitloom-media-optimizer.php:
| Key | Default | |
|---|---|---|
enabled | MEDIA_OPTIMIZE, true | false — sizes stay as GD made them |
path | MEDIA_OPTIMIZE_PATH | a folder looked in before PATH |
timeout | 60 | seconds one tool may take over one size |
tools | spatie's defaults | tool => its command-line options; false — not used |
filament.register, nova.register | true | the «Image compression» section in each admin |
php
'tools' => [
'jpegoptim' => ['-m80', '--force', '--strip-all', '--all-progressive'], // stronger
'cwebp' => false, // leave WebP alone
],Which tools the server has is looked up once per process: after installing one, restart PHP-FPM, Octane and the queue workers.
AI agents
With kitloom/ai installed, an agent whose user has manage_options reads the same status as the admin's screen — media_optimizer_status: the overall state, each tool and whether this server has it (without its path), and the install commands when one is missing — so it can tell the owner why uploads come out heavy. It changes nothing: the tools are programs on the server. kitloom-media-optimizer.ai.register false — no such tool.
For developers
The package binds Kitloom\Media\Contracts\ImageOptimizer (kitloom/media), which the media library's ImageResizer asks for every size it cuts. An application with a compression of its own — a cloud service, an image CDN — binds the contract itself instead of installing this package.
Tests
From the application that installs the package: php vendor/bin/phpunit --testsuite MediaOptimizer. The tests use shell scripts named as the tools, so they do not depend on what is installed; one test runs the real cwebp when the machine has it.