Miksi sivustosi pitäisi lähettää vähemmän pyyntöjä, ei vain pienempiä
Pienet tiedostot eivät ole ilmaisia. Moderni HTTP pienensi pyyntöjen yleiskustannusta, mutta ei tehnyt siitä merkityksetöntä.
Sisällysluettelo
- Mukava myytti: “tehdään vain jokaisesta tiedostosta pienempi”
- Pyynnöt eivät ole vain tavuja
- “Mutta HTTP/2 korjasi tämän” — enimmäkseen ei
- Totuus löytyy vesiputouksesta
- Pienemmillä tiedostoilla on yhä merkitystä — mutta ei yhtä paljon kaikilla
- Monien pienten tiedostojen piilokustannukset
- 1. Myöhäinen löytyminen
- 2. Otsakkeiden yleiskustannus
- 3. Pääsäikeen keskeytykset
- 4. Välimuistin monimutkaisuus
- Bundlaus on palannut, mutta harkiten
- Kolmannen osapuolen pyynnöt ansaitsevat erityistä epäluuloa
- Käytännön tarkistuslista pyyntöjen vähentämiseen
- Poista
- Yhdistä harkiten
- Lykkää
- Välimuistita oikein
- Mittaa uudelleen
- Miltä hyvä näyttää
Mukava myytti: “tehdään vain jokaisesta tiedostosta pienempi”
Vuosien ajan verkkosuorituskyvyn neuvo kuulosti yksinkertaiselta: pakkaa kaikki, minimoi kaikki, tee jokaisesta resurssista pienempi.
Neuvo on edelleen laajasti oikea. 40 KB:n skripti on yleensä parempi kuin 400 KB:n skripti. Optimoitu kuva on parempi kuin raakavienti. Brotli, AVIF, CSS:n minimointi, tree shaking ja fonttien alijoukot ovat kaikki tärkeitä.
Mutta monilla tuotantosivustoilla suurempi ongelma ei enää ole yksi ylikokoinen tiedosto. Se on niiden asioiden määrä, joita selaimen täytyy pyytää ennen kuin sivu tuntuu käyttökelpoiselta.
Sivu voi näyttää tiedostokokojen osalta kurinalaiselta ja olla silti hidas, koska se lähettää 120 pyyntöä: CSS-paloja, JavaScript-lohkoja, kolmannen osapuolen tageja, fonttitiedostoja, seurantapikseleitä, kuvakespritejä, JSON-päätepisteitä, preload-pyyntöjä, analytiikkamajakoita ja välimuistin uudelleenvalidointeja. Jokainen voi olla “pieni”. Yhdessä ne luovat pitkän ja hauraan vesiputouksen.
Käytännön sääntö on tämä: kun yksittäiset resurssit on jo kohtuullisesti pakattu, pyyntöjen määrän vähentäminen parantaa usein käyttäjäkokemusta enemmän kuin muutaman kilotavun höylääminen jokaisesta tiedostosta.
Pyynnöt eivät ole vain tavuja
Verkkopyyntö ei ole pelkkä tiedonsiirto. Se on sarja työtä.
Selaimen täytyy löytää resurssi, päättää milloin se haetaan, aikatauluttaa se suhteessa muihin resursseihin, lähettää otsakkeet, odottaa palvelinta, vastaanottaa otsakkeet, jäsentää vastaus, usein purkaa sen pakkaus ja tehdä sitten sillä jotakin hyödyllistä.
Tuo “jotakin hyödyllistä” voi olla kallista. JavaScript-tiedosto täytyy jäsentää, kääntää ja suorittaa. CSS-tiedosto voi estää renderöinnin. Fonttitiedosto voi viivästyttää luettavaa tekstiä tai aiheuttaa asettelun siirtymiä. Kuva voi vaikuttaa Largest Contentful Paint -elementtiin. Kolmannen osapuolen skripti voi tuoda mukanaan oman riippuvuusketjunsa.
Siksi pyyntöjen määrällä on edelleen merkitystä, vaikka tiedostot olisivat pieniä. 3 KB:n skripti voi olla huonompi kuin 30 KB:n kuva, jos se estää renderöinnin, saapuu myöhään ja suoritetaan pääsäikeessä väärällä hetkellä.
Jos luet Lighthouse-raporttia ja tunnet saavasi rangaistuksia kymmenistä erillisistä varoituksista, aloita katsomalla pyyntöjen vesiputousta yksittäisten pisteiden sijaan. Meillä on käytännön läpikäynti artikkelissa miten Lighthouse-raporttia luetaan panikoimatta, mutta lyhyt versio on: etsi mikä estää ensimmäistä renderöintiä ja mikä viivästyttää pääsisältöä.
“Mutta HTTP/2 korjasi tämän” — enimmäkseen ei
HTTP/2 ja HTTP/3 muuttivat pyyntöjen taloutta. Ne toivat multipleksoinnin, otsakkeiden pakkauksen ja paremman yhteyskäyttäytymisen. Yksinkertaisesti sanottuna selaimet paranivat huomattavasti useiden pyyntöjen lähettämisessä harvempien yhteyksien yli.
Se oli todellinen parannus. Se myös lopetti joitakin vanhoja tapoja, kuten äärimmäiset CSS-spritet ja valtavat yhdistetyt bundle-tiedostot, jotka rakennettiin vain yhteysrajojen kiertämiseksi.
Mutta HTTP/2 ei tehnyt pyynnöistä ilmaisia.
Multipleksointi auttaa, kun monet resurssit jakavat yhteyden, mutta selaimen täytyy silti priorisoida ne. Palvelimien täytyy silti vastata. Asiakkaan täytyy silti käsitellä jokainen vastaus. Ruuhkautuminen, pakettihävikki, TLS-neuvottelu, DNS-haku, välimuistiosumat ohi ja pääsäikeen paine ovat edelleen olemassa.
HTTP/3 parantaa joitakin siirtokerroksen käyttäytymisiä, erityisesti yhteyden siirtymisen ja siirtokerroksen head-of-line blocking -ongelman ympärillä. Se ei poista resurssien löytämisen, aikatauluttamisen, lataamisen, jäsentämisen ja suorittamisen kustannusta.
Moderni tavoite ei siis ole “paketoida kaikkea yhteen valtavaan tiedostoon”. Se on “lähettää vähemmän kriittisiä pyyntöjä ja tehdä jäljelle jäävistä pyynnöistä tarkoituksellisia”.
Totuus löytyy vesiputouksesta
Suorituskykyongelmat ilmoittavat harvoin itsestään yhdessä mittarissa. Ne näkyvät muotona.
Avaa selaimen verkkopaneeli ja katso ensimmäisiä sekunteja. Kysy:
- Kuinka monta pyyntöä alkaa ennen kuin pääsisältö ilmestyy?
- Mitkä pyynnöt estävät renderöinnin?
- Löytyvätkö tärkeät resurssit myöhään?
- Kilpailevatko kolmannen osapuolen skriptit oman sivuston CSS:n, fonttien tai kuvien kanssa?
- Palauttavatko monet tiedostot 304-vastauksia sen sijaan, että ne tarjottaisiin suoraan välimuistista?
- Onko kuvakkeet, fontit tai käyttöliittymäpalat pilkottu useampiin tiedostoihin kuin sivu tarvitsee?
Nopealla sivulla on yleensä tylsä alkuvaiheen vesiputous. Pieni määrä kriittisiä resursseja saapuu aikaisin. Ei-kriittiset resurssit odottavat. Kolmannen osapuolen skriptit viivästetään, rajataan tai poistetaan. Selainta ei pakoteta jongleeraamaan kahdenkymmenen prioriteetin kanssa ennen kuin se voi maalata sivun.
Hitaalla sivulla on usein hermostunut vesiputous: paljon pieniä tiedostoja, paljon alkuperiä ja paljon myöhäisiä löytöjä.
Pienemmillä tiedostoilla on yhä merkitystä — mutta ei yhtä paljon kaikilla
Tämä ei ole argumentti pakkaamista tai optimointia vastaan. Se on argumentti sen puolesta, ettei tavuja optimoida koordinointi sivuuttaen.
Pienemmillä tiedostoilla on eniten merkitystä, kun resurssi on suuri, renderöintiä estävä tai osa pääsisällön polkua. Esimerkiksi:
- Hero-kuvan pitäisi olla oikein mitoitettu ja koodattu.
- Renderöintiä estävän CSS:n pitäisi olla kevyt.
- Ensimmäiseen vuorovaikutukseen tarvittavan JavaScriptin pitäisi olla minimaalista.
- Fonttien pitäisi olla alijoukotettuja, pakattuja ja rajattuja vain käytettyihin leikkauksiin.
Fontit ovat yleinen esimerkki. Tiimit pakkomielteisesti pohtivat usein, onko fonttitiedosto 24 KB vai 31 KB, samalla kun ne toimittavat kuusi leikkausta, kaksi tyyliä ja useita perheitä. Parempi korjaus ei ole 7 KB:n höylääminen yhdestä tiedostosta. Se on vähempien fonttitiedostojen lähettäminen. Jos typografia on osa suorituskykytyötäsi, web-fontit ovat edelleen yksi helpoimmista voitoista useimmilla sivustoilla.
Kuvat noudattavat samaa kaavaa. AVIF tai WebP voi säästää merkittävästi tavuja, mutta kymmenen koristekuvan lähettäminen ensinäytön alueelle on silti huono suunnitelma. Valitse parempia formaatteja, kyllä, mutta kyseenalaista myös, tarvitseeko jokaista kuvaa pyytää lainkaan. Formaattipäätöksiin oppaamme milloin AVIF voittaa WebP:n ja milloin ei on hyödyllinen kumppani tälle pyyntömäärätyölle.
Monien pienten tiedostojen piilokustannukset
Monet pienet pyynnöt luovat helposti ongelmia, jotka eivät näy, jos katsot vain siirrettyjen tavujen kokonaismäärää.
1. Myöhäinen löytyminen
Selaimet eivät voi pyytää sitä, mitä ne eivät ole löytäneet. CSS-tiedosto voi viitata fonttiin. Skripti voi tuoda toisen skriptin. Komponentti voi pyytää JSONia hydraation jälkeen. Jokainen riippuvuus luo uuden askeleen ketjuun.
Mitä syvempi ketju, sitä myöhemmin tärkeä työ alkaa.
2. Otsakkeiden yleiskustannus
Jokainen pyyntö ja vastaus sisältää otsakkeita. Otsakkeiden pakkaus auttaa, erityisesti HTTP/2:n ja HTTP/3:n yli, mutta se ei poista yleiskustannusta. Evästeet voivat pahentaa tätä paljon. Jos sivustosi lähettää suuria evästeitä jokaisen pyynnön mukana, pienet resurssit eivät käytännössä olekaan niin pieniä.
Tämä on yksi syy siihen, miksi staattisten resurssien pitäisi usein olla evästeettömillä poluilla tai verkkotunnuksilla, ja miksi välimuistiotsakkeet ansaitsevat huomiota. Jos otsakkeet käyttäytyvät oudosti tuotannossa, uudelleenohjausten ja HTTP-otsakkeiden debuggaus on yleensä nopeampaa kuin arvaaminen.
3. Pääsäikeen keskeytykset
Monet JavaScript-lohkot voivat aiheuttaa toistuvaa jäsentämis- ja suoritustyötä. Vaikka jokainen lohko olisi pieni, selain voi joutua jatkuvasti pysähtymään arvioimaan koodia. Tämä voi heikentää Interaction to Next Paint -mittaria ja saada sivun tuntumaan nykivältä.
Käyttäjää ei kiinnosta, että jokainen tiedosto oli pieni. Häntä kiinnostaa, että valikon napauttaminen kesti 600 millisekuntia.
4. Välimuistin monimutkaisuus
Resurssien jakaminen voi parantaa välimuistitusta, kun se tehdään huolellisesti. Vakaa vendor-bundle ja muuttuva app-bundle voivat olla hyvä jako.
Mutta liiallinen lohkominen voi kostautua. Enemmän tiedostoja tarkoittaa enemmän välimuistihakuja, enemmän uudelleenvalidoinnin mahdollisuuksia, enemmän versioiden koordinointia ja enemmän tapoja vahingossa mitätöidä resursseja, joiden ei olisi tarvinnut muuttua.
Bundlaus on palannut, mutta harkiten
Verkkosuorituskyvyn ensimmäinen aikakausi rakasti bundlausta, koska selaimilla oli tiukat yhteysrajat. Sitten HTTP/2 saapui, ja monet tiimit heilahtivat voimakkaasti aggressiivisen koodin pilkkomisen suuntaan. Osa siitä oli hyödyllistä. Osa siitä muuttui taikauskoksi.
Järkevä välimuoto on reittitietoinen bundlaus.
Tyypillisellä markkinointi- tai sisältösivustolla:
- Lisää inline-muodossa tai lataa vain alkuperäiseen renderöintiin tarvittava CSS.
- Pidä globaali JavaScript pienenä.
- Vältä pienten moduulien pilkkomista erillisiksi verkkopyynnöiksi.
- Viivästä interaktiivisia ominaisuuksia, joita ei tarvita heti.
- Poista kolmannen osapuolen skriptit, jotka eivät oikeuta kustannustaan.
Sovelluksessa:
- Pilko reitin tai suuren ominaisuuden mukaan, ei jokaisen komponentin mukaan.
- Pidä jaetut riippuvuudet vakaina ja välimuistitettavina.
- Esilataa vain resursseja, joita varmasti tarvitaan pian.
- Vältä admin-, dashboard-, editor- tai kokeilukoodin lataamista julkisille sivuille.
- Mittaa vuorovaikutuksen kustannusta, älä vain bundlen kokoa.
Bundlaus ei ole automaattisesti hyvä. Koodin pilkkominen ei ole automaattisesti hyvä. Hyödyllinen kysymys on: auttaako tämä jako selainta toimittamaan seuraavan merkityksellisen käyttäjäkokemuksen aiemmin?
Kolmannen osapuolen pyynnöt ansaitsevat erityistä epäluuloa
Ensimmäisen osapuolen pyynnöt ovat sentään hallinnassasi. Kolmannen osapuolen pyynnöt ovat usein hitaampia, vähemmän ennustettavia ja kalliimpia kuin miltä ne näyttävät.
Yksi tag manager voi käynnistää analytiikkaa, mainoksia, heatmappeja, chat-widgettejä, A/B-testausta, suostumustyökaluja ja personointiskriptejä. Jokainen toimittaja voi tuoda lisää pyyntöjä. Osa suoritetaan aikaisin. Osa estää pääsäiettä. Osa muuttuu ilman julkaisuprosessiasi.
Paras kolmannen osapuolen optimointi on poistaminen. Toiseksi paras on viivästäminen.
Ennen kuin lisäät kolmannen osapuolen skriptin, kysy:
- Täytyykö tämän latautua ennen kuin käyttäjä näkee sivun?
- Täytyykö sen latautua jokaisella sivulla?
- Voiko se latautua suostumuksen, vuorovaikutuksen tai joutoajan jälkeen?
- Kuka omistaa sen sisäisesti?
- Mikä mittari todistaa, että se on suorituskykykustannuksensa arvoinen?
Tässä suorituskyvystä tulee hallintaa. Jollakulla täytyy olla lupa sanoa ei.
Käytännön tarkistuslista pyyntöjen vähentämiseen
Aloita sivuista, joilla on eniten merkitystä: etusivu, hinnoittelusivu, tuotesivu, kassasivu, rekisteröityminen tai tärkeimmät laskeutumissivut. Käy sitten vesiputous läpi.
Poista
- Poista käyttämätön JavaScript ja CSS.
- Poista vanhat kokeilut, hylätyt pikselit ja päällekkäinen analytiikka.
- Pudota käyttämättömät fonttileikkaukset ja kuvakekirjastot.
- Korvaa koristekuvat CSS:llä, kun se on tarkoituksenmukaista.
Yhdistä harkiten
- Bundlaa pienet JavaScript-moduulit, jotka latautuvat aina yhdessä.
- Yhdistä pienet CSS-tiedostot, jotka estävät samaa renderöintipolkua.
- Käytä SVG-spritejä tai inline-SVG:tä toistuviin kuvakkeisiin, kun se vähentää pyyntöjä ylläpidettävyyttä heikentämättä.
Lykkää
- Lazy-load-kuvat ensinäytön alapuolelta.
- Viivästä ei-kriittiset skriptit ensimmäisen maalauksen tai käyttäjän vuorovaikutuksen jälkeiseen aikaan.
- Lataa kommentit, upotukset, kartat, chat ja videosoittimet vain tarvittaessa.
Välimuistita oikein
- Käytä pitkäikäistä välimuistitusta versioiduille staattisille resursseille.
- Vältä tarpeetonta uudelleenvalidointia tiedostoille, jotka muuttuvat harvoin.
- Pidä HTML tuoreena, mutta anna hashattujen resurssien pysyä välimuistissa.
Mittaa uudelleen
Tarkista vesiputous uudelleen jokaisen muutoksen jälkeen. Tavoite ei ole täydellinen pistearvo. Tavoite on vähemmän kriittisiä pyyntöjä, aikaisempi hyödyllinen renderöinti ja vähemmän pääsäikeen häiriöitä.
Miltä hyvä näyttää
Terveellä sivulla ei välttämättä ole mahdollisimman vähän pyyntöjä. Sillä on pieni ja harkittu kriittinen polku.
Selain saa HTML:n, olennaisen CSS:n, pääsisältökuvan jos sellainen on, ehkä pienen skriptin, jota tarvitaan navigaatioon tai ensinäytön vuorovaikutukseen, sekä vähimmäisfonttijoukon, joka tarvitaan tekstin luettavaksi tekemiseen. Kaikki muu odottaa vuoroaan.
Siinä on ero sivun välillä, joka on vain optimoitu, ja sivun välillä, joka tuntuu nopealta.
Tiedostojen pienentäminen on edelleen tekemisen arvoista. Mutta jos sivusto on jo kohtuullisesti pakattu, seuraava suorituskykyvoitto ei yleensä ole toisen 2 KB:n säästäminen bundlesta. Se on yksi estävä pyyntö vähemmän, yksi fonttitiedosto vähemmän, yksi kolmannen osapuolen skripti vähemmän, yksi riippuvuusketju vähemmän.
Vähemmän pyyntöjä tekee selaimen työstä yksinkertaisempaa. Yksinkertainen on useammin nopeaa kuin haluamme myöntää.