kasuken / kasuken/LearnStack

Move resource thumbnails out of SQL Server and stop base64-inlining them

Open
#45 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement
Dominant language
HTML
Stars
10
Forks
0
Avg merge
2h 52m
Merged PRs (30d)
20

Description

Tier 2 — scale

Problem

LearningResource.ThumbnailImage is a varbinary(max) column holding images of up to 5 MB, sitting on the same row as the resource. Every list query loads it, and every render base64-inlines it into the HTML — so a 20-card page can push tens of MB through the SignalR circuit. This already forced the removal of persistent component state (commit a003ea8, "prevent oversized Blazor circuit state"); the underlying cause was never addressed, so the cost just moved to re-rendering.

Evidence
  • LearnStack.Core/Data/Models/LearningResource.cs:42
  • LearnStack.Core/Services/OpenGraphService.cs:252-258 — accepts images up to 5 MB
  • LearnStack/Components/Pages/SharedView.razor:164, Resources.razor:268-270, Shared/ResourceCard.razor:130, Pages/FriendResources.razor:174
Proposed fix
  1. Store blobs in Azure Blob Storage (or at minimum a separate table) keyed by resource id.
  2. Serve them from a cached GET /thumbnails/{id} endpoint with proper Cache-Control and ETag.
  3. Downscale and re-encode on ingest (~400 px wide WebP, tens of KB).
  4. Never select the blob column in list projections.
Acceptance criteria
  • No base64 image data in rendered markup
  • List queries do not transfer image bytes
  • Existing thumbnails migrated

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Read LearningResource.cs:42 and OpenGraphService.cs:252-258 first, then trace thumbnail rendering in SharedView.razor:164, Resources.razor:268-270, Shared/ResourceCard.razor:130, and FriendResources.razor:174. Done means list queries avoid image bytes, rendered markup contains no base64 data, thumbnails are served through the proposed endpoint, and existing thumbnails are migrated.

Written by the indexing model from the issue text.

Assessment

Tech stack
azure, csharp, sql
Domain
api, backend, cloud, databases, performance
Issue type
Refactor
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
32/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.