From ec96fced40f51da44484d1c4a996b7072553917d Mon Sep 17 00:00:00 2001 From: Masahiko AMANO Date: Wed, 10 Jun 2026 14:50:32 +0300 Subject: [PATCH] perf(backend): cache thumbnail, preview and content responses These endpoints had no Cache-Control, so the browser re-downloaded every thumbnail on each grid mount (the client fetches them with an auth header, which also bypasses default image caching). Returning to the grid after viewing a file re-fetched the whole visible page of thumbnails. Add Cache-Control: private, max-age=3600. Content is immutable per file id from the client's perspective (there is no replace-content UI); a future replace flow should cache-bust via a versioned URL. Co-Authored-By: Claude Opus 4.8 --- backend/internal/handler/file_handler.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/backend/internal/handler/file_handler.go b/backend/internal/handler/file_handler.go index 547ed0d..e273402 100644 --- a/backend/internal/handler/file_handler.go +++ b/backend/internal/handler/file_handler.go @@ -382,6 +382,7 @@ func (h *FileHandler) GetContent(c *gin.Context) { defer res.Body.Close() c.Header("Content-Type", res.MIMEType) + c.Header("Cache-Control", "private, max-age=3600") if res.OriginalName != nil { c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%q", *res.OriginalName)) @@ -457,6 +458,7 @@ func (h *FileHandler) GetThumbnail(c *gin.Context) { defer rc.Close() c.Header("Content-Type", "image/jpeg") + c.Header("Cache-Control", "private, max-age=3600") c.Status(http.StatusOK) io.Copy(c.Writer, rc) //nolint:errcheck } @@ -479,6 +481,7 @@ func (h *FileHandler) GetPreview(c *gin.Context) { defer rc.Close() c.Header("Content-Type", "image/jpeg") + c.Header("Cache-Control", "private, max-age=3600") c.Status(http.StatusOK) io.Copy(c.Writer, rc) //nolint:errcheck }