Skip to content

fix(frontend): cache attachment blob urls across components - #3739

Open
tink-bot wants to merge 4 commits into
mainfrom
fix-attachment-blob-cache
Open

fix(frontend): cache attachment blob urls across components#3739
tink-bot wants to merge 4 commits into
mainfrom
fix-attachment-blob-cache

Conversation

@tink-bot

@tink-bot tink-bot commented Sep 4, 2026

Copy link
Copy Markdown
Collaborator

Every component fetch own attachment blob. No cache, no dedupe. Task detail with 19 attachments = 57 requests, ~33s cumulative (Sentry FRONTEND-OSS-1TP, "N+1 API Call"): 19x preview ?preview_size=md, plus 38x full original — every original pulled twice, because description editor and comment editor each keep own in-flight map (inFlightBlobFetches) and own loadedAttachments record.

Now one module-level cache in frontend/src/helpers/attachments.ts, keyed taskId-attachmentId-size, with in-flight promise map for dedupe. Same shape as fetchAvatarBlobUrl. Rejected fetch drop pending entry, so retry work. Cached urls shared — no consumer revoke them; clearAttachmentBlobCache() do that.

Switched: FilePreview.vue, KanbanCard.vue cover image, editor inline images. Untouched, on purpose: AudioPreview.vue, Attachments.vue preview modal, attachmentService.download() — those own their blob and revoke it (unmount, decode error, modal close, download-to-disk), so shared cache would poison it.

How to verify

  1. Open a task that has several image attachments and an inline image in its description, with the browser network tab open.
  2. Reload the page and watch the requests to /api/v1/tasks/:id/attachments/:id.
  3. Expected: each attachment/size combination is requested exactly once. The inline description image is fetched once even though the description editor and the comment editor both render it.
  4. Before this PR: each preview was refetched on every render and every inline image was fetched twice, once per editor instance.

Attachment blob urls were fetched per component instance with no caching
or deduplication, so a task with many attachments issued one request per
attachment per consumer.
@github-actions github-actions Bot added area/attachments File attachments on tasks: upload, preview, download area/frontend Frontend-only code or UI work concern/performance Slow, laggy, or scaling issues labels Sep 4, 2026
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown

Preview Deployment

Preview deployments for this PR are available at:

URL Tag Commit
https://pr-3739.preview.vikunja.dev ghcr.io/go-vikunja/vikunja:pr-3739 latest
https://sha-e2f5b624f8d9dba7df7839b2f344db2cfd61be0e.preview.vikunja.dev ghcr.io/go-vikunja/vikunja:sha-e2f5b624f8d9dba7df7839b2f344db2cfd61be0e e2f5b62

The preview environment will start automatically on first visit. Subsequent pushes to this PR will update the pr-3739 image — the preview picks up the new version on restart. The per-commit URLs point to a specific version and will not change.

Run locally with Docker
docker pull ghcr.io/go-vikunja/vikunja:pr-3739
docker run -p 3456:3456 ghcr.io/go-vikunja/vikunja:pr-3739

Last updated for commit e2f5b62

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/attachments File attachments on tasks: upload, preview, download area/frontend Frontend-only code or UI work concern/performance Slow, laggy, or scaling issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants