Jak przetestować szybkość strony www z Webpagetest API i Golang
Środa, 18 Wrz, 2019Mimo coraz szerszego dostępu do szybkich łącz internetowych jednym z najważniejszych elementów podczas budowania i utrzymywania stron www są testy wydajności (szybkości ładowania stron).
Na rynku jest wiele dostępnych darmowych narzędzi do testowania wydajności stron www. Do najbardziej znanych należą: Google Lighthouse, GTMatrix oraz Webpagetest. Podczas testowania szybkości wczytywania stron w mojej pracy korzystam z każdego z nich w zależności od potrzeby, ale najczęściej testuję strony przy użyciu Webpagetest ze względu na swoją prostotę użycia i informacje, które dostarcza. Daje on możliwość przetestowania strony z różnych miejsc na świecie, emulację przeglądarek, rodzajów połączenia sieciowego oraz urządzeń mobilnych.
W bardzo prosty sposób możemy przetestować wydajność strony www wchodząc na https://www.webpagetest.org/, wpisujemy adres naszej strony, ustawiamy parametry i klikamy “start test”. Po paru sekundach lub minutach (w zależności ile osób przed nami uruchamia test z tej samej lokalizacji) wyświetlają nam się wyniki.
Prosty program w Golang do dekodowania pliku JSON z Webpagetest
No dobrze, a co jeśli chcemy przetestować kilkadziesiąt różnych stron www (lub podstron)? Ręczne wpisywanie adresów www wydaje się mało wydajne :) Z pomocą przychodzi nam Webpagetest API za pomocą którego możemy wykonać za darmo ponad 200 testów dziennie!
Nim zajmiemy się uruchamianiem testów i pobieraniem informacji z API spróbujmy stworzyć prosty program w Go, który będzie wczytywał plik JSON z dysku, dekodował informację i wypisywał wartości na ekranie.
W pierwszej kolejność przetestujemy naszą stronę bezpośrednio na https://www.webpagetest.org/, wpisujemy URL naszej strony, czyli dla tego bloga: https://www.natkart.com/ i ustawiamy wymagane parametry.
Świetnie, teraz czas aby pobrać nasze wyniki jako plik JSON.
Możemy to zrobić na kilka sposobów, ale najłatwiej będzie jeśli na końcu naszego URL dopiszemy ?f=json
https://www.webpagetest.org/result/190917_9H_55b95a0370d9c1a99c7f498128d65d9d/?f=json
lub używając ID naszego testu:
http://www.webpagetest.org/jsonResult.php?test=190917_9H_55b95a0370d9c1a99c7f498128d65d9d
Otwarty kod zapisujemy jako plik JSON na naszym dysku, najlepiej dla wygody w lokalizacji, w której stworzyliśmy plik main.go
Kolejnym krokiem będzie napisanie prostego programu w Golang za pomocą którego otworzymy zapisany wcześniej plik JSON.
package main
import (
"fmt"
"log"
"os"
)
func main() {
file, err := os.Open("data.json")
defer file.Close()
if err != nil {
log.Fatal(err)
}
fmt.Println("File:", file.Name(), "successfully opened.")
}
W pliku JSON wygenerowanego z Webpagetest znajduje się olbrzymia ilość danych. Musimy podjąć decyzję jakie informacje są dla nas najważniejsze i co chcielibyśmy wyświetlić na ekranie. W poniższym przykładzie pobierzemy z pliku JSON URL naszej strony dla której wykonaliśmy test, lokalizację z jakiej test został wykonany, rodzaj połączenia jaki został wykorzystany podczas testu, ile razy kolejno wykonaliśmy nasz test na podanym URL oraz medianę dla czterech wskaźników: Load Time, Time to First Byte, DOM elements oraz Requests. W naszym przypadku mamy tylko kilka wskaźników, którymi jesteśmy zainteresowani więc w prosty sposób możemy utworzyć strukturę wymaganą dla naszego pliku JSON:
type WptJson struct {
Data struct {
TestUrl string `json:"testUrl"`
Location string `json:"location"`
Connectivity string `json:"connectivity"`
TestRuns int `json:"testRuns"`
Median struct {
FirstView struct {
LoadTime float64 `json:"loadTime"`
TTFB float64 `json:"TTFB"`
DomElements int `json:"domElements"`
RequestsFull int `json:"requestsFull"`
}
}
}
}
Następnie tworzymy zmienną posiadająca naszą strukturę, dekodujemy nasz JSON za pomocą Unmarshal i wypisujemy na ekranie wartości pól naszej zmiennej. Poniżej cały kod programu:
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"os"
)
type WptJson struct {
Data struct {
TestUrl string `json:"testUrl"`
Location string `json:"location"`
Connectivity string `json:"connectivity"`
TestRuns int `json:"testRuns"`
Median struct {
FirstView struct {
LoadTime float64 `json:"loadTime"`
TTFB float64 `json:"TTFB"`
DomElements int `json:"domElements"`
RequestsFull int `json:"requestsFull"`
}
}
}
}
func main() {
file, err := os.Open("data.json")
defer file.Close()
if err != nil {
log.Fatal(err)
}
fmt.Println("\nFile:", file.Name(), "successfully opened.")
var perfResults WptJson
byteJSON, _ := ioutil.ReadAll(file)
err = json.Unmarshal(byteJSON, &perfResults)
if err != nil {
log.Fatal(err)
}
fmt.Println("\nTested URL: \t\t", perfResults.Data.TestUrl)
fmt.Println("Test location: \t\t", perfResults.Data.Location)
fmt.Println("Type of connection: \t", perfResults.Data.Connectivity)
fmt.Println("Number of tests: \t", perfResults.Data.TestRuns)
fmt.Println("\nPerformance Results (Median Run)\n")
fmt.Println("Page load time: \t", perfResults.Data.Median.FirstView.LoadTime/1000, "s")
fmt.Println("First byte: \t\t", perfResults.Data.Median.FirstView.TTFB/1000, "s")
fmt.Println("DOM elements: \t\t", perfResults.Data.Median.FirstView.DomElements)
fmt.Println("Requests: \t\t", perfResults.Data.Median.FirstView.RequestsFull)
}
Po uruchomieniu programu powinniśmy zobaczyć coś podobnego do poniższego wydruku z wiersza poleceń:
File: data.json successfully opened.
Tested URL: https://www.natkart.com/
Test location: Maidenhead:Chrome
Type of connection: Cable
Number of tests: 3
Performance Results (Median Run)
Page load time: 0.969 s
First byte: 0.244 s
DOM elements: 109
Requests: 14
Ciąg dalszy nastąpi…