Optimizing image again
By Jeff Byer
Updated todo list
I'll add client-side resize + WebP recompression in media.ts so it runs before upload — no extra Worker cost, works for both the Media page upload and the MarkdownField drag/paste/upload flow.
Replacing 22 lines with 109 lines in
The Media admin page bypasses uploadMedia with a raw fetch. Let me route it through the same helper.
Replacing 34 lines with 29 lines in
Created 2 todos
Ran terminal command: npm run check 2>&1 | tail -5 && npm run build 2>&1 | tail -5 && npx wrangler deploy 2>&1 | tail -5
Deployed (version f58add9a).
What happens on upload now (media.ts):
- Image is decoded in the browser via
createImageBitmap(file). - If the longest edge exceeds 2000px, it's downscaled proportionally.
- Re-encoded to WebP at quality 0.85 using
OffscreenCanvas.convertToBlob()(with anHTMLCanvasElement.toBlobfallback for older browsers). - Uploaded with a
.webpfilename.
Safe-fallback cases that skip processing (original file uploaded unchanged):
- Non-image MIME types.
image/svg+xml(would rasterize a vector — bad).image/gif(would lose animation).- Browser can't decode (e.g. HEIC on non-Safari) —
createImageBitmapthrows → original passes through. - Image is already under the cap and already WebP — no work to do.
- Re-encoded result would be larger than the original (rare with pre-compressed input).
Coverage: every upload path now uses this:
- Drag/paste/Insert-image inside the MarkdownField (was already calling
uploadMedia). MediaImageFieldfor post cover / OG / person photo (was already callinguploadMedia).- The Media library's upload button (previously did a raw
fetch; now routed throughuploadMedia).
Tuning knobs: uploadMedia(file, { maxDimension, quality }) accepts overrides if you want, e.g., a tighter cap for inline body images vs. cover images. The server side (api/media/upload) already allows image/webp and enforces a 10 MB ceiling as a final guard.
Want me to drop a tighter cap (say 1200px) on inline body-image uploads from the MarkdownField, while keeping 2000px for cover images?
Made changes.