Kas iš tiesų yra preload ir prefetch?
Kai pirmą kartą susiduri su šiomis direktyvomis, gali atrodyti, kad tai dar vienas iš tų „optimizavimo triukų”, kuriuos visi mini, bet niekas iš tiesų nesupranta. Tiesą sakant, preload ir prefetch yra gana paprastos koncepcijos, tik dažnai klaidingai suprantamos ir neteisingai taikomos.
Preload direktyva nurodo naršyklei, kad tam tikras resursas bus reikalingas labai greitai – praktiškai dabar. Tai tarsi sakytum: „Ei, naršykle, matau, kad tu dar neskenuoji viso HTML, bet aš jau žinau, kad mums reikės šio šrifto/CSS/JS failo, tai pradėk jį krauti dabar, nelauk.”
Prefetch veikia visiškai kitaip. Tai optimizavimas ateičiai. Sakote naršyklei: „Kai turėsi laisvo pralaidumo, užkrauk šitą resursą – jis galbūt prireiks kitame puslapyje ar vėliau.” Naršyklė čia elgiasi kaip protingas asistentas – jei turi laiko ir resursų, padarys, jei ne – praleist.
Kada preload išgelbsti situaciją
Pirmiausia, preload puikiai tinka šriftams. Jei naudojate custom šriftus, tikrai pastebėjote tą bjaurų FOUT (Flash of Unstyled Text) efektą, kai tekstas pirmiausia pasirodo su sisteminiu šriftu, o paskui šokteli į jūsų dizainerio parinktą. Štai kaip tai sprendžiama:
<link rel="preload" href="/fonts/opensans-regular.woff2" as="font" type="font/woff2" crossorigin>
Atkreipkite dėmesį į crossorigin atributą – jis būtinas šriftams, net jei jie yra jūsų domene. Tai viena iš tų keistų naršyklių taisyklių, kurią tiesiog reikia prisiminti.
Kitas klasikinis preload naudojimo atvejis – kritiniai CSS failai. Tarkime, turite „above-the-fold” stilius atskirame faile, kuris tikrai bus reikalingas iš karto. Bet yra viena problema – jei tiesiog įdėsite preload visam CSS, galite sugadinti renderinimo procesą. Naršyklės yra optimizuotos krauti CSS natūralia tvarka, todėl preload naudokite tik tada, kai tikrai žinote ką darote.
Pavyzdžiui, jei turite hero sekcijos background paveikslėlį, kurį naršyklė aptiks tik po to, kai išparsins CSS:
<link rel="preload" href="/images/hero-background.jpg" as="image">
Čia svarbu suprasti – preload nepakeičia normalaus resurso užkrovimo, jis tik paspartina. Jums vis tiek reikės normalaus img tago ar CSS background-image. Preload tiesiog leidžia naršyklei pradėti krauti anksčiau.
Prefetch strategijos realiame pasaulyje
Prefetch yra daug įdomesnis ir lankstesnis įrankis, bet jį naudoti reikia su galva. Klasikinis pavyzdys – e-commerce svetainėje, kai vartotojas žiūri į produkto sąrašą, galite prefetch’inti populiariausių produktų detaliųjų puslapių resursus.
<link rel="prefetch" href="/product/bestseller-123.html">
<link rel="prefetch" href="/js/product-gallery.js">
Bet čia slypi spąstai. Jei prefetch’insite per daug, galite:
- Išeikvoti vartotojo duomenų planą (ypač mobiliuose)
- Užkrauti serverį nereikalingais užklausimais
- Sulėtinti dabartinio puslapio veikimą
Geras praktinis patarimas – naudokite analytics duomenis. Jei matote, kad 70% vartotojų iš pagrindinio puslapio eina į „/products”, tai puikus kandidatas prefetch’ui. Bet jei tik 5% eina į „/about-us”, tai tiesiog švaistymas.
Dar vienas įdomus naudojimo būdas – prefetch’inti kito žingsnio resursus multi-step formuose. Pavyzdžiui, registracijos procese, kai vartotojas užpildo pirmą žingsnį, galite prefetch’inti antro žingsnio JavaScript ir CSS.
Techniniai niuansai, kuriuos reikia žinoti
Vienas dalykas, kuris dažnai suklaidina – preload turi prioritetus. Naršyklė ne visada kraus preload resursus pačiu aukščiausiu prioritetu. Tai priklauso nuo „as” atributo. Pavyzdžiui:
<link rel="preload" href="style.css" as="style"> – aukštas prioritetas
<link rel="preload" href="image.jpg" as="image"> – žemas prioritetas
Jei neįdėsite „as” atributo, naršyklė užkraus resursą su labai žemu prioritetu, ir jūsų optimizavimas bus bevertis. Tai ne optional atributas – jis būtinas.
Dar viena svarbi detalė – preload resursai turi būti panaudoti per 3 sekundes, kitaip Chrome DevTools console’ėje pamatysite warning’ą. Tai ne tik kosmetinė problema – tai reiškia, kad tikriausiai naudojate preload neteisingai.
Prefetch atveju, resursai saugomi HTTP cache’e, bet ne visuose naršyklių cache’uose. Kai kurios naršyklės turi atskirą prefetch cache, kuris išvalomas greičiau nei normalus cache. Tai reiškia, kad prefetch’intas resursas gali būti „išmestas” jei vartotojas per ilgai neperėjo į kitą puslapį.
JavaScript ir dinaminis resource hints valdymas
Ne visada galite žinoti iš anksto, ką reikia preload’inti ar prefetch’inti. Kartais tai priklauso nuo vartotojo elgsenos ar aplikacijos būsenos. Čia į pagalbą ateina JavaScript:
const link = document.createElement('link');
link.rel = 'prefetch';
link.href = '/next-page-data.json';
document.head.appendChild(link);
Tai ypač naudinga SPA (Single Page Applications) aplikacijose. Pavyzdžiui, React aplikacijoje galite prefetch’inti route’o komponentą, kai vartotojas užveda pelę ant navigacijos nuorodos:
function NavigationLink({ to, children }) {
const handleMouseEnter = () => {
const link = document.createElement('link');
link.rel = 'prefetch';
link.href = to;
document.head.appendChild(link);
};
return <a href={to} onMouseEnter={handleMouseEnter}>{children}</a>;
}
Šis metodas vadinamas „intent-based prefetching” – prefetch’inate pagal vartotojo ketinimus, ne tik statistiką. Jei vartotojas užvedė pelę ant nuorodos, yra didelė tikimybė, kad jis ją paspaus.
Bet būkite atsargūs su mobile įrenginiais – ten nėra hover būsenos, todėl reikia kitokių strategijų. Galite naudoti Intersection Observer API, kad prefetch’intumėte resursus, kai jie pasirodo viewport’e.
Webpack, Vite ir kiti build tools
Šiuolaikiniai build tools jau turi įmontuotą palaikymą preload ir prefetch direktyvoms. Webpack, pavyzdžiui, leidžia naudoti magic comments:
import(/* webpackPrefetch: true */ './components/Modal.js');
Tai automatiškai sugeneruos prefetch link tagą jūsų HTML’e. Vite turi panašią funkciją, bet ji veikia šiek tiek kitaip – Vite automatiškai analizuoja jūsų import’us ir generuoja preload direktyvas kritiniams resursams.
Problema su automatiniais sprendimais – jie ne visada žino, kas jūsų aplikacijoje yra tikrai kritinis. Webpack gali nuspręsti preload’inti visus chunk’us, nors jums reikia tik vieno. Todėl visada patikrinkite, ką generuoja jūsų build tool’as.
Next.js turi savo požiūrį – jis automatiškai prefetch’ina visas Link komponentų nuorodas, kai jos pasirodo viewport’e. Tai patogu, bet gali būti per agresyvu dideliems projektams. Galite tai išjungti:
<Link href="/about" prefetch={false}>About</Link>
Performance monitoring ir debugging
Kaip žinoti, ar jūsų preload/prefetch strategija veikia? Chrome DevTools yra jūsų geriausias draugas. Network tab’e galite matyti, kada resursai pradedami krauti ir kokiu prioritetu.
Ieškokite eilutės „Priority” stulpelyje – jei preload resursas turi „Low” prioritetą, kažkas ne taip. Tikriausiai trūksta „as” atributo arba naršyklė nusprendė, kad resursas nėra toks svarbus.
Lighthouse auditas taip pat padeda. Jis įspės, jei:
- Preload’inate per daug resursų
- Preload’intas resursas nėra panaudojamas
- Trūksta preload kritiniams resursams
Bet Lighthouse nėra visagalis – jis negali žinoti jūsų aplikacijos specifikos. Jei jūsų aplikacija dinamiškai kraunasi resursus pagal vartotojo veiksmus, Lighthouse gali duoti false positive warnings.
Real User Monitoring (RUM) duomenys yra daug vertingesni. Žiūrėkite į metrikas kaip First Contentful Paint (FCP) ir Largest Contentful Paint (LCP) prieš ir po preload/prefetch įdiegimo. Jei nematote pagerėjimo arba net matote pablogėjimą, kažkas ne taip.
Vienas dažnas klausimas – ar preload/prefetch veikia su Service Workers? Atsakymas – taip, bet su niuansais. Service Worker gali interceptinti preload/prefetch užklausas ir patarnauti resursus iš cache’o. Bet jei jūsų Service Worker logika yra sudėtinga, galite gauti netikėtų rezultatų.
Kai viskas subėga į vieną vietą
Preload ir prefetch nėra magiškas sprendimas visiems performance problemoms. Tai įrankiai, kurie veikia tik tada, kai žinote, ką darote ir kodėl. Pradėkite nuo analytics – išsiaiškinkite, kokie resursai yra kritiniai, kokie dažniausiai naudojami, kokia vartotojų kelionė jūsų aplikacijoje.
Pirmiausia optimizuokite tai, kas tikrai lėtina jūsų puslapį. Galbūt problema ne tame, kad resursai per vėlai kraunasi, o tame, kad jų per daug arba jie per dideli. Preload nepadės, jei jūsų JavaScript bundle’as sveria 5MB.
Kai jau turite solidų pagrindą, pradėkite eksperimentuoti su preload kritiniams resursams – šriftams, hero paveikslėliams, kritiniam CSS. Matuokite rezultatus. Jei matote pagerėjimą LCP metrikoje 200-300ms, judėkite toliau.
Prefetch naudokite atsargiai ir strategiškai. Geriau prefetch’inti vieną tikrai reikalingą resursą nei dešimt „gal prireiks”. Mobilieji vartotojai jums padėkos už sutaupytus megabaitus.
Ir paskutinis patarimas – dokumentuokite savo sprendimus. Po pusmečio, kai grįšite prie kodo, norėsite žinoti, kodėl preload’inate būtent šį failą, o ne kitą. Komentaras kode ar README failas gali sutaupyti daug laiko ir nervų.

