Miért küldjön a webhelyed kevesebb kérést, nem pedig csak kisebbeket
Az apró fájlok sincsenek ingyen. A modern HTTP kisebbé tette a kérések többletköltségét, nem jelentéktelenné.
Tartalomjegyzék
- A kényelmes mítosz: „csak legyen minden fájl kisebb”
- A kérések nem csak bájtok
- „De a HTTP/2 ezt megoldotta” — többnyire nem
- A waterfallban látszik az igazság
- A kisebb fájlok továbbra is számítanak — csak nem egyformán
- A sok kis fájl rejtett költségei
- 1. Késői felfedezés
- 2. Fejléc-többlet
- 3. A fő szál megszakítása
- 4. Cache-komplexitás
- A bundling visszatért, de megfontolással
- A harmadik féltől származó kérések külön gyanakvást érdemelnek
- Gyakorlati ellenőrzőlista a kérések csökkentéséhez
- Távolíts el
- Kombinálj megfontoltan
- Halaszd el
- Cache-elj megfelelően
- Mérj újra
- Hogy néz ki a jó állapot
A kényelmes mítosz: „csak legyen minden fájl kisebb”
Éveken át a webes teljesítményről szóló tanács egyszerűnek hangzott: tömöríts mindent, minifikálj mindent, tedd kisebbé az összes erőforrást.
Ez a tanács továbbra is nagyjából helyes. Egy 40 KB-os script általában jobb, mint egy 400 KB-os script. Egy optimalizált kép jobb, mint egy nyers export. A Brotli, az AVIF, a CSS-minifikálás, a tree shaking és a betűkészlet-részhalmazok mind számítanak.
Sok éles webhelyen azonban a nagyobb probléma már nem egy túlméretezett fájl. Hanem az, hány dolgot kell a böngészőnek elkérnie, mielőtt az oldal használhatónak érződik.
Egy oldal fájlméretekben fegyelmezettnek tűnhet, mégis lassú lehet, mert 120 kérést küld: CSS-töredékeket, JavaScript-darabokat, harmadik féltől származó tageket, betűfájlokat, követőpixeleket, ikon sprite-okat, JSON-végpontokat, preloadokat, analitikai beaconöket és gyorsítótár-újraérvényesítéseket. Mindegyik lehet „kicsi”. Együtt hosszú, törékeny waterfallt hoznak létre.
A gyakorlati szabály ez: ha az egyes erőforrások már észszerűen tömörítve vannak, a kérések számának csökkentése gyakran többet javít a felhasználói élményen, mint néhány kilobájt lefaragása minden fájlból.
A kérések nem csak bájtok
Egy hálózati kérés nem pusztán adatátvitel. Munkafolyamatok sorozata.
A böngészőnek fel kell fedeznie az erőforrást, el kell döntenie, mikor kérje le, ütemeznie kell a többi erőforráshoz képest, fejléceket kell küldenie, várnia kell a szerverre, fogadnia kell a fejléceket, feldolgoznia a választ, gyakran ki kell csomagolnia, majd valami hasznosat kell kezdenie vele.
Ez a „valami hasznos” drága is lehet. Egy JavaScript-fájlt parse-olni, fordítani és futtatni kell. Egy CSS-fájl blokkolhatja a renderelést. Egy betűfájl késleltetheti az olvasható szöveget, vagy elrendezés-eltolódásokat okozhat. Egy kép hatással lehet a Largest Contentful Paint elemre. Egy harmadik féltől származó script saját függőségi láncot hozhat magával.
Ezért számít továbbra is a kérések száma akkor is, ha a fájlok kicsik. Egy 3 KB-os script rosszabb lehet, mint egy 30 KB-os kép, ha blokkolja a renderelést, későn érkezik, és rossz pillanatban fut a fő szálon.
Ha Lighthouse-jelentést olvasol, és úgy érzed, tucatnyi külön figyelmeztetés büntet, kezdd inkább a kérések waterfalljának vizsgálatával, ne az egyes pontszámokkal. Van egy gyakorlati útmutatónk arról, hogyan olvass Lighthouse-jelentést pánik nélkül, de a rövid változat ez: keresd meg, mi blokkolja az első renderelést, és mi késlelteti a fő tartalmat.
„De a HTTP/2 ezt megoldotta” — többnyire nem
A HTTP/2 és a HTTP/3 megváltoztatta a kérések gazdaságtanát. Bevezették a multiplexelést, a fejléc-tömörítést és a jobb kapcsolatkezelést. Egyszerűen fogalmazva: a böngészők sokkal jobbak lettek abban, hogy több kérést kevesebb kapcsolaton küldjenek el.
Ez valódi javulás volt. Emellett megszüntetett néhány régi szokást is, például a szélsőséges CSS sprite-okat és az óriási összefűzött bundle-öket, amelyeket kizárólag a kapcsolatszám-korlátok elkerülésére építettek.
De a HTTP/2 nem tette ingyenessé a kéréseket.
A multiplexelés segít, ha sok erőforrás osztozik egy kapcsolaton, de a böngészőnek továbbra is priorizálnia kell őket. A szervereknek továbbra is válaszolniuk kell. A kliensnek továbbra is fel kell dolgoznia minden választ. A torlódás, a csomagvesztés, a TLS-egyeztetés, a DNS-keresés, a cache miss és a fő szál terhelése továbbra is létezik.
A HTTP/3 javít bizonyos szállítási viselkedéseken, különösen a kapcsolatvándorlás és a szállítási rétegbeli head-of-line blocking körül. Nem szünteti meg az erőforrások felfedezésének, ütemezésének, letöltésének, feldolgozásának és futtatásának költségét.
A modern cél tehát nem az, hogy „mindent egyetlen hatalmas fájlba csomagoljunk”. Hanem az, hogy „kevesebb kritikus kérést küldjünk, és a megmaradó kérések szándékosak legyenek”.
A waterfallban látszik az igazság
A teljesítményproblémák ritkán jelentkeznek egyetlen metrikában. Alakzatként mutatkoznak meg.
Nyisd meg a böngésző hálózati paneljét, és nézd meg az első néhány másodpercet. Kérdezd meg:
- Hány kérés indul el, mielőtt a fő tartalom megjelenik?
- Mely kérések blokkolják a renderelést?
- A fontos erőforrások későn derülnek ki?
- Harmadik féltől származó scriptek versenyeznek a saját CSS-sel, betűkkel vagy képekkel?
- Sok fájl 304-es választ ad vissza ahelyett, hogy közvetlenül a cache-ből szolgálódna ki?
- Az ikonok, betűk vagy UI-töredékek több fájlra vannak bontva, mint amennyire az oldalnak szüksége van?
Egy gyors oldal korai waterfallja általában unalmas. Kevés kritikus erőforrás érkezik korán. A nem kritikus erőforrások várnak. A harmadik féltől származó scriptek késleltetve, korlátozva vagy eltávolítva vannak. A böngészőnek nem kell húsz prioritással zsonglőrködnie, mielőtt ki tudná festeni az oldalt.
Egy lassú oldal waterfallja gyakran ideges: sok kis fájl, sok origin és sok késői felfedezés.
A kisebb fájlok továbbra is számítanak — csak nem egyformán
Ez nem érv a tömörítés vagy az optimalizálás ellen. Ez érv az ellen, hogy a bájtokat optimalizáljuk, miközben figyelmen kívül hagyjuk az összehangolást.
A kisebb fájlok akkor számítanak a legtöbbet, ha az erőforrás nagy, renderelést blokkol, vagy a fő tartalmi útvonal része. Például:
- A hero képet megfelelő méretre kell vágni és megfelelően kódolni.
- A renderelést blokkoló CSS legyen karcsú.
- Az első interakcióhoz szükséges JavaScript legyen minimális.
- A betűket részhalmazolni, tömöríteni kell, és csak a ténylegesen használt vastagságokra kell korlátozni.
A betűk gyakori példa. A csapatok sokszor azon aggódnak, hogy egy betűfájl 24 KB vagy 31 KB, miközben hat vastagságot, két stílust és több családot szállítanak. A jobb javítás nem 7 KB lefaragása egy fájlból. Hanem kevesebb betűfájl küldése. Ha a tipográfia része a teljesítményjavításnak, a webes betűkészletek továbbra is a legtöbb webhely egyik legegyszerűbb nyereségét jelentik.
A képek ugyanilyen mintát követnek. Az AVIF vagy a WebP jelentős bájtmegtakarítást hozhat, de tíz dekoratív képet küldeni a hajtás fölé továbbra is rossz terv. Válassz jobb formátumokat, igen, de azt is kérdőjelezd meg, hogy egyáltalán szükséges-e minden képet lekérni. A formátumdöntésekhez hasznos kísérője ennek a kérésszám-csökkentési munkának az útmutatónk arról, hogy mikor jobb az AVIF a WebP-nél, és mikor nem.
A sok kis fájl rejtett költségei
A sok kis kérés hajlamos olyan problémákat létrehozni, amelyek nem látszanak, ha csak az összes átvitt bájtot nézed.
1. Késői felfedezés
A böngészők nem tudják lekérni azt, amit még nem fedeztek fel. Egy CSS-fájl hivatkozhat egy betűre. Egy script importálhat egy másik scriptet. Egy komponens a hidratálás után kérhet JSON-t. Minden függőség újabb lépést hoz létre a láncban.
Minél mélyebb a lánc, annál később kezdődik a fontos munka.
2. Fejléc-többlet
Minden kérés és válasz tartalmaz fejléceket. A fejléc-tömörítés segít, különösen HTTP/2 és HTTP/3 felett, de nem szünteti meg a többletköltséget. A cookie-k ezt jelentősen ronthatják. Ha a webhelyed minden kéréssel nagy cookie-kat küld, az apró erőforrások a gyakorlatban kevésbé lesznek aprók.
Ez az egyik oka annak, hogy a statikus erőforrásoknak gyakran cookie-mentes útvonalakon vagy domaineken kellene élniük, és ezért érdemelnek figyelmet a cache-fejlécek. Ha a fejlécek furcsán viselkednek éles környezetben, az átirányítások és HTTP-fejlécek hibakeresése általában gyorsabb, mint a találgatás.
3. A fő szál megszakítása
Sok JavaScript-darab ismétlődő parse-olási és futtatási munkát hozhat létre. Még ha minden darab kicsi is, a böngésző újra és újra megállhat a kód kiértékelésére. Ez ronthatja az Interaction to Next Paint értéket, és szaggatottabbnak éreztetheti az oldalt.
A felhasználót nem érdekli, hogy minden fájl kicsi volt. Az érdekli, hogy egy menü megérintése 600 ezredmásodpercig tartott.
4. Cache-komplexitás
Az erőforrások szétválasztása javíthatja a gyorsítótárazást, ha körültekintően történik. Egy stabil vendor bundle és egy változó app bundle jó felosztás lehet.
A túlzott chunkolás azonban visszaüthet. Több fájl több cache-keresést, több újraérvényesítési lehetőséget, több verziókoordinációt és több módot jelent arra, hogy véletlenül érvénytelenítsünk olyan erőforrásokat, amelyeknek nem kellett volna változniuk.
A bundling visszatért, de megfontolással
A webes teljesítmény első korszaka szerette a bundlingot, mert a böngészőknek szigorú kapcsolatszám-korlátai voltak. Aztán megérkezett a HTTP/2, és sok csapat erősen az agresszív code splitting felé lendült. Ennek egy része hasznos volt. Egy része babonává vált.
Az észszerű középút az útvonal-tudatos bundling.
Egy tipikus marketing- vagy tartalmi webhely esetén:
- Inline-old vagy töltsd be csak a kezdeti rendereléshez szükséges CSS-t.
- Tartsd kicsiben a globális JavaScriptet.
- Kerüld az apró modulok külön hálózati kérésekre bontását.
- Késleltesd azokat az interaktív funkciókat, amelyekre nincs azonnal szükség.
- Távolítsd el azokat a harmadik féltől származó scripteket, amelyek nem igazolják a költségüket.
Egy alkalmazás esetén:
- Útvonal vagy fő funkció szerint bonts, ne minden komponens szerint.
- Tartsd stabilan és cache-elhetően a megosztott függőségeket.
- Csak azokat az erőforrásokat preloadold, amelyekre biztosan hamar szükség lesz.
- Kerüld az admin, dashboard, szerkesztői vagy kísérleti kód betöltését nyilvános oldalakon.
- Az interakciós költséget mérd, ne csak a bundle méretét.
A bundling nem automatikusan jó. A code splitting nem automatikusan jó. A hasznos kérdés ez: segít-e ez a felosztás abban, hogy a böngésző hamarabb eljuttassa a következő jelentős felhasználói élményt?
A harmadik féltől származó kérések külön gyanakvást érdemelnek
A saját kérések legalább az irányításod alatt állnak. A harmadik féltől származó kérések gyakran lassabbak, kevésbé kiszámíthatók és drágábbak, mint amilyennek látszanak.
Egyetlen tag manager elindíthat analitikát, hirdetéseket, heatmapeket, chat widgeteket, A/B tesztelést, hozzájáruláskezelő eszközöket és személyre szabási scripteket. Minden vendor további kéréseket hozhat. Néhány korán fut. Néhány blokkolja a fő szálat. Néhány a te release-folyamatod nélkül változik.
A legjobb harmadik féltől származó optimalizálás a törlés. A második legjobb a késleltetés.
Mielőtt harmadik féltől származó scriptet adnál hozzá, kérdezd meg:
- Ennek be kell töltődnie, mielőtt a felhasználó látja az oldalt?
- Minden oldalon be kell töltődnie?
- Betölthet hozzájárulás, interakció vagy üresjárati idő után?
- Ki a belső felelőse?
- Melyik metrika bizonyítja, hogy megéri a teljesítményköltséget?
Itt válik a teljesítmény irányítássá. Valakinek jogosultnak kell lennie nemet mondani.
Gyakorlati ellenőrzőlista a kérések csökkentéséhez
Kezdd a legfontosabb oldalakkal: főoldal, árazási oldal, termékoldal, checkout, regisztráció vagy a legfontosabb landing oldalak. Ezután menj végig a waterfallon.
Távolíts el
- Töröld a nem használt JavaScriptet és CSS-t.
- Távolítsd el a régi kísérleteket, elhagyott pixeleket és duplikált analitikát.
- Dobd el a nem használt betűvastagságokat és ikonkönyvtárakat.
- Ahol megfelelő, cseréld a dekoratív képeket CSS-re.
Kombinálj megfontoltan
- Bundle-öld az apró JavaScript-modulokat, amelyek mindig együtt töltődnek be.
- Vond össze azokat a kis CSS-fájlokat, amelyek ugyanazt a renderelési útvonalat blokkolják.
- Használj SVG sprite-okat vagy inline SVG-t ismétlődő ikonokhoz, ha ez csökkenti a kérések számát anélkül, hogy rontaná a karbantarthatóságot.
Halaszd el
- Lazy-loadold a hajtás alatti képeket.
- Késleltesd a nem kritikus scripteket az első festés vagy felhasználói interakció utánra.
- A kommenteket, beágyazásokat, térképeket, chatet és videólejátszókat csak akkor töltsd be, amikor szükség van rájuk.
Cache-elj megfelelően
- Használj hosszú élettartamú gyorsítótárazást a verziózott statikus erőforrásokhoz.
- Kerüld a felesleges újraérvényesítést olyan fájloknál, amelyek ritkán változnak.
- Tartsd frissen a HTML-t, de hagyd, hogy a hash-elt erőforrások cache-ben maradjanak.
Mérj újra
Minden változtatás után ellenőrizd újra a waterfallt. A cél nem a tökéletes pontszám. A cél a kevesebb kritikus kérés, a korábbi hasznos renderelés és a kisebb főszál-zavarás.
Hogy néz ki a jó állapot
Egy egészséges oldalnak nem feltétlenül a lehető legkevesebb kérése van. Hanem kicsi, szándékos kritikus útvonala.
A böngésző megkapja a HTML-t, az alapvető CSS-t, a fő tartalmi képet, ha van ilyen, esetleg egy kis scriptet, amely a navigációhoz vagy a hajtás feletti interakcióhoz szükséges, és a minimális betűkészletet, amely ahhoz kell, hogy a szöveg olvasható legyen. Minden más kivárja a sorát.
Ez a különbség egy pusztán optimalizált oldal és egy gyorsnak érződő oldal között.
A fájlok zsugorítása továbbra is megéri. De ha a webhely már észszerűen tömörített, a következő teljesítménynyereség általában nem újabb 2 KB megtakarítása egy bundle-ből. Hanem eggyel kevesebb blokkoló kérés, eggyel kevesebb betűfájl, eggyel kevesebb harmadik féltől származó script, eggyel kevesebb függőségi lánc.
A kevesebb kérés egyszerűbbé teszi a böngésző munkáját. Az egyszerű gyakrabban gyors, mint szeretnénk bevallani.