past jednoho score
Lighthouse je užitečný, pouštím ho pořád, a stejně si myslím, že mu týmy věří až moc. Čistých 95 bodů na MacBooku Pro přes rychlou lokální síť vám skoro nic neřekne o zákazníkovi se střední řadou Samsungu, na rozpadávající se 4G, který otevírá pricing page v in-app browseru a k tomu má otevřených dalších šest tabů, co se perou o paměť. Tenhle zákazník odpadne. Ne ten, který žije ve vašem syntetickém reportu.
Horší problém je, že Lighthouse smrskne performance do jednoho hezkého čísla. Pro product lidi je to neodolatelné, jedno číslo se krásně vejde do sprint goalu, dashboardu i slidů pro board. Jedno číslo uklidňuje. A většinou mate. Viděl jsem týmy, které dva týdny honily 200 ms na Total Blocking Time na marketingové stránce, zatímco reálný důvod opuštěného checkoutu byl React hydration stall ve shipping kroku. Objevil se jen na slabších Android zařízeních a až ve chvíli, kdy se inicializoval third-party fraud script.
Syntetické testování má svoje místo. CI má spadnout, když někdo shipne na homepage JavaScript bundle o velikosti 4,2 MB nebo když se v kontrolovaném prostředí zhorší Largest Contentful Paint o 40 procent. To je základní hygiena. Chyba začíná ve chvíli, kdy z hygieny uděláte strategii. Lighthouse vám neřekne, že uživatelé z placené akvizice naráží na race condition v consent banneru, že vám CRM widget přidává 1,8 sekundy před první interakcí na account pages nebo že jeden customer segment snese pomalejší dashboardy, zatímco jiný tvrdě odpadá, když signup formulář není do tří sekund interaktivní.
Týmy ve Steezr na tenhle strop obvykle narazí po pár měsících škálování. Aplikace ve stagingu působí dost rychle, score nevypadá špatně, support ticket y zmiňují pomalost dost vágně a revenue se stejně chová divně. Hezčí laboratorní čísla to nespraví. Potřebujete telemetrii navázanou na reálné chování, v produkci, napříč skutečnými user journeys.
měřte reálné uživatele
Real User Monitoring má být střed performance strategie, ne dodatek přilepený k tomu, co už si frontend framework nějak loguje sám. Začněte klidně u Web Vitals, tedy LCP, INP, CLS, případně TTFB, pokud řešíte backend latenci na server-rendered routách. Pak přidejte custom spans kolem věcí, které váš produkt skutečně dělá. Dashboard route, která tahá sedm widgetů, dešifruje tenant settings, bootstrappuje feature flag klienta a hydratuje obří tabulku, potřebuje víc než generickou metriku page loadu.
U Next.js 14 appky obvykle zapojíme web-vitals na klientu, eventy pošleme do Sentry nebo OpenTelemetry a pořádně je otagujeme. Device class, effective connection type, route template, experiment variant, logged-in stav, customer segment, někdy i plan tier. Syrové vitals bez kontextu jsou jen o trochu lepší než Lighthouse. Hodnotu má až kontext. Díky němu můžete odpovědět na nepříjemné otázky.
Jednoduchý příklad v app/instrumentation-client.ts úplně stačí:
1import { onLCP, onINP, onCLS } from 'web-vitals';23function send(metric: any) {4 navigator.sendBeacon('/api/vitals', JSON.stringify({5 name: metric.name,6 value: metric.value,7 id: metric.id,8 rating: metric.rating,9 path: window.location.pathname,10 conn: (navigator as any).connection?.effectiveType,11 mem: (navigator as any).deviceMemory,12 }));13}1415onLCP(send);16onINP(send);17onCLS(send);
Tohle je ta jednoduchá část. Užitečné je měření konkrétních UX hranic. Měřte čas do prvního vykresleného price na pricing konfigurátoru. Měřte čas od začátku route transition do chvíle, kdy je primární CTA poprvé enabled. Měřte čas, za jak dlouho po psaní začne validace checkout kroku zase reagovat. Pokud máte backend v Djangu, přidejte server spans s request ID a propagujte je do klienta, aby jeden ošklivý trace vysvětlil špatnou konverzní session místo toho, že všichni budou jen hádat.
OpenTelemetry je na tohle dobré. Používejte ho. Posílejte spans z browseru i serveru, názvy držte nudné a konzistentní a odolejte nutkání trackovat padesát věcí. Trackujte momenty, které uživatel opravdu cítí.
napojte performance na funnel
Většina týmů sbírá performance data a business data do oddělených sil. Pak se diví, že prioritizace sklouzne do politiky. Engineering ukáže graf p75 LCP. Product ukáže graf checkout konverze. Nikdo nedokáže prokázat kauzalitu, každý argumentuje podle pocitu a sprint nakonec dostane ten, kdo mluví nejhlasitěji.
Propojte metriky na úrovni funnelu. To znamená vydefinovat pár klíčových journeys, signup, checkout, lead submission, aktivaci dashboardu, upload dokumentu, prostě to, co reálně hýbe byznysem, a ke každému kroku připojit performance měření. Ne pageviews, kroky. Jedna route může obsahovat několik důležitých momentů a jedna stránka může být součástí několika různých journeys podle intentu.
Vezměte si jednoduchý SaaS signup flow. Krok jedna je zobrazení landing page. Krok dvě je start formuláře. Krok tři je odeslání formuláře. Krok čtyři je ověření e-mailu. Krok pět je první úspěšná session. Teď ke každému eventu přidejte performance pole: p75 INP při startu formuláře, time to interactive na signup routě, API latenci pro založení účtu, hydration delay předtím, než se submit button ustálí, cost third-party scriptů před zobrazením verification UI. Jakmile tyhle dimenze žijí ve stejném event streamu, můžete pokládat užitečné otázky. Třeba jestli uživatelé s INP nad 350 ms konvertují znatelně hůř nebo jestli mobile uživatelé na zařízeních s malou pamětí odpadávají ve chvíli, kdy se onboarding checklist vykreslí pozdě.
Mixpanel, PostHog, Amplitude, BigQuery, tohle zvládnou všechny, pokud máte rozumný event model. Event model většinou rozumný není. Týmy po appce rozhází analytics eventy se jmény jako button_clicked_final_v2 a pak se tváří překvapeně, že analýza nejde dělat. Věnujte jeden den opravě taxonomie. Vrátí se to hned.
Jedna z nejméně sexy a zároveň nejefektivnějších věcí, které na ERP a portálových projektech děláme, je postavit tuhle mapovací vrstvu pořádně. Výsledek je tabulka, která úplně normálně říká: pokud route X na těchto zařízeních překročí tento threshold, krok Y ztratí Z procent uživatelů. Přesně na tomhle má prioritizace stát.
dělejte ošklivé experimenty
Korelace je začátek, ne cíl. Pokud chcete rozpočet na performance work, hlavně na úrovni CTO nebo productu, dělejte experimenty, které oddělí dopad. Klidně ošklivé a praktické. Nablýskaná metodologie je míň užitečná než tupý test, který změní jednu věc a pohne penězi.
Omezte u 20 procent trafficu nějaký nekritický third-party script a porovnejte konverze. U poloviny sessions odložte boot chat widgetu do idle. Mobile uživatelům shipněte lehčí variantu hero image. Nahraďte client-rendered pricing kalkulačku server-rendered shellem s odloženými enhancementy. Pak sledujte performance i business metriky dohromady. Pokud se p75 LCP zlepší o 600 ms a ve funnelu se nic nestane, super, aspoň víte, že tahle route problém nebyla. Jděte dál. Pokud zlepšení input responsiveness o 150 ms ve druhém checkout kroku přinese měřitelný nárůst dokončení, roadmap rozhodnutí je najednou snadné.
Cílem je přestat brát performance jako morální ctnost a začít ji brát jako ekonomickou proměnnou. Viděl jsem týmy, které spálily celé kvartály na vágních iniciativách typu „zrychleme appku“, protože nikdo nepoložil základní otázku: rychlejší pro jakou journey, na jakých zařízeních, v jakém kroku a s jakým očekávaným dopadem. Tahle otázka odřízne spoustu balastu.
Nepotřebujete na to celý data science tým. Překvapivě daleko dojdete s PostgreSQL tabulkou, kde máte session ID, vitals, funnel eventy a experiment flags. Už takový dotaz je lepší než většina dashboardů:
1select2 experiment_variant,3 percentile_cont(0.75) within group (order by inp_ms) as p75_inp,4 avg(case when completed_checkout then 1 else 0 end) as checkout_rate5from checkout_sessions6where device_type = 'mobile'7group by experiment_variant;
Tenhle typ analýzy je nudný, mechanický a brutálně efektivní. To je dobře. Nuda vyhrává.
co udělat v pondělí
Začněte v malém a tam, kde už revenue na výkon citlivě reaguje. Vyberte jednu journey. Obvykle checkout, signup nebo lead capture. Na té journey instrumentujte Web Vitals, přidejte dvě nebo tři custom timings kolem momentů, které uživatel opravdu vnímá, a pošlete ty eventy do stejného warehouse nebo analytics nástroje, kde máte konverzní data. Pokud jedete na Next.js a Djangu, dá se to zvládnout za týden, aniž byste zabili feature work.
Pak nastavte thresholdy, které dávají smysl uživatelům, ne vanity targety opsané z nějakého blogpostu. Vaše interní pravidlo třeba bude: response v mobile checkout kroku musí držet p75 INP pod 200 ms, první použitelný pricing stav se musí objevit pod 2,5 sekundy na 4G, dashboard shell se musí vykreslit pod 1,8 sekundy pro přihlášené uživatele na vašem hlavním trhu. Tyhle cíle mají vycházet z pozorovaných drop-off křivek, ne z obecných best practices.
Pak zbořte pár iluzí. Přestaňte slavit agregovaná zlepšení v Lighthouse, která se nedotknou klíčových funnelů. Přestaňte přidávat third-party nástroje bez performance budgetu. Přestaňte dělat review frontend pull requestů bez kontroly bundle diffů. Dejte do repa @next/bundle-analyzer, kontrolujte chunky a chtějte po lidech vysvětlení velkých závislostí. Pokud někdo importuje date knihovnu, která přidá 90 KB gzip na kritickou route, stopněte to. Pokud stránka nacpaná Tailwindem maskuje hydration problém tím, že vypadá hotově dřív, než skutečně funguje, změřte ten rozdíl explicitně.
Nakonec udělejte z ownershipu performance společnou věc. Product to musí řešit, protože tam leží prioritizace. Engineering to musí řešit, protože tam leží implementace. Leadership to musí řešit, protože tam leží rozpočet. Score z Lighthouse klidně nechte v CI, s tím není problém, jen ho držte na správném místě, jako guardrail, ne jako kompas. Kompas musí ukazovat na chování uživatelů a business výsledky. Jinak optimalizujete laboratorní experiment, zatímco zákazníci vám potichu odcházejí.
