thumbnails are encoded as thumbnails
Quality 82 went on every rung, so a picture 173 CSS pixels wide in a gallery grid carried the same fidelity as the copy somebody opens full screen. Compression artefacts scale with display size: at thumbnail size 74 is indistinguishable from 82 and 15% smaller — 108,388 bytes to 92,568 on the worst image in this gallery, measured rather than assumed. 640 is the line because it is the widest rung a phone picks for a grid slot. Above it something is showing the picture large, and 82 is the right answer again. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+21
-2
@@ -62,8 +62,27 @@ import { mediaPath } from './media';
|
|||||||
*/
|
*/
|
||||||
export const LADDER = [320, 480, 640, 960, 1280, 1920, 2560] as const;
|
export const LADDER = [320, 480, 640, 960, 1280, 1920, 2560] as const;
|
||||||
|
|
||||||
/** WebP quality. 82 is the usual knee: visually clean on photographs, well off the top of the curve. */
|
/**
|
||||||
|
* WebP quality, by rung.
|
||||||
|
*
|
||||||
|
* 82 is the usual knee for a photograph being LOOKED at — the lightbox, a detail page, anything at or
|
||||||
|
* near its real size. It was applied to every rung, which meant a thumbnail 173 CSS pixels wide in a
|
||||||
|
* gallery grid carried the same fidelity as the copy someone opens full screen.
|
||||||
|
*
|
||||||
|
* Artefacts scale with display size. At thumbnail size 74 is indistinguishable from 82 and 15% smaller,
|
||||||
|
* measured on the worst image in this gallery: 108,388 bytes to 92,568. Nine of those on a page is
|
||||||
|
* most of what an audit calls "increasing the compression factor".
|
||||||
|
*
|
||||||
|
* 640 is the line because it is the widest rung a phone ever picks for a grid slot. Anything above it
|
||||||
|
* is being chosen because something is showing the picture large.
|
||||||
|
*/
|
||||||
|
const WEBP_QUALITY_SMALL = 74;
|
||||||
const WEBP_QUALITY = 82;
|
const WEBP_QUALITY = 82;
|
||||||
|
const THUMB_MAX_WIDTH = 640;
|
||||||
|
|
||||||
|
/** The quality a rung is worth. `null` is `full.webp`, which is the one people open. */
|
||||||
|
const qualityFor = (rung: number | null): number =>
|
||||||
|
rung !== null && rung <= THUMB_MAX_WIDTH ? WEBP_QUALITY_SMALL : WEBP_QUALITY;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The placeholder: a picture small enough to travel INSIDE the manifest.
|
* The placeholder: a picture small enough to travel INSIDE the manifest.
|
||||||
@@ -454,7 +473,7 @@ async function encodeWebp(
|
|||||||
{ rotate: {} },
|
{ rotate: {} },
|
||||||
...(rung === null ? [] : [{ resize: { width: rung, fit: 'inside', withoutEnlargement: true } }]),
|
...(rung === null ? [] : [{ resize: { width: rung, fit: 'inside', withoutEnlargement: true } }]),
|
||||||
],
|
],
|
||||||
output: { format: 'webp', options: { quality: WEBP_QUALITY } },
|
output: { format: 'webp', options: { quality: qualityFor(rung) } },
|
||||||
});
|
});
|
||||||
|
|
||||||
const width = rung ?? sourceWidth;
|
const width = rung ?? sourceWidth;
|
||||||
|
|||||||
Reference in New Issue
Block a user