Bannerul paginii de start să vină odată cu HTML-ul, nu printr-o cerere separată
Imaginea principală se descarcă acum din prima (#21 (closed)), dar nu poate fi desenată până nu sosesc textele bannerului printr-o cerere separată. Măsurat pe producție după #21 (closed): fișierul e complet la 636 ms, iar datele bannerului abia la 1.262 ms — imaginea stă gata în memorie mai bine de o jumătate de secundă, degeaba.
Ce am găsit
Lanțul de pe https://hyperice.md/, Lighthouse 13.4.1 mobil:
2 -> 186 HTML
219 -> 630 assets/index-*.js
220 -> 636 uploads/75456663-….jpg <- imaginea principală, gata
985 -> 1128 OPTIONS /api/banners <- permisiunea CORS (vezi #35)
1128 -> 1262 GET /api/banners <- textele și adresa bannerului
LCP-ul raportat rămâne 5,7 s: elementul e desenat de React, care nu are ce desena până la 1.262 ms, iar apoi mai urmează randarea.
Cererea pornește la 985 ms pentru că frontend/src/components/HeroBanner.tsx o face dintr-un useEffect, adică după ce pachetul de intrare s-a descărcat, a rulat și a montat componenta.
Soluția
Randarea de pe server (backend/src/services/render-page.ts) citește deja bannerele ca să scrie <link rel="preload"> pentru prima imagine — deci le are în mână când scrie documentul. Scrise în HTML ca stare inițială, hero-ul se desenează la prima randare a lui React, fără să mai aștepte nimic.
Componenta are deja exact acest mecanism: HeroBanner își ia starea inițială dintr-o copie păstrată în sessionStorage, tocmai ca să nu clipească la reîncărcare. Diferența e că acea copie nu există la prima vizită — care e chiar vizita măsurată de Google.
De făcut
-
Scrie bannerele publice în document din render-page.ts, în limba paginii, alături depreload-ul pe care îl emite deja -
HeroBannerîși ia starea inițială din document când există, înaintea copiei dinsessionStorage; cererea către/api/bannersrămâne, ca o editare din panou să se vadă fără redeploy -
Datele scrise în document se escapează pentru context de <script>, ca JSON-LD-ul din același fișier
Criteriu de acceptare
Pe încărcare completă a paginii de start, măsurat pe producție: hero-ul e desenat fără să se aștepte răspunsul /api/banners, iar LCP-ul scade sub valoarea de acum (5,7 s). Un banner editat din panou se vede în continuare la reîncărcarea paginii.