Hur jag ökade prestandan med 951% på Gymjakt.se

Ökad prestanda med 951%

Webbprestanda blir viktigare för varje dag som går, särskilt med tanke på att mobila surfare kommer vara en majoritet om ett år. En bättre prestanda ger inte bara besökaren en bättre användarupplevelse, utan gör också att du kan ha fler besökare samtidigt.

Den här artikeln är en fallstudie av Sveriges största gymguide där jag ökade prestandan med 951%. Jag kommer berätta vad jag gjorde för något, varför jag gjorde det och vad de exakta resultaten över prestandan blev.

Anledningen till arbetet

Gymjakt.se växer och behövde utrymme för att växa ännu mer. Optimeringen gjordes i förebyggande syfte för just detta ändamål, så att varje besökare ska få en lika bra upplevelse — oavsett ifall det är en besökare eller tusen besökare inne på webbplatsen samtidigt.

Sajtens kodstruktur byggdes även om för att göra det enklare att underhålla och bygga vidare med nya funktioner.

De optimeringar som gjorts

Det är fler än en optimering som gjorts för att öka Gymjakt’s prestanda. Nedan kommer jag beskriva dem så enkelt men detaljerat som möjligt.

Byte av server

I samband med optimeringen av Gymjakt bytte jag server, men inom samma leverantör (Ipeer). Både nya och gamla servern har följande specifikationer:

  • En dedikerad processorkärna hos en Intel® Xeon® CPU E5-2630 0 @ 2.30GHz
  • SAS-hårddiskar i RAID 1
  • Debian 6.0 x64 som operativsystem
  • En dedikerad IP-adress
  • 100Mbps nätverksanslutning
  • Placerad i Karlstad

Det som skiljer dem åt är RAM-minnet, där gamla servern har 1024 MB medan nya servern bara har hälften så mycket: 512 MB.

Nginx

Implementering av Nginx

Den välkända webbservern Apache drev gamla Gymjakt under ett års tid. Många tror att det är den enda webbservern som finns, men så är verkligen inte fallet.

För ett par veckor sedan skrev jag en introduktion till webbservern Nginx. Nginx driver självklart även nya Gymjakt och är den förändring som gjort störst påverkan för den ökade prestandan. Eftersom Nginx är väldigt resurssnål kunde jag halvera minnet på nya servern och därmed få den billigare i drift. Jag konfigurerade även Nginx för att trimma sajten lite ytterligare.

Implementering av MariaDB

Det finns även alternativ till den populära databasen MySQL, som gamla Gymjakt använde. MariaDB fungerar ungefär likadant men presterar kort sagt bättre, samtidigt som det finns stöd för fler funktioner. MariaDB var ett enkelt val för nya Gymjakt.

Förbättrad kodstruktur

Koden bakom nya Gymjakt har MVC-struktur och använder sig av så kallad “output buffering” (direktöversatt blir det utgångsbuffert). På så sätt blir koden mer strukturerad, lättläst, återanvändningsbar och även lite snabbare — mycket trevliga egenskaper.

Eftersom JavaScript-biblioteket jQuery var överflödigt för Gymjakt så plockades det bort, vilket gjorde sajten ca 80 kB lättare.

Prestandaanalys

Prestanda

För att kunna mäta och jämföra prestandan gjorde jag två olika sorters prestandaanalyser av startsidan på gamla och nya Gymjakt — ett enklare sidladdningstest och ett stresstest.

Sidladdningstest

I sidladdningstestet kontrollerar jag hur snabbt sidan laddar in alla resurser med webbläsarens cache avstängt. Testet körs tio gånger i följd och därefter räknas medeltalen ut. Testet sker från min dator (Stockholm, ca 25 mil från servern).

Stresstest

Det här testet går ut på att se hur många anrop webbplatsen klarar av att hantera. 200 anrop skickas i taget till webbplatsen i snabb följd tills de uppnått totalt 5000 anrop. Anropen sker från samma serverhall som webbplatsen. Tio sådana här tester körs i följd och därefter räknas medeltalen ut.

