Skip to content

Ia JavaScript-ul de pe drumul primei vopsiri, și dă primei pagini cadrul ei

Vitalie requested to merge 44_first-paint-priorities into main

Patru schimbări care iau octeți de pe drumul primei vopsiri, plus reparația issue-ului #66 (closed), care e condiția ca jumătatea de „prima pagină" din criteriul lui #44 (closed) să poată fi măsurată.

De ce astea și nu pasul scris în #44 (closed)

Pasul din issue — foaia de stiluri urcă înaintea preîncărcărilor de fonturi — valorează zero. Măsurat: Lighthouse nu pune fonturile pe seama primei vopsiri deloc. Regula lui e hasRenderBlockingPriority: orice cerere VeryHigh, plus orice script de prioritate High terminat înainte de vopsirea observată. Pe pagina de produs asta face 200.988 de octeți, din care doar 21.675 — documentul și foaia de stiluri — blochează cu adevărat randarea. Restul de ~179 KB sunt JavaScript.

Atribuire deterministă, aceleași artefacte de rulare, o singură schimbare pe rând (control: FCP 3,09 s / LCP 3,47 s):

Schimbare FCP LCP
foaia de stiluri deasupra fonturilor 0 0
preîncărcările de chunk-uri de rută scoase −0,61 s −0,80 s
JavaScript-ul pe prioritate mică −1,33 s 0
foaia de stiluri scrisă în document 0 −0,19 s
beaconul Cloudflare scos (din panou, nu din cod) −0,19 s −0,19 s
toate 0,91 s 2,29 s

Timpul până la interactivitate rămâne 2,52 s cu sau fără prioritatea mică pe modulul de intrare — costul acelei schimbări e măsurat la zero.

Ce e onest de spus despre cifre

O parte din câștigul de FCP e felul în care Lighthouse ține contabilitatea: un modul e amânat prin definiție și nu blochează niciodată parserul într-un browser real. Mecanismul real prin care marcajul ajută e concurența pe bandă — poza cea mai mare primește firul înaintea aplicației. Câștigul de teren se citește în Search Console (#46), nu aici.

Ce am reparat după recenzie

Prima variantă scria <style>-ul în locul <link>-ului. Cei 70 KB mutau preconnect-ul și preîncărcarea imaginii LCP de la octetul 4.354 la 74.269 — dincolo de prima fereastră de congestie, iar scanerul de preîncărcare citește documentul în ordine. Lantern taxează octeți, nu poziții, deci costul era invizibil exact în unealta pe care s-a luat decizia. Foaia se scrie acum ultima în cap: blochează vopsirea la fel, iar cele două indicii rămân la 4.322 și 4.404, verificat pe documentul randat din build-ul real.

Din aceeași trecere: răspunsul negativ al aducerii foii de stiluri se memorează (altfel un redeploy costa o cerere eșuată per vizitator), iar capul și punctul de montare se completează prin funcții de înlocuire — conținutul lor e o foaie de stiluri, un titlu de produs și textul unei pagini, iar $& în oricare dintre ele e tipar de substituție pentru String.replace.

Verificare

  • backend/: npm run build trece, npm test 47 fișiere / 702 teste.
  • frontend/: npx tsc --noEmit -p tsconfig.app.json și npm run build trec, npm run lint cu singurul avertisment preexistent pe main, npm test 42 fișiere / 502 teste.
  • Randare locală cap-coadă cu build-ul real servit ca origine de frontend: prima pagină și pagina de produs pleacă fără <link rel="stylesheet">, cu <style> ultimul în cap, cu modulul de intrare pe fetchpriority="low" și fără preîncărcări de chunk-uri de rută; pagina de colecție păstrează cele zece preîncărcări.

Cifrele din criteriul de acceptare al lui #44 (closed) se măsoară pe producție după deploy, mediana a cinci rulări, pe amândouă paginile. Issue-ul rămâne deschis până atunci.

Closes #66 (closed)

Merge request reports