edalnice.cz může být rychlejší — jak správně monitorovat a měřit rychlost načítání webových aplikací

edalnice.cz e-shop pro prodej a správu elektronických dálničních známek

Datum 1.12.2020 byl pro nás řidiče historickým dnem. Byl totiž spuštěn e-shop pro prodej elektronických dálničních známek a tím pádem se stali papírové nalepovací dálniční známky minulostí. 🎉🎉🎉

Dá se říct, že veřejnost ale i náš tým jsme netrpělivě očekávali jak spuštění dopadne. Víme, že spuštění nových aplikací vždy závisí na zavedené kultuře testování, její míře a doménové specializaci samotných testerů.

Bohužel se po spuštění objevili problémy a e-shop měl několika hodinový výpadek.

Mezitím se na twitteru objevila spousta tweetů, hodnotící spuštění a i samotnou otestovanost. Později p.Paroubek jehož firma CENDIS tento e-shop dodávala na svém twitteru přiznal, že v systému byla chyba, která nebyla dříve objevena.

V době psaní tohoto článku má tento incident snad šťastný konec. Já jsem si e-shop prošel a vyzkoušel (bez většího exploratory snažení) hlavní use cases, tedy landing page, nákup a i správa dálniční známky fungovaly na první dobrou a určitě palec nahoru 👍 p.Paroubkovi za upřímnost.

Náš tým se specializuje na performance testy a web performance testy webových aplikací a proto věta “Jedna komponenta generuje obrovské množství operací mezi frontendem a backendem, což se nám při testech neprojevilo” byla doslova fascinujícím use casem a proto jsme se na e-shop edalnice.cz zaměřili a provedli několik neinvazivních měření a to z důvodu ukázat, jak se mají webové aplikace správně testovat a měřit.

Performance testy nestačí

Výkon webových aplikací, kde se očekává zájem x tisíců a více uživatelů se běžně testují pomocí tzv. performance testů. Máme zkušenosti s rozsáhlými performance testy, jejich různou variací, ve výzbroji máme několik nástrojů a obecně lze říci, že podobným výpadkům lze předejít.

Browser je malá infrastruktura

Pro testování webových aplikací a její infrastruktury z pohledu uživatele využijeme typy testů

  • Performance testy, vytvoříme model zátěže podle předpokladu, kolik uživatelů a jak budou s aplikací pracovat
  • Funckionální E2E testy, nejčastěji skloňovaný Selenium, nebo playwright či Webdriver.io nebo vývojáři oblíbený Cypress.io. Jde o automatizované klikání v prohlížeči.
  • Browser-based performance analyzátory jako je Canarytrace, který webové aplikace funkcionálně testuje a navíc měří rychlost načítání webové aplikace (podobně jako Lighthouse či PageSpeed Insights) a navíc stahuje z browseru spoustu telemetrických dat pro analýzu webové aplikace a chování prohlížeče.

Podle tvrzení “komponenta generuje obrovské množství operací mezi frontendem a backendem, což se nám při testech neprojevilo” je problém celkem přímočarý. Performance testy a ani browser-based performance testy se buď neprovedly vůbec, nebo špatně a nebo nebylo na správné provedení dostatek času. Tohle je k vidění celkem běžně, jak přes kopírák.

Je naprosto jednoduché aplikaci nasadit do Kubernetes, ručně nebo pouze funkcionálně aplikaci oklikat, ale pod zátěží (pomocí performance testů) se může infrastruktura chovat tak, jak jsme nepředpokládali.

Performance testy testují aplikaci pouze od úrovně protokolů — vůbec neřeší performance prohlížeče, tzn. od prohlížeče směrem k infrastruktuře. Běžné funkcionální testy sice testují prohlížeč, ale nedostatečně, pouze funkcionálně. Proto pro skutečné tvrzení “Uživateli bude aplikace fungovat, správně a svižně” potřebujeme do našeho testware zařadit právě již zmiňovaný browser-based performance analyzátor Canarytrace.

Browser je malá infrastruktura

Webový prohlížeč obsahuje spoustu komponent, má i své flow jak zpracovává požadavky, má i jednu, druhou cache a další, má mnoho APIs, chová se i heuristicky, co vývojář, to aplikace, to nová výzva, pro svou práci spotřebovává prostředky typu CPU, RAM, I/O a nesmíme zapomenout na propustnost, rychlost připojení, vlákna, pluginy, prohlížeč má k dispozici několik typu logů, sám měří spoustu metrik a má i vestavěné monitorovací nástroje.

Browser není blackbox a jeho testováním se dostáváme k nejsložitějším typům testů.