Viktigt att veta

Något som är viktigt att veta när man granskar resultaten är några skillnader i innehållet på startsidan.

  • Gamla webbplatsen har 13 anrop på totalt 283 KB (varav 6,3 KB är HTML)
  • Nya webbplatsen har 15 anrop på totalt 311 KB (varav 5,3 KB är HTML)

Det kan tyckas vara en obefintlig skillnad, men när man räknar millisekunder kan det påverka resultaten.

Resultat

Resultaten för båda testerna är ganska imponerande.

Sidladdningstest

De tio olika testen är presenterade i diagrammet nedan, där siffrorna är tid i millisekunder (lägre är bättre). “DOM” är när dokumentet laddat klart och “Totalt” är när allt laddat klart.

Prestandaanalys: Sidladdningstest

Genomsnittet för gamla och nya sajten är 216 ms respektive 177 ms för dokumentet och 464 ms respektive 387 ms totalt. Det innebär alltså en förbättring på ungefär 22% för dokumentet och ungefär 20% totalt, trots att det är 28 KB och två anrop extra. Inte illa!

Stresstest

Det är resultatet för stresstestet som är mest intressant — siffrorna är antalet anrop per sekund för de tio olika testen (högre är bättre).

Prestandaanalys: Stresstest

Den gamla webbplatsen (med Apache) är det svarta strecket i botten och ser näst intill död ut i jämförelse med den nya webbplatsen (med Nginx). Även nedanstående diagram visar en enorm skillnad mellan resultaten, där staplarna i svart är gamla webbplatsen och oranget den nya.

Prestandaanalys: Stresstest (totalt)

Den gamla webbplatsen klarar av att hantera i snitt 171,10 anrop per sekund, medan nya webbplatsen klarar av 1627,27 anrop per sekund — en massiv ökning med 951%. Med en överföringshastighet på 1158 kbps respektive 1355 kbps skickas datan dessutom 17% snabbare från den nya webbplatsen. Det tog i snitt 29,25 sekunder att få svar från gamla webbplatsen på alla 5000 anrop, något som nya webbplatsen fixade på 3,11 sekunder — nästan en tiondel av tiden.

Om du vill ha alla exakta siffror av stresstestet kan du ladda ner dem här: Stresstest av Gymjakt.se (PDF)

Sammanfattning

  • Webbplatsen laddar in cirka 20% snabbare
  • Webbplatsen kan hantera 951% fler anrop med bara hälften av RAM-minnet
  • Datan skickas med 17% högre hastighet
  • Webbplatsen hanterar 5000 anrop på nästan 10% av den ursprungliga tiden

Slutord

Att optimera webbprestanda är ett jobb som jag verkligen tycker om. Resultatet blir ofta väldigt bra, och det finns många fördelar med att ha en snabb och välpresterande webbplats (kommer i en senare artikel).

Hur viktigt är webbprestanda för dig?

Ivar Johansson

Skriven av

