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;
|
||||
|
||||
/** 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 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.
|
||||
@@ -454,7 +473,7 @@ async function encodeWebp(
|
||||
{ rotate: {} },
|
||||
...(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;
|
||||
|
||||
Reference in New Issue
Block a user