Sondajul de meniu repetat: 44 din 51 de cereri API pe pagina de produs sunt aceleași
Ca să afle care linkuri din meniu să afișeze, site-ul face pe fiecare deschidere de pagină de produs 44 de drumuri dus-întors separate până la server, cerând de patru ori aceleași adrese. Pe o conexiune mobilă din Moldova fiecare drum costă zeci sau sute de milisecunde, iar ele se bat pe aceeași bandă și aceleași conexiuni cu imaginea principală — exact resursa care decide LCP-ul. E și sarcină inutilă pe backend: zeci de interogări în baza de date pentru un răspuns identic pentru toți vizitatorii.
Ce am găsit
44 de cereri duplicate pe pagina de produs, 22 pe pagina de start
Măsurat pe producție, încărcare completă (nu navigare în aplicație), viewport 375px, cu performance.getEntriesByType('resource'):
-
https://hyperice.md/products/hypervolt-3-pro→ 92 de cereri totale, 51 către API, dintre care 44 sunt sondajul de meniu. Fiecare din cele 10 colecții de navigație (accessories,hyperboot-by-nike-hyperice,hyperice-x,hypervolt,normatec,outlet,sale,shop-all,venom,vyper-hypersphere) plus/api/products/gift-carde cerută de exact 4 ori:4x /api/collections/hypervolt?locale=ro,4x /api/collections/normatec?locale=ro,4x /api/collections/shop-all?locale=roși așa mai departe. -
https://hyperice.md/→ 67 de cereri, 32 către API, 22 sondaj de meniu — aceleași adrese, de 2 ori fiecare.
Cauza: două componente montate pe fiecare pagină, fără cache comun
frontend/src/components/Header.tsx:60-61 și frontend/src/components/Footer.tsx:180-181 apelează, fiecare independent, aceleași două cârlige:
const publishedSlugs = usePublishedNavCollectionSlugs();
const publishedProductHandles = usePublishedNavProductHandles();
Cârligele — frontend/src/lib/catalog.ts:229 și :275 — nu au niciun cache comun: fiecare instanță pornește propriul useEffect care face Promise.all peste navigationCollectionSlugs (frontend/src/data/navigation.ts:334), adică o cerere per slug. Efectul depinde de locale, deci se reia când se așază limba — de aici cele 4 runde de pe pagina de produs (2 componente × 2 rulări), față de 2 pe pagina de start.
Răspunsurile nu se pot recupera din cache
$ curl -sI "https://api.hyperice.md/api/products?locale=ro"
... etag: ...
... cf-cache-status: DYNAMIC
Niciun antet Cache-Control, deci nici măcar cererile identice consecutive nu sunt servite din cache.
De făcut
-
Un singur punct de adevăr pentru vizibilitatea meniului: fie un endpoint care întoarce dintr-o dată setul de slug-uri publicate, fie un cache la nivel de modul în frontend/src/lib/catalog.ts— o promisiune per limbă, refolosită de toți apelanții — astfel încâtHeaderșiFootersă citească același rezultat. -
Cache-Control: public, max-age=60pe acest răspuns, fiind identic pentru toți vizitatorii.
Criteriu de acceptare
Pe încărcare completă la 375px, măsurat cu performance.getEntriesByType('resource'): /products/hypervolt-3-pro face cel mult 10 cereri API, fără nicio adresă repetată; pagina de start, cel mult 10, tot fără repetări.