W obecnym świecie – nastawionym na digitalizację – każda z firm oferujących swoje produkty za pośrednictwem sieci zdaje sobie sprawę z tego, że atrakcyjna aplikacja służąca do sprzedaży przez internet jest niezbędna do generowania przychodu.
Cyfrowy postęp wymusza już nie tylko poprawne działanie aplikacji w kontekście operacyjnym lub funkcjonalnym (czyli żeby aplikacja była dostępna i pozwalała robić użytkownikowi zakupy), ale równie istotna staje się szybkości jej działania.
Wyniki badań pokazują, że prawie 80% użytkowników jest gotowych porzucić zakup, jeśli napotkają dowolny problem ze stroną internetową. Dodatkowo aż 3 na 4 użytkowników wybrało właśnie szybkość działania strony jako główne z 5 kryteriów działania stron, podczas przeglądania treści w Internecie. Wszystkie te zależności przekładają się na mniejszy o 7% poziom konwersji (liczbę sfinalizowanych zakupów w stosunku do odwiedzin), gdy strona ładuje się o 1 sekundę dłużej!
Nowe wskaźniki od Google
Jak zatem zdefiniować ową szybkość działania stron internetowych lub aplikacji? Czy da się ją zmierzyć i porównać?
Określenie szybkości działania, zarówno sklepu internetowego, jak i dowolnej aplikacji czy strony, jest trudne, jednak możliwe do wykonania, pomimo tego, że odczucie szybkości jest względne.
Google rozpoczęło inicjatywę mającą na celu wprowadzenie wskaźników jakości dostarczanych treści. Obok „zwykłych” wskaźników, które określamy w celu zapewnienia odpowiednich zasobów do obsługi wielu użytkowników jednocześnie w trybie ciągłym lub szczytowym, cyfrowy gigant wprowadza nowe wskaźniki, mogące posłużyć do zdefiniowania ogólnej szybkości strony.
3 rodzaje testów dopasowanych do okoliczności
W e-commerce możemy wyodrębnić 3 podstawowe przypadki użycia, z którymi nasi potencjalni klienci będą mieli do czynienia. My natomiast musimy znać nasze możliwości w celu odpowiednich reakcji. Są to przede wszystkim:
- Stress testy – nagłe „zalanie” systemu użytkownikami (black friday, cyber monday, błąd cenowy, „reddit effect”).
- Load testy – ciągła, wzmożona aktywność użytkowników (wszelkiego rodzaju święta, dłuższe okresy promocyjne).
- UX-performance testy – zwykła, spodziewana aktywność (codzienna aktywność bez szczególnych kampanii marketingowych).
Stress i load testy są opisywane w wielu systemach. W e-commerce ich idea jest identyczna. W dużym uproszczeniu: testy mają dać odpowiedź, czy i jak system zachowuje sprawność w zależności od natężenia użytkowników. Następnie chcemy ustalić graniczne wartości, które będziemy monitorować podczas działania systemu, by reagować z wyprzedzeniem w ramach możliwości.
UX-performance testy
Jeśli chodzi o ostatni zestaw testów, nazwanych roboczo testami „UX-performance”, mamy na myśli wszystkie testy, które pozwolą nam zebrać metryki zorientowane na odczucia użytkowników.
Do podstawowych wskaźników należą:
- Largest Contentful Paint (LCP) – oznaczający czas załadowania największego wizualnie (w kontekście rozdzielczości) elementu strony.
- Cumulative Layout Shift (CLS) – wskazujący wynik niezamierzonego przesunięcia zawartości w obszarze strony.
- First Input Delay (FCP) – określający czas, po którym strona staje się responsywna dla użytkownika.
Pozycjonowanie stron ze względu na szybkość działania
Google, jako pionier definiowania metryk, od roku 2020 testuje strony w celu uzyskania wyżej wymienionych parametrów, a następnie uwzględnienia je przy pozycjonowaniu danej strony. Wyżej pozycjonowane strony przyciągną większą liczbę odwiedzających. Jednocześnie – wyżej pozycjonowane strony muszą działać odpowiednio szybko, przez co współczynnik konwersji (przełożenie liczby odwiedzających na klientów) będzie na wysokim poziomie.
Jest to więc kolejna zależność między przychodem a szybkością działania strony.
Zbieranie metryk
Skoro poznaliśmy przyczyny mierzenia szybkości oraz metryki, które potrzebujemy określić, aby zdefiniować naszą stronę pod względem szybkości, pojawia się pytanie: jak zebrać odpowiednie metryki?
Z odpowiedzią śpieszy samo Google, ale nie tylko. Na rynku jest wiele narzędzi pozwalających na zbieranie metryk określonych jako Core Web Vitals.
Do podstawowych narzędzi należą:
- Google Lighthouse,
- Google PageSpeed Insights,
- WebPageTest.
Istnieje również wiele narzędzi, które wykorzystują kombinację wyżej wymienionych lub opakowanych w inny interfejs graficzny. Niemniej wszystkie służą temu samemu celowi. Oprócz metryk, musimy też wziąć pod uwagę kilka innych czynników, które będą miały wpływ na odczucia potencjalnego klienta.
Są nimi:
- Wydajność urządzenia do przeglądania.
- Przepustowość łącza internetowego, z którego korzysta.
Narzędzia do testowania wydajności UX
W przypadku testowania wydajności UX stron statycznych wybór narzędzia nie stanowi większego problemu. Naturalną i popularną opcją, ze względu na swoją stabilność jak i prostotę użycia, będzie Google Lighthouse.
WebPageTest
Jednak, kiedy zależy nam na odwzorowaniu ruchu użytkownika po aplikacji, to zakres dostępnych narzędzi pozwalających obsłużyć ten ruch jest znacznie mniejszy. Możemy skorzystać z WebPageTest (WPT), lecz skrypty napisane do niego mają pewne ograniczenia oraz odbiegają znacznie od znanych i przyjętych standardów.
WPT używa utworzonych w ramach narzędzia keywordów, które odpowiadają poszczególnym akcjom użytkownika. W związku z tym problematyczne będzie utworzenie dużej bazy scenariuszy testowych łatwych w utrzymaniu. Przykład kodu skryptu WebPageTest przechodzącego logowanie na stronie.
logData 0
// bring up the login screen
navigate http://webmail.aol.com
logData 1
// log in
setValue name=loginId [email protected]
setValue name=password somepassword
submitForm name=AOLLoginForm
Chrome Devtools Protocol
Niestety, nie zawsze ograniczona ilość akcji, jaką WPT oferuje, jest wystarczająca do osiągnięcia zamierzonego rezultatu. Możemy użyć również frameworków do automatyzacji testów opartych na wykorzystaniu Chrome Devtools Protocol (CDP).
Narzędzie różni się od znanego WebDriver protokołu tym, że test jest bezpośrednio uruchamiany w przeglądarce Chrome, więc bez problemu można korzystać ze wszystkich „narzędzi deweloperskich” dostarczonych z przeglądarką.
Wykorzystanie Webdriver.IO
Wśród popularnych rozwiązań wykorzystujących CDP znajdziemy Webdriver.IO (WDIO), który poza możliwością działania z WebDriver protokołem, posiada możliwość pracy z CDP.
W celu skorzystania z możliwości CDP musimy zainstalować odpowiedni pakiet i przestawić WDIO w tryb 'devtools’. Da nam to możliwość użycia CDP nie tylko do sterowania aplikacją, ale także zbierania metryk. Pełne metryki są dostępne za pomocą wywołania jednej metody:
browser.getMetrics()
Natomiast ogólny wynik wydajności proponowany przez Google pobierzemy za pomocą:
browser.getPerformanceScore()
Główną korzyścią płynącą z wykorzystania Webdriver.IO w trybie devtools jest możliwość ponownego użycia istniejących testów do sprawdzenia wydajności. Testy te mogą być wcześniej napisane w trybie korzystającym z Selenium, ale do testów wydajnościowych potrzebujemy drugiej konfiguracji z ustawiony serwisem devtools.
Również dostarczone API w celu pobrania metryk jest proste i intuicyjne. Dzięki temu można niskim kosztem rozszerzyć możliwość weryfikowania naszego produktu.
Jednak ma ono też wady. Główną z nich jest drugorzędne spojrzenie społeczności rozwijającej framework na ten serwis. Może to skutkować opóźnieniami w dodawaniu nowych funkcjonalności, z jakich można korzystać.
- Dla przykładu: w jednej z aktualizacji Lighthouse dodał nową metrykę do Core Web Vitals. Jednak zanim ta metryka była obsługiwana przez Webdriver.IO minęło kilka miesięcy.
Wykorzystanie Puppeteer i Lighthouse
Z tego powodu warto rozważyć uproszczenie zależności i korzystanie bezpośrednio z Puppeteer i Lighthouse. Od wersji 9 paczki Lighthouse, jest to rozwiązanie zalecane przez Google.
Przykład kodu służący prostemu wygenerowaniu raportu ze strony example.com w takim podejściu wygląda następująco:
import {writeFileSync} from 'fs';
import puppeteer from 'puppeteer';
import lighthouse from 'lighthouse';
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
const flow = await lighthouse.startFlow(page);
// Navigate with a URL
await flow.navigate('https://example-navigation.com');
// Navigate with a callback function
await flow.navigate(async () => {
await page.click('button');
});
await browser.close();
writeFileSync('report.html', flow.generateReport());
})()
Na przykładzie kodu wyżej widać, że do obsługi przeglądarki wykorzystywany jest Puppeteer, ale do zbierania metryk korzysta się bezpośrednio z paczki Lighthouse. Dzięki temu dany projekt jest na bieżąco ze wszystkimi KPI sprawdzającymi wydajność stron internetowych oraz dużo szybciej korzysta z nowości wprowadzanych w Lighthouse. To ważne, gdyż w wersji 9 jest ich sporo.
Nowości w Lighthouse
Jeśli chodzo o zmiany, to między innymi raportowanie przestało ograniczać się do sprawdzania wczytywania strony (Navigation), ale możliwe jest weryfikowanie okresu między interakcjami (Timespan) oraz stan strony w stosunku do norm związanych z wyglądem i dostępnością (Snapshot).
Interakcja użytkownika z aplikacją
We wspomnianym już przykładzie pokazano zebranie danych dotyczących nawigacji. Podczas wczytywania strony jest przeprowadzany zestaw testów sprawdzających, jak radzi sobie ona w różnych warunkach.
Przykład kodu realizującego interakcję użytkownika z aplikacją wygląda następująco:
import {writeFileSync} from 'fs';
import puppeteer from 'puppeteer';
import lighthouse from 'lighthouse';
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
const flow = await lighthouse.startFlow(page);
await page.goto('https://example-login.com');
// Timespan for login
await flow.beginTimespan();
await page.type('#username', 'Test');
await page.type('#password', Pa$w0rd');
await page.click('#login');
await page.waitForSelector('#menu');
await flow.endTimespan();
await browser.close();
writeFileSync('report.html', flow.generateReport());
})()
We fragmencie kodu przedstawionym powyżej, wykorzystujemy timespan. Używając tego mechanizmu, musimy być już na jakiejś stronie internetowej. Jeżeli nie przeszliśmy do niej poprzez:
await flow.navigate(adres-strony)
to należy zrobić to za pomocą:
await page.goto(adres-strony)
Następnie, dla interesujących nas akcji zaczynamy sprawdzanie timespanu, poprzez:
await flow.beginTimespan()
i po ich wykonaniu kończymy zbieranie metryk dzięki:
await flow.endTimespan()
Musimy pamiętać o tym, by akcje sprawdzane były pojedynczą, w miarę krótką sekwencją oraz timespan powinien być zakończony po jakiś oczekiwaniu.
Chrome Devtools Protocol umożliwia też czekanie na response z requestów wysłanych przez przeglądarkę, co upraszcza znalezienie odpowiedniego czynnika pozwalającego załadować stronę.
… imports
(async () => {
… init puppeteer and lighthouse and navigate
await page.click('#menu');
await flow.snapshot();
… close browser and generate report
})()
Różnice między snapshotem a timespanem
Na podstawie powyższego i wcześniej omówionego przykładu możemy zauważyć niewielką różnicę między snapshotem i timespanem w przygotowaniach do ich wykonania. Jednak walidują one inne rzeczy.
O ile timespan chce zmierzyć, jak testowana aplikacja (aplication under test) zachowuje się w czasie, tak snapshot dokonuje zrzutu strony w danym stanie i weryfikuje ją pod kątem oceny statycznej, czyli dostępności jak i designu.
Kilka słów na koniec
Jak widać, jest to całkiem spory zestaw narzędzi, dzięki któremu weryfikacja wydajności stron może wejść na wyższy poziom, ale prawdziwą ich wartość można odkryć dopiero łącząc je.
Załóżmy, że chcemy przetestować wydajność internetowej wyszukiwarki. Zaczynając od sprawdzenia parametrów podczas ładowania strony, przejdziemy do zmierzenia, jak zachowuje się ona w czasie od wpisania wyszukiwanego hasła do znalezienia wyników oraz jak wygląda ze znalezionymi wynikami. Przykład implementacji takiego przypadku możemy zobaczyć w kodzie poniżej:
… imports
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
const flow = await lighthouse.startFlow(page);
// Navigate
await flow.navigate('https://example-search-engine.com');
// Timespan
await flow.beginTimespan();
await page.type('#search-field', 'Sweet cat');
await page.click('#submit');
await page.waitForSelector('#results');
await flow.endTimespan();
// Snapshot
await flow.snapshot();
await browser.close();
writeFileSync('report.html', flow.generateReport());
})()
Jak możemy zauważyć, podmieniając metodę przejścia na stronę internetową, otaczając ważne dla nas akcje timespanem i robiąc snapshota po nich, mamy możliwość stworzyć nowe testy wykorzystując powszechnie znane narzędzia.
Podsumowując, nie ważne z jakiego frameworku czy narzędzia skorzystamy, żeby zebrać odpowiednie metryki, UX-performance jest ważny dla użytkownika końcowego i od niego może zależeć powodzenie produktu.
Dlatego warto rozważyć dodanie do swoich testów regresji testowanie sprawdzające ten rodzaj wydajności.
Świetny tekst panowie!
Dzięki wielkie za spory kawałek wiedzy 🙂