Repository navigation
perf(studio): cacheable image previews and colour placeholders - #69
Merged
Merged
Conversation
Studio's previews were `private, no-store`, so the media grid downloaded every original (3.4 MB on cloudhal.com) on every visit, each through the authenticated D1 path, behind a spinner. - Preview URLs carry the bytes' hash (`?v=<sha16>`); a matching `v` gets `private, max-age=86400` (a day, so a takedown does not linger long). Without it the route answers `private, no-cache`, so the ETag gives a 304. - `ImagePreview` takes an optional `placeholder` (`Asset.image.color`, `.lqip`, computed at upload) and paints it while the image loads, instead of a spinner; Studio's asset tiles pass it. - `contentHeaders` moves to `routes/asset-content-headers.ts` (assets.ts 833 lines, baseline lowered). Co-Authored-By: Claude Opus 5.5 <[email protected]> Signed-off-by: Madraka <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes 3 and 5 of the internal performance review (Studio media).
Before:
GET /api/sites/:id/assets/:id/contentansweredprivate, no-store, so the browser re-downloaded every original on every visit (3.4 MB of 2880 px PNGs for the Media grid on cloudhal.com), each through the authenticated D1 path (0.4–2 s to first byte), with only a spinner meanwhile. The ETag/304 code existed butno-storedisabled it.Now:
…/content?v=<first 16 hex of sha256>(assetPreviewUrl,AssetPage). A matchingvgetsprivate, max-age=86400. That's a day, not a year, so a file taken down does not linger in staff browsers; the bytes behind the URL never change. Withoutv(or with a stale one) the route answersprivate, no-cache, and the browser revalidates with the ETag and gets a 304.ImagePreview(@cloudhal/ui) takes an optionalplaceholder: { color, lqip }. While loading, it paints the image's dominant colour and blurred preview (both computed at upload, RFC-0028) instead of the spinner; the loading label stays for screen readers.AssetFramepassesasset.image.contentHeadersmoved toroutes/asset-content-headers.ts, soroutes/assets.tsshrinks 853 → 833 lines (baseline lowered).Tests: shared assets suite (no-cache without
v, 304 with the ETag, a day with a matchingv, no-cache with a stale one);image-preview-placeholder.test.tsx; Studio design rules and media-lib updated. API 371/371, UI 201/201, Studio design rules + media 518/518.Not in this PR: resized variants (fix 14, needs an RFC) and public
/media/URLs for published assets (fix 13).🤖 Generated with Claude Code