Zašto vaš sajt treba da šalje manje zahteva, a ne samo manje fajlove
Sitni fajlovi nisu besplatni. Moderni HTTP je smanjio trošak zahteva, nije ga učinio nevažnim.
Sadržaj
- Udoban mit o tome da „samo treba smanjiti svaki fajl”
- Zahtevi nisu samo bajtovi
- „Ali HTTP/2 je to rešio” — uglavnom nije
- Waterfall je mesto gde živi istina
- Manji fajlovi su i dalje važni — samo ne podjednako
- Skriveni troškovi mnogih malih fajlova
- 1. Kasno otkrivanje
- 2. Trošak headera
- 3. Prekidanje glavne niti
- 4. Složenost keša
- Bundling se vratio, ali uz rasuđivanje
- Third-party zahtevi zaslužuju dodatnu sumnju
- Praktična checklist-a za smanjenje zahteva
- Uklonite
- Kombinujte promišljeno
- Odložite
- Keširajte pravilno
- Izmerite ponovo
- Kako izgleda dobro
Udoban mit o tome da „samo treba smanjiti svaki fajl”
Godinama je savet za web performanse zvučao jednostavno: kompresujte sve, minifikujte sve, smanjite svaki asset.
Taj savet je i dalje uglavnom tačan. Skripta od 40 KB obično je bolja od skripte od 400 KB. Optimizovana slika je bolja od sirovog izvoza. Brotli, AVIF, CSS minifikacija, tree shaking i font subsetting — sve je to važno.
Ali na mnogim produkcionim sajtovima veći problem više nije jedan prevelik fajl. Problem je broj stvari koje browser mora da zatraži pre nego što stranica počne da deluje upotrebljivo.
Stranica može izgledati disciplinovano po veličinama fajlova, a ipak biti spora jer šalje 120 zahteva: CSS fragmente, JavaScript chunkove, third-party tagove, font fajlove, piksele za praćenje, icon spriteove, JSON endpoint-e, preloadove, analytics beacon-e i revalidacije keša. Svaki od njih može biti „mali”. Zajedno stvaraju dug, krhak waterfall.
Praktično pravilo je ovo: kada su pojedinačni asseti razumno kompresovani, smanjenje broja zahteva često poboljšava korisničko iskustvo više nego skidanje nekoliko kilobajta sa svakog fajla.
Zahtevi nisu samo bajtovi
Mrežni zahtev nije samo prenos podataka. To je niz poslova.
Browser mora da otkrije resurs, odluči kada da ga preuzme, rasporedi ga u odnosu na druge resurse, pošalje headere, sačeka server, primi headere, parsira odgovor, često ga dekompresuje, a zatim uradi nešto korisno s njim.
To „nešto korisno” može biti skupo. JavaScript fajl mora da se parsira, kompajlira i izvrši. CSS fajl može da blokira renderovanje. Font fajl može da odloži čitljiv tekst ili izazove pomeranja layouta. Slika može da utiče na Largest Contentful Paint element. Third-party skripta može da donese sopstveni lanac zavisnosti.
Zato je broj zahteva i dalje važan, čak i kada su fajlovi mali. Skripta od 3 KB može biti gora od slike od 30 KB ako blokira renderovanje, stiže kasno i izvršava se na glavnoj niti u pogrešnom trenutku.
Ako čitate Lighthouse izveštaj i imate osećaj da vas kažnjava desetinama odvojenih upozorenja, počnite od request waterfall-a, a ne od pojedinačnih ocena. Imamo praktičan vodič u tekstu kako čitati Lighthouse izveštaj bez panike, ali kratka verzija glasi: pronađite šta blokira prvo renderovanje i šta odlaže glavni sadržaj.
„Ali HTTP/2 je to rešio” — uglavnom nije
HTTP/2 i HTTP/3 promenili su ekonomiku zahteva. Uveli su multiplexing, kompresiju headera i bolje ponašanje konekcija. Jednostavno rečeno, browseri su postali mnogo bolji u slanju više zahteva preko manjeg broja konekcija.
To je bilo pravo poboljšanje. Takođe je ugasilo neke stare navike, kao što su ekstremni CSS spriteovi i ogromni spojeni bundleovi pravljeni samo da bi se izbegla ograničenja konekcija.
Ali HTTP/2 nije učinio zahteve besplatnim.
Multiplexing pomaže kada mnogi resursi dele konekciju, ali browser i dalje mora da im odredi prioritete. Serveri i dalje moraju da odgovore. Klijent i dalje mora da obradi svaki odgovor. Zagušenje, gubitak paketa, TLS pregovaranje, DNS lookup, promašaji keša i pritisak na glavnu nit i dalje postoje.
HTTP/3 poboljšava deo transportnog ponašanja, posebno oko migracije konekcije i head-of-line blocking-a na transportnom sloju. Ne uklanja cenu otkrivanja, raspoređivanja, preuzimanja, parsiranja i izvršavanja resursa.
Zato moderni cilj nije „spakovati sve u jedan ogroman fajl”. Cilj je „poslati manje kritičnih zahteva i učiniti preostale zahteve namernim”.
Waterfall je mesto gde živi istina
Problemi s performansama retko se najave jednom metrikom. Pojavljuju se kao oblik.
Otvorite network panel u browseru i pogledajte prvih nekoliko sekundi. Pitajte:
- Koliko zahteva počinje pre nego što se pojavi glavni sadržaj?
- Koji zahtevi blokiraju renderovanje?
- Da li se važni resursi otkrivaju kasno?
- Da li se third-party skripte takmiče sa first-party CSS-om, fontovima ili slikama?
- Da li mnogi fajlovi vraćaju 304 odgovore umesto da se serviraju direktno iz keša?
- Da li su ikone, fontovi ili UI fragmenti podeljeni u više fajlova nego što je stranici potrebno?
Brza stranica obično ima dosadan rani waterfall. Mali broj kritičnih resursa stiže rano. Nekritični resursi čekaju. Third-party skripte su odložene, ograničene ili uklonjene. Browser nije primoran da žonglira sa dvadeset prioriteta pre nego što može da iscrta stranicu.
Spora stranica često ima nervozan waterfall: mnogo malih fajlova, mnogo origin-a i mnogo kasnih otkrića.
Manji fajlovi su i dalje važni — samo ne podjednako
Ovo nije argument protiv kompresije ili optimizacije. Ovo je argument protiv optimizacije bajtova uz ignorisanje koordinacije.
Manji fajlovi su najvažniji kada je resurs veliki, kada blokira renderovanje ili kada je deo glavne putanje sadržaja. Na primer:
- Hero slika treba da bude pravilno dimenzionisana i enkodovana.
- CSS koji blokira renderovanje treba da bude lean.
- JavaScript potreban za prvu interakciju treba da bude minimalan.
- Fontovi treba da budu subsetovani, kompresovani i ograničeni na težine koje se zaista koriste.
Fontovi su čest primer. Timovi se često opsedaju time da li je font fajl 24 KB ili 31 KB, dok isporučuju šest težina, dva stila i više porodica. Bolje rešenje nije skidanje 7 KB sa jednog fajla. Bolje rešenje je slanje manjeg broja font fajlova. Ako je tipografija deo vašeg rada na performansama, web fontovi su i dalje jedna od najlakših pobeda na većini sajtova.
Slike prate isti obrazac. AVIF ili WebP mogu značajno da uštede bajtove, ali slanje deset dekorativnih slika iznad preloma i dalje je loš plan. Birajte bolje formate, da, ali se i zapitajte da li svaka slika uopšte mora da bude zatražena. Za odluke o formatima, naš vodič o tome kada AVIF nadmašuje WebP, a kada ne koristan je pratilac ovom radu na broju zahteva.
Skriveni troškovi mnogih malih fajlova
Mnogo malih zahteva obično stvara probleme koji se ne vide ako gledate samo ukupno prenete bajtove.
1. Kasno otkrivanje
Browseri ne mogu da zatraže ono što nisu otkrili. CSS fajl može da referencira font. Skripta može da importuje drugu skriptu. Komponenta može da zatraži JSON posle hydration-a. Svaka zavisnost pravi još jedan korak u lancu.
Što je lanac dublji, to važan posao počinje kasnije.
2. Trošak headera
Svaki zahtev i odgovor uključuje headere. Kompresija headera pomaže, posebno preko HTTP/2 i HTTP/3, ali ne eliminiše trošak. Cookieji mogu ovo mnogo da pogoršaju. Ako vaš sajt šalje velike cookieje uz svaki zahtev, sitni asseti u praksi postaju manje sitni.
To je jedan od razloga zašto statički asseti često treba da žive na putanjama ili domenima bez cookieja, i zašto cache headeri zaslužuju pažnju. Ako se headeri čudno ponašaju u produkciji, debugging redirecta i HTTP headera obično je brži od nagađanja.
3. Prekidanje glavne niti
Mnogo JavaScript chunkova može da stvori ponavljani posao parsiranja i izvršavanja. Čak i ako je svaki chunk mali, browser može stalno da zastaje da bi evaluirao kod. To može da naškodi Interaction to Next Paint-u i učini da stranica deluje trzavo.
Korisnika ne zanima što je svaki fajl bio mali. Zanima ga što je dodir na meni trajao 600 milisekundi.
4. Složenost keša
Podela asseta može poboljšati keširanje kada se uradi pažljivo. Stabilan vendor bundle i promenljiv app bundle mogu biti dobra podela.
Ali preterano chunkovanje može da se obije o glavu. Više fajlova znači više cache lookup-a, više prilika za revalidaciju, više koordinacije verzija i više načina da se slučajno invalidiraju resursi koji nisu morali da se menjaju.
Bundling se vratio, ali uz rasuđivanje
Prva era web performansi volela je bundling zato što su browseri imali stroga ograničenja konekcija. Onda je stigao HTTP/2 i mnogi timovi su snažno krenuli ka agresivnom code splitting-u. Nešto od toga je bilo korisno. Nešto je postalo sujeverje.
Razumna sredina je bundling svestan ruta.
Za tipičan marketinški sajt ili content sajt:
- Inline-ujte ili učitajte samo CSS potreban za početno renderovanje.
- Neka globalni JavaScript bude mali.
- Izbegavajte cepanje sitnih modula u odvojene mrežne zahteve.
- Odložite interaktivne funkcije koje nisu odmah potrebne.
- Uklonite third-party skripte koje ne opravdavaju svoj trošak.
Za aplikaciju:
- Delite po ruti ili velikoj funkcionalnosti, ne po svakoj komponenti.
- Neka deljene zavisnosti budu stabilne i kešabilne.
- Preload-ujte samo resurse koji će sigurno uskoro biti potrebni.
- Izbegavajte učitavanje admin, dashboard, editor ili experiment koda na javnim stranicama.
- Merite cenu interakcije, ne samo veličinu bundlea.
Bundling nije automatski dobar. Code splitting nije automatski dobar. Korisno pitanje glasi: da li ova podela pomaže browseru da ranije isporuči sledeće smisleno korisničko iskustvo?
Third-party zahtevi zaslužuju dodatnu sumnju
First-party zahtevi su barem pod vašom kontrolom. Third-party zahtevi su često sporiji, manje predvidivi i skuplji nego što izgledaju.
Jedan tag manager može pokrenuti analytics, oglase, heatmap-e, chat widgete, A/B testing, alate za pristanak i skripte za personalizaciju. Svaki vendor može doneti još zahteva. Neki će se izvršavati rano. Neki će blokirati glavnu nit. Neki će se menjati bez vašeg release procesa.
Najbolja optimizacija third-party koda je brisanje. Druga najbolja je odlaganje.
Pre dodavanja third-party skripte, pitajte:
- Da li ovo mora da se učita pre nego što korisnik vidi stranicu?
- Da li mora da se učita na svakoj stranici?
- Može li da se učita posle pristanka, interakcije ili idle vremena?
- Ko je interno vlasnik toga?
- Koja metrika dokazuje da vredi performansnog troška?
Ovde performanse postaju governance. Neko mora imati dozvolu da kaže ne.
Praktična checklist-a za smanjenje zahteva
Počnite od stranica koje su najvažnije: homepage, pricing page, product page, checkout, signup ili najvažnije landing stranice. Zatim prođite kroz waterfall.
Uklonite
- Obrišite neiskorišćeni JavaScript i CSS.
- Uklonite stare eksperimente, napuštene piksele i dupliranu analitiku.
- Izbacite neiskorišćene težine fontova i biblioteke ikona.
- Zamenite dekorativne slike CSS-om gde je prikladno.
Kombinujte promišljeno
- Bundle-ujte sitne JavaScript module koji se uvek učitavaju zajedno.
- Spojite male CSS fajlove koji blokiraju istu putanju renderovanja.
- Koristite SVG spriteove ili inline SVG za ponovljene ikone kada to smanjuje zahteve bez štete po održivost.
Odložite
- Lazy-load-ujte slike ispod preloma.
- Odložite nekritične skripte do posle prvog iscrtavanja ili korisničke interakcije.
- Učitavajte komentare, embedove, mape, chat i video playere samo kada su potrebni.
Keširajte pravilno
- Koristite dugotrajno keširanje za verzionisane statičke assete.
- Izbegavajte nepotrebnu revalidaciju fajlova koji se retko menjaju.
- Neka HTML ostane svež, ali dozvolite hashed assetima da ostanu keširani.
Izmerite ponovo
Posle svake promene ponovo proverite waterfall. Cilj nije savršena ocena. Cilj je manje kritičnih zahteva, ranije korisno renderovanje i manje ometanja glavne niti.
Kako izgleda dobro
Zdrava stranica ne mora nužno da ima najmanji mogući broj zahteva. Ona ima malu, namernu kritičnu putanju.
Browser dobija HTML, ključni CSS, glavnu sliku sadržaja ako postoji, možda malu skriptu potrebnu za navigaciju ili interakciju iznad preloma, i minimalni skup fontova potreban da tekst bude čitljiv. Sve ostalo čeka svoj red.
To je razlika između stranice koja je samo optimizovana i stranice koja deluje brzo.
Smanjivanje fajlova i dalje vredi raditi. Ali ako je sajt već razumno kompresovan, sledeća performansna pobeda obično nije još 2 KB ušteđena iz bundlea. To je jedan blokirajući zahtev manje, jedan font fajl manje, jedna third-party skripta manje, jedan lanac zavisnosti manje.
Manje zahteva čini posao browsera jednostavnijim. Jednostavno je brzo češće nego što volimo da priznamo.