Preimage
Measured images for pretext. Preimage loads and measures images before layout runs — so browser reflows don't happen, text can wrap around figures whose dimensions aren't declared, and canvas/SVG/WebGL renderers get correct fit math without relying on CSS.
Demos
Each demo has per-panel Run buttons — click one side at a time to feel the click-to-layout delay. Photos are committed locally (~1-3MB PNGs) so cache-busting is honest and there's no CDN redirect chain skewing the numbers.
Packing — shortest columns and justified rows
Runtime-probe one local image set, then pack the same aspect ratios two ways. Shortest columns gives masonry-style balance; justified rows closes Flickr-style strips at a target row height.
Editorial article with floats
Three floated figures inside flowing paragraph text. Naive HTML reflows as each figure decodes. Pretext + preimage measures up front and flows the text around the measured rects via flowColumnWithFloats.
Time to first sizing
One ~3MB local PNG loaded three ways: naive <img src>, declared width/height attrs, and prepare(). The timestamp shows when each strategy knows the dimensions.
Decode pool for canvas timelines
Sixteen ~1-3MB PNG frames scrubbable on a canvas. Left decodes on every scrub on the main thread; right warms a DecodePool up front and each scrub is a single cached-bitmap blit.
Virtual — ten thousand tiles, DOM-recycled
The chicken-and-egg of windowing: you need heights to position items, but heights come from loading them. Crank to 10k tiles — naive side opens 10k parallel fetches and the CSS column layout thrashes on every arriving image. Measured side probes dims-only, packs the full layout synchronously, and recycles ~40 DOM nodes as you scroll. Scrollbar is honest from frame one.
Manifest — build-time dimensions, instant layout
Cold prepare(url) versus recordKnownMeasurement hydrated from a preimage-manifest JSON. Same 34 photos, same cache-bust, same layout. Cold pays a network probe per URL. Hydrated resolves every prepare() synchronously from cache — layout commits in microseconds.
Stream — reserve space mid-stream
Same photo streamed to both panels under a throttle (simulates a WebSocket, AI-gen feed, or slow CDN). Left buffers every byte, builds a Blob, sets img.src, and only then knows the size — space pops in at the end. Right pipes the same stream through probeImageStream: the first chunk's header fires onDims, space reserves mid-stream, the final Blob renders into it when the stream drains.
Drop zone — Blob inputs
Drag images from your desktop. Left panel inlines them as naive <img> — each file's width is unknown until decode, so surrounding text shifts. Right panel runs prepare(file) — byte-probe on the first 4KB of the blob, ~5ms — and writes the exact width into the <img> before insert.
Chat — pretext rich-inline
A chat bubble with text, avatar icons, stickers, and photo attachments mixed inline. inlineImage turns each image into a pretext RichInlineItem with its measured width reserved as extraWidth. Drag the bubble-width slider — text rebreaks and images shuffle to new positions in one synchronous flow pass.
Instant — what it looks like on a real site
500 photos probed live on page load. No build-time manifest, no Run button, no bench furniture. Measures every URL at concurrency 50 with the auto strategy, skeletons appear as placements resolve, DOM recycles as you scroll. The "zero prior knowledge" version — what the probe path feels like on a live site.
URL speed — paste arbitrary image URLs
Paste HTTP(S) image URLs and measure time-to-dimensions, time-to-preview, source, and exposed byte counts with the current probe strategy and concurrency controls.