Proč by váš web měl posílat méně požadavků, ne jen menší soubory
Drobné soubory nejsou zadarmo. Moderní HTTP režii požadavků snížilo, ne odstranilo.
Obsah
- Pohodlný mýtus „prostě zmenšete každý soubor“
- Požadavky nejsou jen bajty
- „Ale HTTP/2 to vyřešilo“ — většinou ne
- Pravda žije ve vodopádu
- Menší soubory mají stále smysl — jen ne stejně
- Skryté náklady mnoha malých souborů
- 1. Pozdní objevení
- 2. Režie hlaviček
- 3. Přerušování hlavního vlákna
- 4. Složitost cache
- Bundlování je zpět, ale s rozvahou
- Požadavky třetích stran si zaslouží zvláštní podezření
- Praktický checklist pro snížení počtu požadavků
- Odstraňte
- Promyšleně spojte
- Odložte
- Cachujte správně
- Znovu změřte
- Jak vypadá dobrý stav
Pohodlný mýtus „prostě zmenšete každý soubor“
Po léta zněla doporučení pro výkon webu jednoduše: všechno komprimovat, všechno minifikovat, každý asset zmenšit.
Tato rada je stále obecně správná. Skript o velikosti 40 KB je obvykle lepší než skript o velikosti 400 KB. Optimalizovaný obrázek je lepší než surový export. Brotli, AVIF, minifikace CSS, tree shaking i subsetting fontů mají smysl.
Na mnoha produkčních webech už ale větší problém nepředstavuje jeden přerostlý soubor. Je jím počet věcí, o které musí prohlížeč požádat, než stránka začne působit použitelně.
Stránka může vypadat disciplinovaně co do velikostí souborů, a přesto být pomalá, protože posílá 120 požadavků: fragmenty CSS, chunky JavaScriptu, tagy třetích stran, soubory fontů, tracking pixely, sprity ikon, JSON endpointy, preloady, analytické beacony a revalidace cache. Každý z nich může být „malý“. Dohromady vytvářejí dlouhý, křehký vodopád.
Praktické pravidlo zní takto: jakmile jsou jednotlivé assety rozumně komprimované, snížení počtu požadavků často zlepší uživatelský zážitek víc než osekání několika kilobajtů z každého souboru.
Požadavky nejsou jen bajty
Síťový požadavek není jen přenos dat. Je to posloupnost práce.
Prohlížeč musí zdroj objevit, rozhodnout, kdy ho stáhnout, naplánovat ho vůči ostatním zdrojům, odeslat hlavičky, počkat na server, přijmout hlavičky, zpracovat odpověď, často ji dekomprimovat a pak s ní udělat něco užitečného.
To „něco užitečného“ může být nákladné. Soubor JavaScriptu se musí naparsovat, zkompilovat a spustit. Soubor CSS může blokovat vykreslování. Soubor fontu může oddálit čitelný text nebo způsobit posuny rozvržení. Obrázek může ovlivnit prvek Largest Contentful Paint. Skript třetí strany si může přinést vlastní řetězec závislostí.
Proto na počtu požadavků stále záleží, i když jsou soubory malé. Skript o velikosti 3 KB může být horší než obrázek o velikosti 30 KB, pokud blokuje vykreslování, dorazí pozdě a spustí se na hlavním vlákně ve špatný okamžik.
Pokud čtete report Lighthouse a máte pocit, že vás trestá desítkami samostatných varování, začněte pohledem na vodopád požadavků, ne na jednotlivá skóre. Praktický postup máme v článku, jak číst report Lighthouse bez paniky, ale krátká verze zní: najděte, co blokuje první vykreslení a co zdržuje hlavní obsah.
„Ale HTTP/2 to vyřešilo“ — většinou ne
HTTP/2 a HTTP/3 změnily ekonomiku požadavků. Přinesly multiplexing, kompresi hlaviček a lepší chování spojení. Jednoduše řečeno, prohlížeče začaly mnohem lépe posílat více požadavků přes méně spojení.
Bylo to skutečné zlepšení. Zároveň to ukončilo některé staré zvyky, například extrémní CSS sprity a obří spojované bundly vytvářené jen kvůli obcházení limitů spojení.
HTTP/2 ale z požadavků neudělalo něco bez nákladů.
Multiplexing pomáhá, když mnoho zdrojů sdílí jedno spojení, ale prohlížeč je stále musí prioritizovat. Servery stále musí odpovídat. Klient stále musí zpracovat každou odpověď. Zahlcení, ztráty paketů, vyjednávání TLS, DNS lookup, cache missy i tlak na hlavní vlákno stále existují.
HTTP/3 zlepšuje některé vlastnosti transportu, zejména migraci spojení a head-of-line blocking na transportní vrstvě. Neodstraňuje náklady na objevování, plánování, stahování, parsování a spouštění zdrojů.
Moderním cílem tedy není „zabalit všechno do jednoho obrovského souboru“. Je jím „posílat méně kritických požadavků a z těch zbývajících udělat záměrné požadavky“.
Pravda žije ve vodopádu
Výkonnostní problémy se málokdy ohlásí jedinou metrikou. Projevují se tvarem.
Otevřete v prohlížeči panel sítě a podívejte se na prvních pár sekund. Ptejte se:
- Kolik požadavků začne předtím, než se objeví hlavní obsah?
- Které požadavky blokují vykreslování?
- Jsou důležité zdroje objevené pozdě?
- Soutěží skripty třetích stran s vaším CSS, fonty nebo obrázky?
- Vrací mnoho souborů odpovědi 304 místo toho, aby byly obslouženy přímo z cache?
- Jsou ikony, fonty nebo fragmenty UI rozdělené do více souborů, než stránka potřebuje?
Rychlá stránka má obvykle nudný raný vodopád. Malý počet kritických zdrojů dorazí brzy. Nekritické zdroje počkají. Skripty třetích stran jsou odložené, omezené nebo odstraněné. Prohlížeč není nucen žonglovat s dvaceti prioritami, než stránku vykreslí.
Pomalá stránka má často nervózní vodopád: mnoho malých souborů, mnoho originů a mnoho pozdních objevů.
Menší soubory mají stále smysl — jen ne stejně
Toto není argument proti kompresi nebo optimalizaci. Je to argument proti optimalizaci bajtů při ignorování koordinace.
Menší soubory mají největší význam, když je zdroj velký, blokuje vykreslování nebo je součástí cesty k hlavnímu obsahu. Například:
- Hero obrázek by měl mít správnou velikost a kódování.
- CSS blokující vykreslování by mělo být úsporné.
- JavaScript potřebný pro první interakci by měl být minimální.
- Fonty by měly být subsetované, komprimované a omezené na řezy, které se skutečně používají.
Fonty jsou častý příklad. Týmy často posedle řeší, zda má soubor fontu 24 KB nebo 31 KB, zatímco posílají šest řezů, dva styly a několik rodin. Lepší oprava není ušetřit 7 KB z jednoho souboru. Je to poslat méně souborů fontů. Pokud je typografie součástí vaší výkonnostní práce, webové fonty jsou na většině webů stále jedním z nejsnazších vítězství.
U obrázků platí stejný vzorec. AVIF nebo WebP mohou ušetřit významné množství bajtů, ale poslat deset dekorativních obrázků nad zlomem stránky je pořád špatný plán. Volte lepší formáty, ano, ale zároveň se ptejte, jestli je vůbec potřeba každý obrázek vyžadovat. Pro rozhodování o formátech je užitečným doplňkem k práci s počtem požadavků náš průvodce kdy AVIF překoná WebP a kdy ne.
Skryté náklady mnoha malých souborů
Mnoho malých požadavků má tendenci vytvářet problémy, které se neukážou, pokud sledujete jen celkový počet přenesených bajtů.
1. Pozdní objevení
Prohlížeče nemohou požádat o něco, co ještě neobjevily. Soubor CSS může odkazovat na font. Skript může importovat jiný skript. Komponenta může po hydrataci požádat o JSON. Každá závislost vytváří další krok v řetězci.
Čím hlubší řetězec, tím později začne důležitá práce.
2. Režie hlaviček
Každý požadavek a odpověď obsahují hlavičky. Komprese hlaviček pomáhá, zejména přes HTTP/2 a HTTP/3, ale režii neodstraňuje. Cookies to mohou výrazně zhoršit. Pokud váš web posílá velké cookies s každým požadavkem, drobné assety v praxi tak drobné nejsou.
To je jeden z důvodů, proč by statické assety často měly žít na cestách nebo doménách bez cookies, a proč si cache hlavičky zaslouží pozornost. Pokud se hlavičky v produkci chovají zvláštně, debugování přesměrování a HTTP hlaviček je obvykle rychlejší než hádání.
3. Přerušování hlavního vlákna
Mnoho chunků JavaScriptu může vytvářet opakovanou práci s parsováním a spouštěním. I když je každý chunk malý, prohlížeč se může stále zastavovat, aby vyhodnotil kód. To může poškodit Interaction to Next Paint a způsobit, že stránka působí trhaně.
Uživatele nezajímá, že každý soubor byl malý. Zajímá ho, že klepnutí na menu trvalo 600 milisekund.
4. Složitost cache
Rozdělování assetů může při pečlivém provedení zlepšit cachování. Stabilní vendor bundle a měnící se app bundle mohou být dobré rozdělení.
Přehnané chunkování se ale může obrátit proti vám. Více souborů znamená více lookupů v cache, více příležitostí k revalidaci, více koordinace verzí a více způsobů, jak omylem invalidovat zdroje, které se měnit nemusely.
Bundlování je zpět, ale s rozvahou
První éra webového výkonu milovala bundlování, protože prohlížeče měly přísné limity spojení. Pak přišlo HTTP/2 a mnoho týmů se prudce přiklonilo k agresivnímu code splittingu. Něco z toho bylo užitečné. Něco se stalo pověrou.
Rozumným středem je bundlování podle tras.
Pro typický marketingový nebo obsahový web:
- Inlinujte nebo načítejte jen CSS potřebné pro počáteční vykreslení.
- Udržujte globální JavaScript malý.
- Nerozdělujte drobné moduly do samostatných síťových požadavků.
- Odložte interaktivní prvky, které nejsou potřeba okamžitě.
- Odstraňte skripty třetích stran, které neospravedlňují své náklady.
Pro aplikaci:
- Dělte podle trasy nebo hlavní funkce, ne podle každé komponenty.
- Udržujte sdílené závislosti stabilní a cacheovatelné.
- Preloadujte jen zdroje, které budou brzy určitě potřeba.
- Nenačítejte kód pro administraci, dashboard, editor nebo experimenty na veřejných stránkách.
- Měřte náklady na interakci, ne jen velikost bundlu.
Bundlování není automaticky dobré. Code splitting není automaticky dobrý. Užitečná otázka zní: pomůže toto rozdělení prohlížeči doručit další smysluplný uživatelský zážitek dříve?
Požadavky třetích stran si zaslouží zvláštní podezření
Požadavky první strany máte alespoň pod kontrolou. Požadavky třetích stran jsou často pomalejší, méně předvídatelné a dražší, než vypadají.
Jediný tag manager může spustit analytiku, reklamy, heatmapy, chat widgety, A/B testing, nástroje pro souhlas a personalizační skripty. Každý dodavatel může přinést další požadavky. Některé poběží brzy. Některé zablokují hlavní vlákno. Některé se změní mimo váš release proces.
Nejlepší optimalizace třetích stran je smazání. Druhá nejlepší je odložení.
Než přidáte skript třetí strany, zeptejte se:
- Musí se načíst předtím, než uživatel uvidí stránku?
- Musí se načítat na každé stránce?
- Může se načíst po souhlasu, interakci nebo během nečinnosti?
- Kdo ho interně vlastní?
- Která metrika dokazuje, že za výkonnostní náklady stojí?
Tady se z výkonu stává governance. Někdo musí mít právo říct ne.
Praktický checklist pro snížení počtu požadavků
Začněte stránkami, na kterých záleží nejvíc: homepage, stránka s cenami, produktová stránka, checkout, registrace nebo nejdůležitější landing pages. Pak projděte vodopád.
Odstraňte
- Smažte nepoužívaný JavaScript a CSS.
- Odstraňte staré experimenty, opuštěné pixely a duplicitní analytiku.
- Vyřaďte nepoužívané řezy fontů a knihovny ikon.
- Tam, kde je to vhodné, nahraďte dekorativní obrázky pomocí CSS.
Promyšleně spojte
- Sbalte drobné moduly JavaScriptu, které se vždy načítají společně.
- Sloučte malé soubory CSS, které blokují stejnou cestu vykreslování.
- Použijte SVG sprity nebo inline SVG pro opakované ikony, pokud to sníží počet požadavků a nepoškodí udržovatelnost.
Odložte
- Lazy-loadujte obrázky pod zlomem stránky.
- Odložte nekritické skripty až po prvním vykreslení nebo interakci uživatele.
- Komentáře, embedy, mapy, chat a videopřehrávače načítejte jen tehdy, když jsou potřeba.
Cachujte správně
- Používejte dlouhodobé cachování pro verzované statické assety.
- Vyhněte se zbytečné revalidaci souborů, které se mění jen zřídka.
- HTML udržujte čerstvé, ale hashované assety nechte zůstat v cache.
Znovu změřte
Po každé změně znovu zkontrolujte vodopád. Cílem není dokonalé skóre. Cílem je méně kritických požadavků, dřívější užitečné vykreslení a menší narušování hlavního vlákna.
Jak vypadá dobrý stav
Zdravá stránka nemusí nutně mít nejnižší možný počet požadavků. Má malou, promyšlenou kritickou cestu.
Prohlížeč dostane HTML, základní CSS, obrázek hlavního obsahu, pokud existuje, možná malý skript potřebný pro navigaci nebo interakci nad zlomem stránky, a minimální sadu fontů potřebnou k tomu, aby byl text čitelný. Všechno ostatní počká, až na něj přijde řada.
To je rozdíl mezi stránkou, která je pouze optimalizovaná, a stránkou, která působí rychle.
Zmenšovat soubory má stále smysl. Pokud je ale web už rozumně komprimovaný, další výkonnostní zisk obvykle nebude dalších 2 KB ušetřených z bundlu. Bude to o jeden blokující požadavek méně, o jeden soubor fontu méně, o jeden skript třetí strany méně, o jeden řetězec závislostí méně.
Méně požadavků zjednodušuje práci prohlížeče. Jednoduché je rychlé častěji, než si rádi připouštíme.