Výpis posílá plná HTML těla záznamů — megabajty na kliknutí vypadají jako pomalý backend
Symptom
Sekce “Symptom”Přepínání kategorií/složek v seznamu (e-maily, dokumenty, logy) trvá sekundy, UI se “zasekává”. Uživatel si to vysvětluje po svém: “proč se to pořád načítá z IMAPu/externí služby?” — přitom data jsou dávno v lokální DB a SQL dotaz běží pod 1 ms.
Root cause
Sekce “Root cause”List endpoint vracel celé záznamy včetně TEXT sloupce s HTML obsahem:
prisma.emailLog.findMany({ where, include: {...}, take: 50 })// každý záznam nese body: ~120 kB HTML → 50 × 120 kB ≈ 6 MB JSONTabulka: 1,7 GB na 14 500 záznamů. Bottleneck nebyl SQL (0,1 ms) ani externí služba, ale serializace + přenos + parsování ~6 MB JSON na každé kliknutí. Na pomalejší lince/CPU se to projeví jako zaseknuté UI a svádí to k honění falešných stop (sync, indexy, cache).
Řešení
Sekce “Řešení”- List vrací místo plného obsahu jen krátký textový náhled:
const data = emails.map((e) => { const { body, ...rest } = e; const preview = (body || "").replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim().slice(0, 160); return { ...rest, preview };});- Detail má vlastní endpoint
GET /resource/[id], který vrací plný obsah (s autorizací na vlastníka) — frontend ho dotáhne až při otevření záznamu.
Výsledek: odpověď výpisu z ~6 MB na jednotky kB (~1000× méně), přepínání okamžité.
Jak to poznat příště
Sekce “Jak to poznat příště”- V DevTools Network má list request stovky kB až MB — response size je první, co u “pomalého výpisu” kontrolovat, ještě před EXPLAIN ANALYZE
- ORM
include/select: *na modelu s TEXT/JSON sloupcem v list dotazu = red flag při code review