Proto si musíme zapamatovat:

  • aby webová aplikace dobře fungovala, musí mít prvně k dispozici dostatek zdrojů
  • aplikaci na backendu, infrastrukturu a samotný provoz spravují specialisté, zatím co browser (malá infrastruktura), kde běží frontendová část aplikace, která se stáhne ze serveru — spravují různě zkušení uživatelé (naši zákazníci), kteří na svůj browser spravují na různě výkonných zařízeních za různých podmínek (pomalé připojení k internetu, mobilní zařízení, mnoho záložek atp.)

Zátěž infrastruktury má vliv na chování browseru

Výrazně zvýšená konzumace prostředků v browseru během zatížené infrastruktury

Málo kdo ví, ale pokud zatížíme infrastrukturu (např. pomocí performance testů) bude ovlivněna i webová aplikace stažená a spuštěná v prohlížeči.

Na obrázku vidíme graf s metrikami TTFB, RT a LoadEventEnd (více zelený graf) naměřený v prohlížeči při stahování img, js, css, fontů, fetch requestů atp. Druhý graf ukazuje množství spotřebované paměti v prohlížeči.
Zároveň si můžete všimnout “klidného stavu” s nízkými hodnotami metrik a zároveň stavu, kdy metriky doslova vystřelili vzhůru a to několika násobně.

Toto je graf naměřený u našeho klienta a v době zvýšení metrik probíhaly performance testy.
Performance testy podle NFR dopadly na výbornou, ale měření v prohlížeči nedopadlo ani trochu dobře.

Takže, když to shrnu — provozovat pouze velké performance testy (jmeter, k6.io, gatling, atp) bez web performance testů (měření nefunkcionálních metrik v prohlížeči) je naprosto špatně. Rozhodovat se na základě výsledků pouze z performance testů o tom, jestli release může jít ven je šlápnutí do prázdna.

Laboratoře pro měření rychlosti načítání webových aplikací

V rámci měření rychlosti webových aplikací se musíme seznámit s tím, jak prohlížeč funguje a seznámíme se i s novými metrikami.

Rychlost načítání webové aplikace můžeme měřit pomocí eventů
Stejně tak můžeme rychlost načítání webové aplikace pomocí metrik

Mnozí z vás jistě znají v Google Chrome vestavěné prostředí DevTools a nástroj pro měření rychlosti načítání webových aplikací Lighthouse nebo online laboratoře PageSpeed Insights či SpeedCurve a tyto nástroje nám reportují rychlost a kvalitu načtené webové aplikace pomocí metrik:

Performance Score

Skóre performance měřené stránky, které se skládá ze syntetických metrik přičemž každá z nich je posuzována podle vah. Ve verzi Lighthouse 6 došlo ke změně vah, protože tým okolo Lighthouse stále provádí výzkum a bere v potaz feedbacky od uživatelů.

(FCP) First Contentful Paint

  • (první vykreslení obsahu) udává okamžik vykreslení prvního textu nebo obrázku

(LCP) Largest Contentful Paint

  • (vykreslení největšího obsahu) udává čas, kdy byl vykreslen největší text nebo obrázek ve viewportu uživatele.

(SI) Speed Index

  • Metrika Speed Index ukazuje, jak rychle se viditelně vyplní obsah stránky.

(TTI) Time to Interactive

(doba do interaktivity) udává, jak dlouho trvá, než stránka začne být plně interaktivní. Označuje okamžik, kdy je stránka spolehlivě interaktivní, tzn. v hlavním vlákně nejsou dlouhé po sobě jdoucí tásky alespoň po dobu 5s.

(TBT) Total Blocking TIme

Součet všech dob uvedený v milisekundách mezi FCP (prvním vykreslením obsahu) a TTI (dobou do interaktivity), u nichž délka úlohy překročila 50 ms a hlavní vlákno není schopné reagovat na vstupy uživatele = hlavní vlákno je blokováno.

(CLS) Cumulative Layout Shift

Metrika Cumulative Layout Shift (kumulativní změna rozvržení) měří přesuny viditelných prvků v zobrazované oblasti / view portu uživatele. CLS pomáhá identifikovat, jak často dochází k neočekávané změně rozložení prvků na stránce.

Core Web Vitals

Web Vitals je iniciativa společnosti Google, jejímž cílem je poskytnout signály ke zlepšení kvality webu. Cílem Core Web Vitals je zaměření se na metriky na kterých záleží nejvíce a jednodušší formou tak poukázat na aktuální stav web performance.

Metriky, které tvoří Core Web Vitals se budou časem vyvíjet. Aktuální sada pro rok 2020 se zaměřuje na tři aspekty uživatelské zkušenosti — načítání, interaktivitu a vizuální stabilitu — a zahrnuje následující metriky.