Ivar började med webbutveckling för tio år sedan och har sedan dess utvecklat breda kunskaper inom framför allt webbprestanda, sökmotorer och användarupplevelse. Idag driver han eget företag där han skapar webbplatser som är snabba, säkra och enkla att hantera.

  1. Gerd Wallin

    12 januari, 2014

    Heja Ivar!!
    Mycket proffsigt!!

    Lycka till!

  2. Andreas

    12 januari, 2014

    Diagrammen kunde ha varit mer tydliga med vad som är Apache2 respektive Nginx. Men för övrigt bra artikel! Kul att du har fått bättre prestanda.

  3. Ivar Johansson

    13 januari, 2014

    Tack Gerd och Andreas!

    Det är sajtens prestanda i sig som jag jämför, där är Nginx bara en del av förbättringarna. Men ska tänka på det till nästa gång!

  4. Olaf

    10 mars, 2014

    Intressant jämförelse och bra skrivet, vore kul att veta lite mer vilka verktyg du valt att använda och bakgrunden till dessa. :)

  5. Ivar Johansson

    10 mars, 2014

    Tack Olaf!

    I prestandatestet användes Chrome tillsammans med ApacheBench för att få resultaten. Hör gärna av dig om det är något mer du är nyfiken på. :-)

  6. Olaf

    24 mars, 2014

    Sent svar men tackar för infon, det är alltid kul att veta lite bakgrund till testen, iaf för en som vill grotta ner sig. :)

    Artiklarna på sajten håller helt klart en hög nivå, bra jobbat med dem! :)

  7. Ivar Johansson

    24 mars, 2014

    Tack ska du ha Olaf! Det ligger många timmar bakom de flesta av mina artiklar, så det är kul att höra att de uppskattas. :-)

  8. Timmy

    4 januari, 2015

    Intressant artikel. Webbhotellet svarar för en stor del av prestandan där många faktorer inverkar såsom diskhastighet, mysql på lokal eller fjärran maskin, maskinbelastning från andra anvöndare, svarstider/routning mellan noder, upstream bandbredd, mfl.

    Vad gäller nginx har jag sett statistiska rapporter där det överträffar apache2 på statiskt innehåll men inte dynamik. Nginx lämpar sig väl för bilder men inte PHP.

    Att buffra din output vinner du sällan prestanda på, tvärtom då det dröjer innan webbläsar mottar sin första byte. Den kan således inte börja bearbeta css eller javascript medan den mottar resten av sidans innehåll. Med undantag kraftigt textinnehåll som drar nytta av gzip kompression. Tyvärr buffrar vissa webbläsare (Firefox) byteströmmen och rendererar inte sidan förrän sista byten är mottagen. Men chrome användare drar nytta av prestandan i att inte buffersamla serversidans utdata.

  9. Ivar Johansson

    4 januari, 2015

    Hej Timmy!

    Tack för din input.

    Nu rör det sig inte om något webbhotell, utan en VPS. Båda VPS:erna var från samma leverantör och hade ingen hårdvaruskillnad bortsett från storleken på minnet.

    Angående Nginx fungerar det väldigt olikt exempelvis Apache. Det är extremt effektivt när det kommer till statiskt innehåll. När det kommer till PHP finns det inga större skillnader, däremot är det generellt sätt mycket mer minneseffektivt än Apache.

    Och att buffra outputen i PHP är effektivare än att lagra all output i en variabel som sedan skrivs ut, som det gjordes innan. Att skicka iväg delar av bufferten kan ge bättre prestanda om det tar lång tid att generera sidan, men då finns det oftast bättre sätt att optimera prestandan på. Personligen föredrar jag att skicka bufferten när allt är färdiggenererat, det ger även möjligheten att cacha outputen på servern om man skulle vilja.

  10. Timmy

    5 januari, 2015

    Att lagra allt i en variabel är också en form av buffering. Jag förespråkar buffering, men det är då nyttan är större när man jobbar med templates. Men i avseendet att det laddar en sida snabbare är fel. Det tar alltid längre tid för sista byten att resa till klienten när man lagrar outputen på serversidan istället för att släppa den. I en optimal kod ska du släppa html huvudet så klienten kan läsa in stylesheets och javascript medan du bearbetar att släppa bodyn. Annars sitter klienten och rullar tummarna. :)

    Bra artikel i övrigt. :)

  11. Ivar Johansson

    5 januari, 2015

    Absolut, men på en (tillräckligt) snabb sida sparar man inte många millisekunder på att skicka sidhuvudet innan bodyn. :-) Fast är man ute efter det allra sista i prestandaväg så kan det absolut vara en lösning.

    Tack för att du tog dig tid att kommentera! Och ursäkta om jag är kortfattad, har en hel del arbete att stå i just nu.

Mejla mig: