Web Performance

Preload, prefetch și preconnect: când ajută fiecare cu adevărat

Indiciile pentru resurse sunt utile atunci când corespund unor blocaje reale ale browserului. Folosite orbește, adaugă zgomot de prioritate și uneori încetinesc paginile.

The Wux Webtools Team The Wux Webtools Team 11 min citire Asistat de AI, revizuit de oameni
A simplified browser loading waterfall showing early resource hints for a web page.
Cuprins
  1. Indiciile pentru resurse nu sunt magie
  2. Ce face deja bine browserul
  3. Preload: pentru resurse ale paginii curente descoperite prea târziu
  4. Preload și imaginile LCP
  5. Prefetch: pentru pagina următoare, nu pentru aceasta
  6. Preconnect: pentru conexiuni costisitoare către origini importante
  7. DNS-prefetch: vărul mai ușor
  8. Cum să decizi: un workflow practic
  9. 1. Identifică blocajul
  10. 2. Adaugă câte un indiciu pe rând
  11. 3. Verifică efectele secundare asupra priorității
  12. 4. Verifică headerele și caching-ul
  13. Greșeli comune
  14. Preloading pentru prea multe lucruri
  15. Folosirea prefetch pentru resurse necesare
  16. Preconnecting către fiecare terț
  17. Uitarea condițiilor mobile
  18. Un tabel simplu de decizie
  19. Regula calmă

Indiciile pentru resurse nu sunt magie

preload, prefetch și preconnect sunt tratate adesea ca o listă de verificare pentru performanță. Adaugi câteva taguri în <head>, rulezi din nou Lighthouse, te simți mai bine. Nu așa funcționează.

Aceste indicii sunt instrucțiuni pentru pipeline-ul de încărcare al browserului. Pot ajuta atunci când știi ceva ce browserul nu poate descoperi suficient de devreme. Pot dăuna atunci când ghicești, supra-prioritizezi muncă necritică sau încălzești conexiuni de care utilizatorii nu vor avea niciodată nevoie.

Versiunea scurtă:

  • Folosește preload pentru resurse necesare paginii curente, dar descoperite prea târziu.
  • Folosește prefetch pentru resurse probabile ale navigării viitoare, nu pentru elemente esențiale ale paginii curente.
  • Folosește preconnect pentru origini third-party importante, unde inițializarea conexiunii este o întârziere reală.

Întrebarea practică nu este „care indiciu este cel mai rapid?” Ci „ce așteaptă browserul și poate acest indiciu să elimine acea așteptare?”

Ce face deja bine browserul

Browserele moderne nu sunt descărcătoare pasive de fișiere. Ele parsează HTML, scanează înainte după resurse, atribuie priorități, reutilizează conexiuni, amână munca ce nu este vizibilă și se adaptează la condițiile de rețea.

Asta înseamnă că indiciile pentru resurse trebuie să fie selective. Dacă o foaie de stil, un script, o imagine sau un font este deja descoperit devreme și primește prioritatea corectă, adăugarea unui indiciu poate să nu facă nimic. Mai rău, poate concura cu resurse care contează mai mult.

Înainte de a adăuga indicii, uită-te la o trasare waterfall în DevTools sau la un raport de laborator. Dacă folosești Lighthouse, începe cu diagnosticele, nu cu scorul; avem un ghid separat despre citirea unui raport Lighthouse fără panică — dar reține că URL-ul corect este case-sensitive, așa că folosește articolul legat din navigația site-ului tău dacă este nevoie.

Dovezile reale sunt de obicei vizibile în trei locuri:

  1. O resursă critică pornește târziu deoarece browserul o descoperă târziu.
  2. O conexiune către o origine importantă durează vizibil înainte de prima cerere.
  3. O resursă pentru pagina următoare este foarte previzibilă și ieftin de preluat în timp inactiv.

Dacă niciuna dintre acestea nu este adevărată, un indiciu este probabil decorativ.

Preload: pentru resurse ale paginii curente descoperite prea târziu

preload îi spune browserului: „Preia această resursă acum, deoarece pagina curentă va avea nevoie de ea.”

Un exemplu tipic este un web font referențiat în CSS. Browserul trebuie să descarce HTML, să descopere CSS-ul, să descarce CSS-ul, să îl parseze, să descopere fontul și apoi să ceară fontul. Dacă acel font este important pentru textul vizibil inițial, descoperirea poate fi suficient de târzie încât să cauzeze deplasări de layout sau randare întârziată a textului.

Un preload poate muta acea cerere mai devreme:

<link rel='preload' href='/fonts/inter-var.woff2' as='font' type='font/woff2' crossorigin>

Atributul as contează. El îi spune browserului ce fel de resursă este aceasta, ceea ce afectează prioritatea, caching-ul, politica de securitate a conținutului și headerele cererii. Fonturile au de obicei nevoie și de crossorigin, chiar și când sunt servite de pe același site, deoarece preluarea fonturilor folosește modul CORS.

Candidați buni pentru preload includ:

  • Web fontul principal folosit pentru textul vizibil.
  • O imagine hero care este elementul Largest Contentful Paint și nu poate fi descoperită devreme.
  • Un fișier CSS critic încărcat indirect.
  • Un modul sau script necesar foarte devreme, dar ascuns în spatele altui script.

Candidați slabi pentru preload includ:

  • Fiecare greutate de font din design system.
  • Imagini de sub pliul paginii.
  • Scripturi care nu sunt necesare pentru randarea inițială.
  • Resurse pe care browserul le descoperă deja în primul fragment HTML.

Preload este puternic deoarece afectează prioritatea paginii curente. Tocmai de aceea este ușor de folosit greșit. Dacă faci preload pentru cinci asseturi mari, nu mai ajuți browserul. Te contrazici cu el.

Fonturile sunt cazul clasic. Preloading-ul unui singur fișier de font principal poate ajuta. Preloading-ul a șase greutăți și variante italice de obicei înrăutățește lucrurile. Dacă fonturile sunt blocajul tău, repară mai întâi setul de fonturi; ghidul nostru despre motivul pentru care web fonts are still the easiest performance win on most sites acoperă această curățare mai detaliat.

Preload și imaginile LCP

Preloading-ul unei imagini LCP poate fi util atunci când imaginea nu este vizibilă în HTML-ul inițial. Cauze frecvente includ imagini de fundal CSS, componente randate pe client sau logică pentru imagini responsive care apare târziu.

Dar dacă imaginea ta hero este deja în HTML ca un <img> cu srcset, sizes, dimensiuni și fără lazy loading, browserul o poate găsi probabil rapid. În acest caz, adăugarea fetchpriority='high' poate fi mai potrivită decât preload, în funcție de pagină.

Un test bun: dacă cererea imaginii pornește târziu în waterfall și devine elementul LCP, ia în calcul preload. Dacă pornește devreme, dar se descarcă lent, problema este dimensiunea, formatul, comportamentul CDN-ului sau latența serverului — nu descoperirea. Pentru decizii despre formatul imaginilor, vezi when AVIF beats WebP and when it does not.

Prefetch: pentru pagina următoare, nu pentru aceasta

prefetch îi spune browserului: „Această resursă ar putea fi necesară în curând, dar nu este necesară chiar acum.”

Această distincție este importantă. Prefetch este intenționat cu prioritate scăzută. Browserul o poate prelua în timp inactiv și o poate stoca pentru utilizare ulterioară. De asemenea, o poate sări pe conexiuni slabe, în moduri de economisire a datelor sau sub presiune de memorie.

Folosește prefetch când intenția utilizatorului este suficient de puternică încât următoarea resursă să fie probabilă.

Candidați buni pentru prefetch includ:

  • Pasul următor într-un checkout multi-pagină.
  • Rezultatele căutării după ce un utilizator începe să tasteze o interogare, dacă ruta următoare este previzibilă.
  • Pagini de documentație legate dintr-un cuprins, când utilizatorul citește activ conținut apropiat.
  • Fragmente de rută într-o single-page app după ce utilizatorul trece cu cursorul peste un element de navigație sau îl focalizează.

Candidați slabi pentru prefetch includ:

  • Întregul arbore de navigație.
  • Videoclipuri mari sau galerii de imagini.
  • Scripturi third-party „pentru orice eventualitate”.
  • Pagini pe care utilizatorii le vizitează rar în continuare.

Prefetch este locul unde reținerea dă rezultate. O resursă preluată și niciodată folosită nu este gratuită. Consumă lățime de bandă, capacitate de server, energie și posibil date ale utilizatorului. Pe rețele mobile, preluarea speculativă poate fi activ neprietenoasă.

Pentru multe site-uri, cea mai bună strategie de prefetch este bazată pe intenție. Nu face prefetch pentru pagina de pricing imediat ce se încarcă pagina principală. Fă prefetch când utilizatorul deschide meniul de pricing, trece cu cursorul peste linkul de pricing sau derulează aproape de un call-to-action care prezice puternic navigarea.

Amintește-ți și că comportamentul browserelor variază. Unele browsere sunt conservatoare cu prefetch; unele setări de confidențialitate reduc sau dezactivează încărcarea speculativă. Tratează prefetch ca pe o îmbunătățire oportunistă, nu ca pe un mecanism de corectitudine.