Podívejte se na ukázkový report stránky https://edalnice.cz/jednoduchy-nakup/index.html vygenerovaný z Lighthouse.

Chyby při měření

Jen v České republice je mnoho poradců či konzultantů, kteří vám nabídnou své služby v oblasti měření rychlosti webových aplikací, zpravidla neberou v potaz dvě nejdůležitější prerekvizity pro správné měření a úplně v pohodě vám doporučí využívat vestavěný Lighthouse, PageSpeed Insights nebo SpeedCurve.

Používání těchto nástrojů není špatně ale stejně tak jako velké performance testy vyžadují specifické podmínky pro úspěšné, opakovatelné a průkazné měření, tak i v oblasti měření výkonu webových aplikací se musíme držet pravidel aby jsme se nehonili za něčím, co třeba neexistuje nebo nesprávně provedené měření nám nezakrylo vážný problém.

PageSpeed Insights vs Lighthouse z Liberce

Na obrázku vidíte v rámci 5 minut opakované měření stránky https://developers.google.com/speed/pagespeed/insights/ ze služby PageSpeed Insights (vlevo) a pomocí Lighthouse na silným iMacu v čistém browseru z lokace Liberec (vpravo).

Myslíte, že pro české e-shopy je správně měřit rychlost načítání někde ze zahraničního regionu? Na obrázku je vidět opakovaný propastný rozdíl v metrice Performance Score (40 vs 65 a vyšší číslo znamená lepší). Samozřejmě to způsobuje například rozdílná latence, která má vliv na některé metriky.

Co se vám ale může hodit jsou informace z auditu, které nejsou úplně závislé na tom, odkud měříte.

Ptejte se svého konzultanta pro měření rychlosti načítání

  • Odkud měření probíhá
  • Jaká je latence
  • Které metriky mohou být ovlivněny zhoršenou latencí

Častěji znamená přesněji a hlavně pod parou

Dalším opomíjeným problémem je četnost měření. Stačí vám změřit rychlost načítání jednou denně?

SpeedCurve a zobrazení výsledku metriky po jednom dni

U auta dost často nekoukáme na okamžitou spotřebu, ale spíše na tu dlouhodobou. Pokud budeme i takto nahlížet na metriky rychlosti načítání webových aplikací, tak koukáme na dlouhodobý trend, který ale může zakrývat peklo, kterým si uživatelé mohou procházet.

Canarytrace Smoke Pro a měření Web Vitals a dalších telemetrických dat každé 3 minuty

Zatím co dlouhodobý trend nás chlácholí, tak (okamžitá spotřeba) nás zamrazí. Právě se díváte měření produkce — je to část live reportu z Canarytrace a v grafech jsou zobrazeny notoricky známé metriky — stejné, které reportuje Lighthouse a další online laboratoře, které Lighthouse pro svá měření využívají. Rozdíl je ale v tom, že Canarytrace provádí plnohodnotný audit každé 3 minuty 24/7 a to je zásadní!

Graf z měření opět pochází od našeho klienta, z produkce, kde hlídkuje Canarytrace a vidíme opět klidné období a i období, které je pod náporem uživatelů.

A jsme opět u toho. Nápor uživatelů = zatížená infrastruktura = dopad na frontendovou aplikaci = dopad na uživatele.

Canarytrace Smoke Pro a rozpad na Desktop a Mobile

Z posledních třech obrázků si můžeme bezpečně odnést pár pravidel.

  • Měřit velmi často (dle našich dvouletých zkušeností je ideální rotace monitor scriptu nad webovou aplikací každé 3 minuty)
  • Měřit celý den, celý víkend, celý týden i celý měsíc. Uvidíme patterny, uvidíme reál.
  • Měřit hlavně když je infrastruktura pod zátěží. To jsou reálné podmínky a právě za těchto podmínek chceme znát reál.
  • Provozovat performance testy bez web performance testů nemá moc smysl.
  • Měřit hlavně nad plnohodnotným browserem, který je zafreezovaný, izolovaný (měření nemůže z venčí nic ovlivnit) a má dostatek zdrojů.

Canarytrace

Pro úspěšné zvládnutí disciplíny web performance testování potřebujeme

  • měřit z pohledu uživatele
  • měřit velmi často
  • během provozní zátěže či performance testů
  • musíme emulovat různé zařízení a typ připojení
  • monitor script musí mít dostatek prostředků, musí být izolovaný a nesmí jej nic ovlivnit
  • aktuální naměřené metriky a další telemetrie se musí live logovat, aby jsme na incidenty či změnu stavu browseru dokázali co nejdříve reagovat

