Pingap ImageOptim
On-the-fly image optimization for Pingap.
This crate provides the image_optim plugin: it intercepts PNG and JPEG
responses coming back from an upstream and re-encodes them — either at a lower
quality in the same format, or into a modern format (WebP or AVIF) when the
client says it accepts one.
The point is to get the bandwidth savings of modern formats without changing the origin: the origin keeps storing PNG/JPEG, and Pingap negotiates per client.
Building
The crate is behind a cargo feature and is not compiled by default:
Supported formats
| Direction | Formats |
|---|---|
| Input (from upstream) | image/png, image/jpeg |
| Output (to client) | png, jpeg, webp, avif |
Configuration
Registered as plugin category image_optim:
[]
= "image_optim"
= "avif,webp"
= 85
= 80
= 70
= 4
| Key | Type | Default | Description |
|---|---|---|---|
output_types |
string | "" |
Comma-separated target formats. Each becomes image/<format> and is matched against the client's Accept. |
png_quality |
int | 90 |
1–100; out-of-range resets to the default. |
jpeg_quality |
int | 80 |
1–100. |
avif_quality |
int | 75 |
1–100. |
avif_speed |
int | 3 |
1–10. Higher is faster to encode and produces larger files. |
Full plugin documentation, including the cache interaction, is in pingap-plugin/docs/image_optim.md.
How it works
requeststep — the client'sAcceptheader is inspected. Every configured output MIME type the client accepts is sorted and appended to the cache key, so AVIF-capable and legacy clients get separate cache entries.upstream_responsestep — if the response is PNG or JPEG and the client accepts one ofoutput_types, a body modifier is installed and the response is re-framed as chunked.upstream_response_bodystep — the body is buffered and re-encoded, andContent-Typeis updated to the chosen format.
Underlying encoders
| Format | Crate |
|---|---|
| PNG | imagequant + lodepng |
| JPEG | mozjpeg |
| WebP / AVIF | image (with the webp and avif features) |
Some of these compile native code, which is why the crate is optional: it makes the default build noticeably slower and larger.
Performance
Re-encoding is CPU-bound and, for AVIF, expensive. Always put a
cache plugin in front so each image is
converted once per variant rather than once per request, and list the cache
plugin before image_optim in the location's plugins.
avif_speed is the main trade-off knob: 1–2 produce the smallest files and
are only viable behind a warm cache; 4–6 is a reasonable live default.
License
Apache-2.0.