Moderne nettlesere har fått veldig gode verktøy for å måle ytelse.
Ved å velge nettverksfanen i utviklerverktøyet kan vi se detaljer om nettverkstrafikk og tidsbruk.
I underfanen Timing
vises tiden det tar å laste en ressurs:
Dette er velkjent for de fleste utviklere. Vi kan se detaljert oversikt over hvor lang tid det tar å sende requesten, hvor lang tid det tar å vente på svar fra serveren og hvor lang tid det tar å laste ned innholdet. I dette tilfellet har vi lastet en side som består av mer eller mindre statisk HTML, så den hentes dermed relativt raskt.
¶Innhold som tar tid
I en webapplikasjon trenger vi innhold. Når applikasjonen vår spør serveren om data, gjerne via et fetch
-kall, må serveren ofte gjøre en del arbeid før den kan svare.
Den må kanskje hente data fra en database eller fra andre tjenester.
Kanskje må den også gjøre litt kverning av dataene.
Dette ser vi bare som “Waiting for server response”, hva serveren bruker tiden på er ukjent for nettleseren.
For å undersøke hva som tar tid, kan vi prøve å finne igjen requesten i logger på serversiden, eller f.eks. se i databasens oversikt over nylige spørringer. Men det er tidkrevende og tungvindt.
Her er et eksempel der vi henter data med fetch
:
Vi ser at serveren brukte 1,5 sekunder på å svare. Men vi ser ikke hvorfor.
¶Server Timing
Men hva er det utviklerverktøyet sier nederst der?
During development, you can use the Server Timing API to add insights into the server-side timing of this request.
La oss ta en titt på det!
Vi kaller samme URL på nytt:
Denne gangen vises det også detaljer om hva serveren har brukt tiden på. Vi ser at den har brukt 1 sekund på å hente data fra et api og et halvt sekund på å slå opp i databasen.
Så hvordan fikk vi foret nettleseren med denne informasjonen? Vi tar en titt på Response Headers:
Vi får altså til dette ved å sende en header med navnet Server-Timing
med en verdi som er en kommaseparert liste av målinger (metrics
).
Hver måling må ha et navn og kan også ha med tidsbruk i millisekunder (dur
) og en beskrivelse (desc
).
I dette tilfellet har vi altså 2 målinger (api
og db
), begge med både tidsbruk og beskrivelse.
Dette er en relativt ny standard, men nettleserstøtten er god. Eksempler på bruk kan du finne på MDN.
¶Sikkerhet
Da utviklerverktøyet hintet om denne muligheten, brukte den uttrykket “During development”. Det er ingenting som hindrer deg å sende denne headeren også i prod. Men det er viktig å være klar over at det er en del informasjon som kan være interessant for en angriper. Kanskje kan du sende headeren i test, men ikke prod? Eller kanskje også i prod, men bare til utvalgte brukergrupper? Kanskje er det ikke så farlig å lekke at du gjør et databaseoppslag? Det er noe du må ta stilling til selv.
¶Implementasjon på serversiden
Hvordan du kan ta tiden og lage denne headeren på serversiden, kommer veldig an på hvilket språk og eventuelt rammeverk du bruker, og er utenfor scope for denne bloggposten. Jeg har en implementasjon i Clojure, som jeg kanskje kan dele i en senere bloggpost.