Canarytrace je plug’n’play stack pro monitoring dostupnosti webových aplikací z pohledu uživatele, měří rychlost načítání a pro analýzu chování webového prohlížeče.

Architektura Canarytrace Smoke Pro

Canarytrace je dnes již ve třetí verzi, je k dispozici v několika edicích včetně komunitních a byl navržen pro specifický úkol kterým je testování webových aplikací a měření rychlostních metrik, které browser nabízí.

Hlídkuje na produkcích ale je i sparring partnerem pro frontendové vývojáře a performance testery na nižších prostředích.

Canarytrace je distribuován formou docker images, nasazuje se pomocí připraveného deployment skriptu do Kubernetes či OpenShift a výsledky průběžně loguje do Elasticsearch stacku.

Pro nastavení Elasticsearch a Kibanu nahrajeme vizualizace společně s dashboardy pomocí připraveného Canarytrace Installeru.

Pojďme testovat

Než se pustíme do testování a měření, připravíme si deployment script do kterého nadefinujeme cílové adresy oddělené středníkem, nastavíme prostředky, profil měření tzn. desktop či mobile a cestu, kde běží Elasticsearch.

apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: smoke-edalnice-desktop
spec:
concurrencyPolicy: Replace
failedJobsHistoryLimit: 2
schedule: "*/3 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: canary
image: quay.io/canarytrace/smoke-pro:2.15.6
env:
- name: BASE_URL
value: "https://edalnice.cz;https://edalnice.cz/jednoduchy-nakup/index.html;https://edalnice.cz/sprava-zakoupene-znamky/index.html"
- name: SMOKE
value: allow
- name: ELASTIC_CLUSTER
value: "https://XXX.europe-west3.gcp.cloud.es.io:9243"
- name: ELASTIC_HTTP_AUTH
value: "elastic:XXX"
- name: AT_DRIVER_HOST_NAME
value: "localhost"
- name: PT_AUDIT
value: allow
- name: PT_AUDIT_THROTTLING
value: 'desktopDense4G'
resources:
requests:
memory: "300Mi"
cpu: "200m"
limits:
memory: "400Mi"
cpu: "300m"
imagePullPolicy: "Always"
- name: selenium
image: selenium/standalone-chrome:3.141.59-20200730
ports:
- containerPort: 4444
resources:
requests:
memory: "3000Mi"
cpu: "1200m"
limits:
memory: "4000Mi"
cpu: "3000m"
imagePullPolicy: "IfNotPresent"
volumeMounts:
- mountPath: "/dev/shm"
name: "dshm"
livenessProbe:
httpGet:
path: /wd/hub
port: 4444
initialDelaySeconds: 10
timeoutSeconds: 5
readinessProbe:
httpGet:
path: /wd/hub
port: 4444
initialDelaySeconds: 10
timeoutSeconds: 5
restartPolicy: "Never"
volumes:
- name: "dshm"
emptyDir:
medium: "Memory"
imagePullSecrets:
- name: canarytrace-labs-pull-secret

Ukázka, jak vypadá konfigurace profilu pro simulaci desktopu, tester zvolí profil pouze použitím jeho názvudesktopDense4G viz výše v CronJobu.

{
onlyCategories: ['performance'],
maxWaitForFcp: 30 * 1000,
maxWaitForLoad: 45 * 1000,
throttlingMethod: 'simulate',
internalDisableDeviceScreenEmulation: false,
throttling: {
rttMs: 40,
throughputKbps: 10 * 1024,
cpuSlowdownMultiplier: 1,
requestLatencyMs: 0,
downloadThroughputKbps: 0,
uploadThroughputKbps: 0,
}
}

a v posledním kroku CronJob pošleme do Kubernetes a tím je monitoring spuštěn.

Výsledky

Prvně jsem se zaměřil na rychlost načítání resources (jako jsou requesty, která stránka volá), zaměřil jsem se na serverové metriky TTFB, ResponseTime a na metriku LoadEventEnd, kterou poskytuje browser.

Tyto informace vyčítáme z dashboardu Canarytrace Smoke Overview

Zkoukneme delší časový úsek, třeba 7 dní a hledáme víkendové patterny, peaky přes den atp.

Monitorovali jsme stránky https://edalnice.cz, https://edalnice.cz/sprava-zakoupene-znamky/index.html a https://edalnice.cz/jednoduchy-nakup/index.html přičemž poslední stránka byla na incidenty nejzajímavější.

