Generated assets are served `private, no-store`, which is right for a clinical
app on a shared workstation — but it meant every gallery render re-downloaded
every image. Measured: 26 images averaging 279kB, so 7.2MB fetched to draw 56px
tiles, on every open of the Create image popup.
Two changes, both reusable anywhere in the app:
- A session cache holding decoded blobs in MEMORY ONLY, so nothing is written to
disk and the no-store posture is unchanged. Entries are keyed by owner ticket
as well as asset, and cleared when the account boundary moves, so one account
can never read another's bytes out of memory. Concurrent tiles asking for the
same asset share one request rather than racing.
- Any img carrying data-image-thumb gets a downscaled copy instead of the
original, so a 56px tile no longer decodes a 300kB image. The gallery asks for
256px and the in-chat preview for 640px; opening the full view still gets the
original. Browsers without OffscreenCanvas, and any decode failure, fall back
to the full image rather than showing nothing.
This does not reduce the first fetch. Serving genuinely smaller bytes needs
server-side resizing, which needs an image library this project does not carry —
worth a deliberate decision rather than adding a native dependency in passing.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GmpYHPSLGmXGZMyLpn2Lbe