Preconnect: pentru conexiuni costisitoare către origini importante

preconnect îi spune browserului: „Începe acum inițializarea unei conexiuni către această origine.”

Asta poate include DNS lookup, conexiune TCP și negociere TLS. Pentru origini third-party, această inițializare poate dura sute de milisecunde, mai ales pe rețele cu latență ridicată. Dacă pagina are în curând nevoie de o cerere critică de la acea origine, preconnect poate face cererea ulterioară mai rapidă.

Exemplu:

<link rel='preconnect' href='https://fonts.gstatic.com' crossorigin>

Candidați buni pentru preconnect includ:

  • O origine de font folosită pentru text care blochează randarea.
  • O origine API critică necesară în timpul interacțiunii inițiale.
  • O origine CDN care servește asseturi deasupra pliului.
  • Un furnizor de plăți sau identitate necesar imediat după acțiunea utilizatorului.

Candidați slabi pentru preconnect includ:

  • Endpointuri de analytics și advertising care nu sunt critice pentru utilizator.
  • Origini folosite doar în unele sesiuni.
  • Liste lungi de terți.
  • Resurse same-origin, unde browserul are deja sau va deschide curând conexiunea.

Preconnect are un cost de menținere. Socketurile deschise consumă memorie și resurse de rețea. Browserele vor închide conexiunile nefolosite, dar asta nu face preconnect-urile inutile inofensive.

O regulă utilă: fă preconnect pentru cel mult una sau două origini third-party cu încredere ridicată pe o pagină. Dacă ești tentat să adaugi mai multe, arhitectura ta third-party are probabil nevoie de revizuire mai mult decât indiciile tale au nevoie de extindere.

DNS-prefetch: vărul mai ușor

Poți vedea și dns-prefetch:

<link rel='dns-prefetch' href='https://example-cdn.com'>

Acesta rezolvă doar numele de domeniu. Nu deschide o conexiune TCP sau TLS. Este mai ieftin decât preconnect, dar și mai puțin util.

DNS-prefetch poate fi rezonabil pentru origini third-party cu încredere mai scăzută, unde preconnect complet pare prea agresiv. În practică, dacă o origine este critică și va fi folosită cu siguranță în curând, preferă preconnect. Dacă este doar posibilă, folosește fie DNS-prefetch, fie nu face nimic.

Cum să decizi: un workflow practic

Începe cu măsurarea, nu cu tagurile.

1. Identifică blocajul

Deschide o trasare de performanță și caută descoperirea târzie. Cererea pentru font, imaginea hero sau script a pornit abia după ce un alt fișier a fost descărcat și parsat? Acesta este un candidat pentru preload.

Dacă o cerere pornește doar după o inițializare lungă DNS/TCP/TLS către o origine third-party, acesta este un candidat pentru preconnect.

Dacă pagina curentă este în regulă, dar navigarea următoare este previzibil lentă, prefetch poate ajuta.

2. Adaugă câte un indiciu pe rând

Indiciile pentru resurse interacționează. Adaugă unul, testează-l și păstrează-l doar dacă waterfall-ul se îmbunătățește și metricile vizibile pentru utilizator nu regresează.

Pentru preload, urmărește dacă resursa indicată este într-adevăr folosită curând. Chrome poate avertiza când o resursă preloaded nu este folosită la scurt timp după încărcare. Ia acel avertisment în serios.

3. Verifică efectele secundare asupra priorității

Un preload poate lua lățime de bandă de la CSS, JavaScript sau imagini care contează mai mult. Un preconnect poate ocupa un slot de conexiune. Un prefetch poate adăuga trafic de fundal.

Rezultatul corect nu este „fișierul indicat pornește mai devreme.” Rezultatul corect este „pagina devine semnificativ mai bună pentru utilizatori.” Uită-te la LCP, INP, CLS și la monitorizarea utilizatorilor reali acolo unde este posibil.

4. Verifică headerele și caching-ul

Indiciile pot fi trimise în HTML sau în headere HTTP Link. Headerele sunt utile când serverul știe devreme de ce va avea nevoie pagina, dar sunt mai greu de inspectat casual. Dacă depanezi dacă un indiciu este într-adevăr prezent în producție, headerele brute contează; aceasta este exact situația acoperită în ghidul nostru pentru depanarea redirecturilor și a headerelor HTTP.