Na těchto rychlostních metrikách (TTFB, ResponseTime a Load Event End) je vidět sedmidenní průběh načítání všech requestů, který si e-shop do prohlížeče stahuje.

Již z tohoto high-level pohledu je vidět, že monitorovat či měřit webové aplikace nelze jen jednou či 2x denně. Zároveň je pěkně vidět i to, které dny byla stránka na URL https://edalnice.cz/jednoduchy-nakup/index.html pomalejší nebo rychlejší. Zároveň vidíme, že byla dostupná každé 3 minuty v rámci sedmi dnů, kdy běžel monitoring.

Dashboard Canarytrace Smoke Overview porovnáváme s Canarytrace Performance Audit a hledám časové úseky v klidu a pod zátěží.

Dec 2, 2020 @ 21:26:19.094 — Resources responses metrics
Dec 2, 2020 @ 21:26:19.094 — WebVitals metrics

Horní grafy ukazují, že díky velmi častému měření vidíme detail i přes den a dále že, metrika TTFB nemusí mít vliv na Web Vitals metriky. Dost často záleží jestli jde na request na náš server a je blokující pro Main Thread nebo jestli jde o request třetích stran.

LoadEventEnd peak, je ale bez významný
Došlo ke zvýšení TTI a počty tasku v Main Thread, které se provádějí déle jak 50ms, 100ms a 500ms
Skokové zvýšení metrik FCI a TTI, zvýšení počtů requestů stahovných .js a .css souborů a fontů

Na stránce pro nákup dálniční známky došlo pravděpodobně k releasu nové verze. Pomocí LoadEventEnd byl zaznamenán pouze peak v daný čas, zatím co ve WebVitals trvalé zhoršení metrik.

Došlo ke zhoršení metrik FCI, TTI a k navýšení počtu volaných requestů. Tyto metriky napovídají na zhoršenou performance Javascriptu, nebo jak napovídá zvýšený počet requestů, tak trpí spolehlivost první interaktivity.

Rozdělení na desktop a mobil.

Monitor scripty a performance audit na každou URL běží paralelně, ale v různém nastavení simulace.

desktopDense4G a mobileSlow4G

Desktop https://edalnice.cz/jednoduchy-nakup/index.html

Mobile https://edalnice.cz/jednoduchy-nakup/index.html

Z rozdílů mezi nastavenými simulacemi pro desktop a mobil můžete pozorovat rozdíly mezi metrikami Core Web Vitals a vždy v druhém grafu je vidět rozdíl mezi metrikami TTFB a FCP. Tyto metriky říkají, kdy měl server požadavek zpracovaný a začal vracet odpověď a kdy začal browser poprvé kreslit.

Kibana zobrazuje spoustu dalších informací z monitoringu a měření, jako jsou například kompletní responses s hlavičkami, requesty, performance entries, spotřebovaná paměť v browseru, míra nevyužitých .js a .css stažených do prohlížeče a další.

Canarytrace během měření každé URL stáhne několik MB dat z prohlížeče a uloží k analýze do Elasticsearch

Z pozorování

  • Porovnavat a hledat incidenty několik dní zpětne může být složité a zpětně nemusí byt k dispozici detail. Je lepší přístup ‘monitoring’ než ‘zpětná investigace’ to znamená, nastavit si thresholdy na metriky a jejich kombinace a nechat si zasílat alerty, které je dobré přesměrovat na tým k investigaci.
  • Pokud jsou incidenty ve stejný čas a na různých URI, je možné že se jedná o infrastrukturní problém
  • e-shop by si zasloužil optimalizaci počty requestů a nestahovat do browseru javascript a css, který se ani nepoužije.
  • optimalizovat blokující zpracovávání css a javascriptu, například přidat defer při vkládání javascriptu do stránky.
  • snížit souhrnný čas načítání a velikosti souborů
  • nastavit u text-based zdrojů jakou jsou css a javascript br nebo gzip kompresi a switchnout na protokol HTTP/2

Doporučení závěrem

  • Performance testy a Web Performance testy patří k sobě.
  • Zásadně nepovažujte měření na localhostu za správné.
  • Simulujte různá prostředí (mobil, desktop) a různé podmínky (rychlejší či pomalejší připojení k internetu nebo méně prostředků).
  • Online laboratoře pro měření rychlosti načítání berte spíše orientačně.
  • Měřte velmi často.
  • Nastavte si thresholdy a věnujte se tomu, co se děje v browseru

Nasaďte Canarytrace

Canarytrace is a Plug’n’Play stack for testing and monitoring your web application from user perspective. https://canarytrace.com/

Canarytrace is a Plug’n’Play stack for testing and monitoring your web application from user perspective. https://canarytrace.com/