52 lines
2.0 KiB
Plaintext
52 lines
2.0 KiB
Plaintext
grisemonster image variants
|
|
===========================
|
|
|
|
Source: grisemonster-lossless-original.png (2048x1024 RGBA PNG, 2.0M)
|
|
|
|
Files in use
|
|
------------
|
|
grisemonster-2048.png 443K desktop (>1280px viewport)
|
|
grisemonster-1280.png 227K tablet (601-1280px)
|
|
grisemonster-800.png 97K mobile (<=600px)
|
|
|
|
The previous single grisemonster.png was 624K served to every device.
|
|
Mobile now downloads 97K (-84%); desktop downloads 443K (-29%).
|
|
|
|
How they were generated
|
|
-----------------------
|
|
For each width W in {2048, 1280, 800}:
|
|
|
|
magick grisemonster-lossless-original.png -resize ${W}x base.png
|
|
pngquant 64 --quality=50-80 --speed 1 --output grisemonster-${W}.png base.png
|
|
oxipng -o max --strip safe grisemonster-${W}.png
|
|
|
|
pngquant reduces to a 64-colour palette (the image is a flat
|
|
illustration with very few distinct colours, so this is visually
|
|
lossless at the displayed scale). oxipng then does a lossless
|
|
re-encode pass to squeeze the PNG further.
|
|
|
|
Wired up in src/components/layout/footer.module.scss via two
|
|
min-width media queries on `.pigPattern`'s background-image.
|
|
|
|
Why PNG, not WebP/AVIF
|
|
----------------------
|
|
Tested at 2048 width:
|
|
|
|
PNG (pngquant 64 + oxipng) 443K <-- chosen
|
|
PNG (pngquant 256 + oxipng) 522K
|
|
AVIF q50 493K
|
|
AVIF q60 598K
|
|
AVIF q75 718K
|
|
WebP q75 829K larger than current PNG
|
|
WebP q85 903K larger than current PNG
|
|
WebP lossless 1.0M larger than current PNG
|
|
|
|
For this kind of content -- a flat, limited-palette illustration with
|
|
large transparent regions -- palette PNG is the smallest format.
|
|
WebP and AVIF are tuned for photographic content and lose to a
|
|
well-quantised PNG here. Visual quality of the three PNG/AVIF options
|
|
above was indistinguishable at the rendered scale.
|
|
|
|
Conclusion: the win came from responsive sizing, not from changing
|
|
format. Stayed on PNG to keep the CSS simple (no image-set() needed).
|