Caching-ul contează și el. Preloading-ul unei resurse cu credențiale nepotrivite, as greșit sau parametri URL diferiți poate cauza descărcări duplicate. Aceasta este una dintre cele mai comune modalități prin care un preload bine intenționat devine un bug de performanță.

Greșeli comune

Preloading pentru prea multe lucruri

Dacă totul este critic, nimic nu este. Limitează preload la resursele necesare pentru randarea inițială sau interactivitatea imediată. O pagină tipică ar trebui să aibă de la zero la trei preload-uri, nu douăzeci.

Folosirea prefetch pentru resurse necesare

Prefetch este cu prioritate scăzută și opțional. Nu îl folosi pentru asseturi necesare paginii curente. Dacă pagina are nevoie de el acum, ia în calcul preload sau descoperirea normală prin HTML.

Preconnecting către fiecare terț

Paginile încărcate cu third-party au adesea zece sau mai multe origini externe. Preconnecting către toate creează zgomot. Alege una sau două care sunt atât critice, cât și folosite previzibil.

Uitarea condițiilor mobile

Indiciile pentru resurse sunt cele mai valoroase pe conexiuni mai lente, dar tot acolo sunt și cele mai periculoase. Un prefetch irosit pe o conexiune rapidă de desktop este o eroare de rotunjire. Pe un plan mobil constrâns, este un schimb prost.

Un tabel simplu de decizie

| Situație | Cel mai bun indiciu | De ce | |---|---:|---| | Font critic descoperit prin CSS | preload | Pagina curentă are nevoie de el, descoperirea este târzie | | Imagine hero ascunsă în spatele CSS sau randării pe client | preload | Poate îmbunătăți LCP dacă imaginea pornește târziu | | Rută următoare probabilă după intenția utilizatorului | prefetch | Ajută navigarea viitoare fără a bloca pagina curentă | | Origine third-party critică pentru font/API | preconnect | Elimină inițializarea conexiunii din calea critică | | Origine third-party posibilă, dar incertă | dns-prefetch sau nimic | Cost mai mic, încredere mai scăzută | | Imagine de sub pliul paginii | nimic | Lasă lazy loading și prioritatea browserului să funcționeze |

Regula calmă

Indiciile pentru resurse funcționează cel mai bine când sunt plictisitoare și specifice. Un font. O imagine LCP. O origine third-party importantă. O rută următoare probabilă după intenție.

Funcționează prost când sunt folosite ca optimism: poate utilizatorul va avea nevoie de asta, poate browserul ar trebui să preia aceea, poate mai multe indicii înseamnă mai multă viteză.

Browserele optimizează deja agresiv. Treaba ta nu este să microgestionezi fiecare cerere. Treaba ta este să corectezi puținele cazuri în care browserului îi lipsesc informațiile la momentul potrivit.

Întrebări frecvente

Ar trebui să fac preload pentru toate fonturile mele?
Nu. Fă preload doar pentru fișierele de font necesare textului vizibil devreme în pagină. Preloading-ul fiecărei greutăți și fiecărui stil irosește de obicei lățime de bandă și poate întârzia resurse mai importante.
Este sigur să folosesc prefetch pentru fiecare link intern?
De obicei, nu. Poate crea trafic de fundal inutil și poate irosi datele utilizatorului. Preferă prefetching-ul bazat pe intenție, cum ar fi după hover, focus, deschiderea unui meniu sau un pas următor previzibil.
Care este diferența dintre preconnect și dns-prefetch?
Preconnect efectuează inițializarea DNS, TCP și TLS pentru o origine. DNS-prefetch rezolvă doar numele de domeniu. Preconnect este mai puternic, dar mai costisitor, așa că trebuie folosit cu mai multă încredere.
Pot indiciile pentru resurse să îmbunătățească Core Web Vitals?
Da, mai ales LCP, atunci când repară descoperirea târzie sau inițializarea conexiunii pentru o resursă critică. Nu vor ajuta dacă problema reală este reprezentată de asseturi supradimensionate, răspuns lent al serverului, cod care blochează randarea sau caching slab.
Ar trebui adăugate indiciile pentru resurse în HTML sau în headere HTTP?
Ambele pot funcționa. HTML este mai ușor de înțeles pentru indicii specifice paginii. Headerele HTTP Link pot fi utile când serverul știe resursele critice înainte ca HTML-ul să fie parsat, dar necesită testare atentă pentru a evita duplicatele sau indiciile învechite.

Surse și lecturi suplimentare

  1. MDN: rel=preload
  2. MDN: Resource hints
  3. web.dev: Preconnect and DNS-prefetch
  4. W3C: Resource Hints
Despre autor
The Wux Webtools Team

Ultima actualizare:

Continuă să citești