Výkon webové aplikace: jak zrychlit databázi, API i rozhraní
Webovou aplikaci zrychlíte tím, že nejdřív zjistíte, kde uživatel skutečně čeká, a upravíte příčinu. Pomalá obrazovka může čekat na databázový dotaz, externí API i JavaScript v prohlížeči. Každý problém vyžaduje jiný zásah. Projdeme jednu operaci od kliknutí po použitelný výsledek: co měřit, kdy pomůže index nebo mezipaměť a jak ověřit zlepšení, které neschová chyby ani nevrací nesprávná data. Srozumitelně pro vedení firmy i s technickými souvislostmi pro vývojový tým.

„Aplikace je pomalá“ je užitečné hlášení, ale neúplné zadání. Doplňte, která činnost zpomaluje, komu, s jak velkými daty a v jakou dobu. Zákazník otevírající rozsáhlý účet na běžném telefonu může narazit na problém, který se na vývojářském notebooku nikdy neprojeví.
Technické podklady jsme ověřili 23. října 2026. Níže uvedený časový graf je záměrně zjednodušený model, nikoli test aplikace ani příslib zrychlení. Postup je stále stejný: výchozí měření, dohledání konkrétní příčiny, cílená změna a srovnání stejných podmínek. Širší uživatelský pohled rozebírá článek o prvních okamžicích na webu a v aplikaci.
01Pojmenujte pomalou operaci a její obchodní dopad
Začněte větou, kterou dokáže někdo další zopakovat: „Otevření seznamu objednávek velkého zákazníka na telefonu trvá příliš dlouho.“ Doplňte velikost účtu, filtry, třídu zařízení, přibližný čas a očekávaný výsledek. Nesbírejte osobní údaje, které k diagnóze nepotřebujete. Společný identifikátor požadavku bývá užitečnější než zkopírovaná zákaznická karta.
Určete okamžik dokončení. Může jím být první použitelný seznam, potvrzené uložení nebo připravený export. Zobrazení točícího se kolečka je zpětná vazba, ne hotová práce. Když měříte nesprávný okamžik, tým dokáže zlepšit vykazované číslo, zatímco člověk na potřebný výsledek čeká stejně dlouho.
Priority určujte podle dopadu a četnosti. Opakované zdržení při vychystávání může spolknout více pracovního času než vzácně pomalé nastavení účtu. Problém v objednávce si může zasloužit přednost i při menší skupině postižených zákazníků. Dohodněte cíl konkrétní operace a vedle rychlosti sledujte správnost i chyby.
02Čtěte percentily společně s jejich kontextem
Průměr schovává rozložení čekání. Hodnota p95 rovná 800 milisekundám znamená, že 95 % sledovaných dob ve vybrané skupině a období nepřekročilo tuto hodnotu. P99 popisuje vzdálenější část pomalého konce rozdělení. Ani jedno číslo neslibuje, že příští požadavek skončí právě v takovém čase.
U výsledku ponechte počet pozorování, časové okno a sledovanou skupinu. Oddělujte důležité operace, zařízení i úspěšné a chybové odpovědi. U malých vzorků mohou krajní percentily výrazně kolísat. Srovnání klidného rána s rušným odpolednem mnoho neřekne, pokud nezohledníte změnu skladby a intenzity provozu.
Nespočítejte p95 celé služby jako průměr p95 jednotlivých serverů. Dokumentace Promethea vysvětluje, proč takové agregování nefunguje. Potřebujete vhodná data o rozdělení a jednotný postup výpočtu. Stejně tak součet p95 databáze a p95 API nedává smysluplný percentil celé uživatelské operace.
03Propojte kliknutí s konkrétním požadavkem a dotazem
Spojte časování prohlížeče, telemetrii aplikace a podklady z databáze. Distribuované trasování propojuje související úseky práce společným kontextem; OpenTelemetry je popisuje jako spany. Pomalou obrazovku tak můžete spojit s požadavkem, závislostí a dotazem, které ji skutečně zdržují.
Než začnete sčítat časy, přečtěte časovou osu. Nadřazený úsek zahrnuje práci podřízeného a paralelní požadavky se překrývají. Hledejte kritickou cestu: posloupnost, která určuje okamžik použitelného výsledku. Součet všech úseků trasování může vykázat více čekání, než uživatel skutečně zažil.
Model níže používá šest navazujících fází bez překryvu, dohromady 1 500 milisekund. Největší část připadá na databázi, ale záleží i na prohlížeči. Vymyšlené vstupy ukazují, kam zaměřit další zkoumání. Nejde o p95, měření INP ani důkaz, že určitá úprava ušetří 600 milisekund.
- Cesta požadavku100
- Čekání na serveru150
- Práce databáze600
- Ostatní práce serveru200
- Přenos odpovědi150
- Zpracování a vykreslení v prohlížeči300
Vymyšlený příklad šesti navazujících fází bez překryvu, celkem 1 500 ms. Nejde o měření, percentil ani skóre INP. Skutečné trasování může obsahovat souběžné a vnořené úseky, jejichž časy se nesmějí prostě sečíst.
04Sestavte měřicí přehled použitelný i po další verzi
Pro každou důležitou operaci udržujte stručný výchozí záznam. Uveďte verzi, datum, reprezentativní velikost dat, zátěž a způsob měření. Výsledek bez podmínek se špatně opakuje a snadno zneužije v prezentaci. Stejná pole ponechte i při ověřování navržené změny.
| Vrstva | Užitečné podklady | Na co odpovídají |
|---|---|---|
| Uživatelská operace | Čas dokončení, úspěšnost, zařízení a velikost účtu | Dokáže zákazník dokončit skutečný úkol? |
| API | Rozdělení odezvy, počet požadavků, chyby a objem odpovědi | Které volání a provoz potřebují pozornost? |
| Databáze | Četnost dotazů, čas provedení, řádky a čekání | Způsobuje náklady dotaz, opakování, nebo soupeření o zdroje? |
| Závislosti | Délka volání, časové limity a opakované pokusy | Čekáme na partnera, nebo opakujeme práci? |
| Prohlížeč | Síťová časová osa, hlavní vlákno a reálná uživatelská data | Vzniká zdržení při načítání, interakci, nebo vykreslení? |
Chyby zaznamenávejte samostatně. Pokud úprava způsobí rychlé selhávání požadavků, průměrná odezva může klesnout, přestože se služba zhoršila. Pokud možno porovnávejte stejnou skupinu zákazníků a dostatečný vzorek. Podrobné záznamy chraňte přístupovými právy a dobou uchování; výkonnostní log nemá být nekontrolovanou kopií zákaznických dat.
05Databázovou práci seřaďte podle celkového dopadu
Občas pomalý dotaz nemusí být největší příležitostí ke zlepšení. Sledujte četnost i dobu provedení a oddělte ji od čekání na spojení nebo zámek. Nenápadný dotaz opakovaný mnohokrát může spotřebovat více prostředků než jeden dlouhý report. Důležité je také to, kdy se s ostatní prací potkává.
Pokud jsou dostupné, pomohou souhrnné statistiky dotazů, například PostgreSQL pg_stat_statements. Se správcem ověřte, co už běží. Zapnutí nebo změna databázové instrumentace je provozní zásah, nikoli bezmyšlenkovitý krok při ladění. Parametry a citlivé hodnoty vynechte z reportu, pokud pro něj nejsou nutné.
Dohledejte místo, odkud aplikace dotaz volá. Načítá sloupce, které obrazovka neukazuje? Opakuje stále stejnou kontrolu oprávnění? Soutěží export o prostředky s interaktivními požadavky? Sepište hypotézu s pozorovatelným výsledkem, například méně databázových volání na otevřenou stránku. Takový cíl ověříte lépe než neurčité „zrychlit databázi“.
06Plány dotazů čtěte bezpečně, indexy navrhujte podle dat
Plán pomůže vysvětlit procházení tabulek, spojování, řazení a odhady počtu řádků. Kde je to vhodné, začněte obyčejným EXPLAIN. PostgreSQL upozorňuje, že EXPLAIN ANALYZE příkaz skutečně provede, včetně vedlejších účinků. Upřednostněte reprezentativní testovací prostředí; produkční zkoumání potřebuje schválený rozsah a vhodné limity.
Vrácení transakce nepovažujte za univerzální ochranu libovolných příkazů a funkcí. Některé účinky mohou zasáhnout mimo transakci. Nákladové údaje plánu jsou odhady, ne milisekundy, a konkrétní plán závisí na rozložení dat i parametrech. Malá testovací tabulka může vést k jinému rozhodnutí než produkce.
Index navrhujte podle skutečných filtrů, spojení a řazení. Dokumentace vícesloupcových indexů vysvětluje význam výběru a pořadí sloupců. Index zabírá místo a přidává práci při změnách dat. Ověřte přínos pro čtení i dopad na zápisy a naplánujte jeho vytvoření tak, aby nečekaně nenarušilo běžný provoz.
07Odstraňte opakované dotazy a posílejte rozumnou stránku
Typický problém N+1 nejdřív načte seznam a potom pro každý řádek provede další dotaz. Modelový seznam 50 objednávek tak s jedním úvodním dotazem a 50 dohledáními zákazníka vytvoří 51 dotazů. Problémem je opakovaná práce a síťová komunikace, nikoli samotné číslo. S velikostí stránky se nároky mění.
Související čtení seskupte nebo použijte vhodné spojení či způsob načítání. Dokumentace Prisma popisuje více možností. Jeden obrovský join nemusí být vždy lepší než dva řízené dotazy. Prověřte násobení řádků, velikost odpovědi, oprávnění a chování u rozsáhlého účtu.
Stránkujte ještě před přenosem dat po síti a určete stabilní jednoznačné pořadí. Vysoký OFFSET může zůstat drahý, protože přeskočené řádky stále vyžadují práci, jak popisuje PostgreSQL. Kurzor se hodí pro postupné procházení; skok na očíslovanou stránku může chtít jiný návrh. Omezte velikost stránky a nepočítejte drahý přesný součet, pokud ho produkt nepotřebuje.
08Mezipaměť přidejte až s pravidly správnosti
Mezipaměť může ušetřit opakovaný výpočet nebo načítání. Návrh ale začíná otázkou, jak stará smí odpověď být. Veřejná nápověda, zůstatek účtu a rezervace posledního kusu mají odlišné požadavky. Určete odpovědnost za zneplatnění uložené hodnoty i chování při jejím chybění.
Klíč mezipaměti musí rozlišovat všechny vlivy, které mění odpověď, včetně zákazníka nebo organizace, kde je to potřeba. Zkontrolujte změny oprávnění a personalizovaný obsah. MDN rozlišuje soukromé a sdílené HTTP cache; samotná přítomnost cookie nezaručuje bezpečnost sdíleného ukládání.
Měřte zásahy, chybějící položky, čerstvost i zátěž po vypršení oblíbených záznamů. Ukázka se zahřátou mezipamětí nestačí. Ověřte cestu bez uložené odpovědi i výpadek cache a zabraňte tomu, aby zastaralá data tiše nahradila autoritativní zdroj. Nesprávná informace je selhání optimalizace bez ohledu na rychlost.
09Na kritické cestě API ponechte jen potřebnou práci
Projděte dohodnutý formát komunikace mezi rozhraním a API. Vracejte potřebná pole a skutečně volitelné činnosti přesuňte mimo okamžitou cestu. Nezávislá volání mohou běžet souběžně v kontrolovaných mezích. Závislé operace potřebují pořadí a neomezená paralelizace může vyčerpat spojení nebo přetížit partnera.
Poctivě odlište přijetí úlohy od dokončení. Asynchronní export může vrátit identifikátor, ukazovat průběh a chybu a nabídnout hotový soubor. Nemá hlásit úspěšné vytvoření dřív, než soubor existuje. Fronta potřebuje odpovědnost, pravidla opakování a určený cíl dokončení.
Omezte zbytečná volání také v rozhraní. Vyhledávání nemusí odesílat zastaralý požadavek při každém stisku klávesy a pozdní starší odpověď nesmí přepsat novější výsledek. Prověřte rušení v celém řetězci: zastavení požadavku v prohlížeči automaticky neukončí každou práci serveru. Při odstraňování zbytečností zachovejte ověření oprávnění a vstupů.

10Po odpovědi serveru zkontrolujte prohlížeč
Rychlé API nezaručuje svižnou obrazovku. Prohlížeč stále zpracovává data, spouští JavaScript, počítá rozvržení a vykresluje. Velká tabulka nebo opakované změny stavu mohou zaměstnat hlavní vlákno. Zkoušejte reprezentativní zařízení a účet, nikoli jen počítač s malou ukázkovou databází.
Oddělte načítání, odezvu na interakce a vizuální stabilitu. Core Web Vitals pro ně používají LCP, INP a CLS. Dobré hranice jsou postupně 2,5 sekundy, 200 milisekund a 0,1, vyhodnocované na 75. percentilu. Nenahrazují však cíl dokončení vaší konkrétní obchodní operace.
Interakce může rychle zobrazit stav načítání, zatímco asynchronní výsledek dorazí později. INP a doba dokončení úkolu tedy odpovídají na různé otázky. Průvodce INP rozděluje odezvu na prodlevu před zpracováním vstupu, vlastní zpracování a následné vykreslení. Z reálných dat zjistěte postižené uživatele a příčinu potom reprodukujte při podrobném měření.
Pomoci může méně zbytečného JavaScriptu, rozdělení dlouhé práce, vykreslování rozumného počtu řádků nebo rezervované místo pro obsah. Zásah vyberte podle profilu. Vyšší skóre automatického auditu samo neprokazuje, že zákazník dokončí úkol rychleji.
11Změnu ověřte za srovnatelných podmínek
Ještě před úpravou kódu zapište hypotézu, měřítko úspěchu a kontrolu možného zhoršení. Například seskupené dohledání zákazníků má snížit počet dotazů v seznamu objednávek a zachovat oprávnění i výsledky. Před změnou a po ní použijte stejnou velikost účtu, zátěž a stav mezipaměti.
Nestačí jeden rychlý pokus. Porovnejte rozdělení dob i chybovost na dostatečném počtu pozorování a prohlédněte důležité odlehlé případy. Zachovejte údaj o infrastruktuře a verzi aplikace. Pokud test současně změnil hardware, velikost dat i cache, nemůže izolovat přínos úpravy kódu.
Kde to lze, nasazujte postupně a určete podmínky návratu. Kontroly mají zahrnout správnost dat, prohlížeč, náklady i úlohy na pozadí. Databázová migrace nebo nový index mohou potřebovat vlastní provozní plán. Výsledek popište s jeho omezeními; z jednoho scénáře nevyrábějte garantované procento pro všechny uživatele.
12Z nálezů sestavte pořadí smysluplných úprav
Ke každému nálezu doplňte dopad na uživatele, podklady, navrženou změnu, odhad práce a způsob ověření. Začněte důležitými operacemi, u kterých měření podporuje konkrétní příčinu. Domnělé optimalizace ponechte odděleně, dokud pro ně nejsou důkazy. Výkonnostní projekt se tak nerozroste v nekonečné přepisování.
Plán formulujte tak, aby podle něj mohlo jednat vedení i vývojáři. „Omezit opakované dohledávání v objednávkách a ověřit velké účty“ je jasnější než „optimalizovat backend“. Původní výchozí měření uchovejte, aby šlo kontrolovat zhoršení po dalších verzích.

Pokud je operace efektivní, ale kapacitu vyčerpává celková poptávka, pokračujte plánováním škálování rostoucí aplikace. Pro konkrétní projekt přineste pomalou operaci a dostupné podklady do diskuse o webové aplikaci. Prvním užitečným výstupem je diagnóza a ověřitelný seznam priorit.
13Časté otázky
Kde začít, když je webová aplikace pomalá?
Vyberte důležitou operaci a zopakujte ji s reprezentativním účtem, zařízením a daty. Určete dokončení užitečné práce a propojte časování prohlížeče, API a databáze. Úpravu vybírejte až podle místa, kde vzniká hlavní zdržení.
Je p95 užitečnější než průměrná odezva?
Odpovídá na jinou otázku: ukazuje bod v pomalejší části rozdělení. Sledujte společně průměr, objem, chyby i relevantní percentily. Výsledek závisí na skupině a období; samotné p95 stále může schovat problém menší skupiny.
Zrychlí přidání indexu databázi vždy?
Ne. Plánovač ho nemusí využít a indexy stojí místo i práci při změnách dat. Navrhněte index pro skutečný dotaz, ověřte plán a změřte čtení i zápisy za reprezentativních podmínek.
Je bezpečné spouštět EXPLAIN ANALYZE v produkci?
EXPLAIN ANALYZE zadaný příkaz skutečně provede, takže záleží na dotazu, oprávnění, zátěži, limitech a vedlejších účincích. Upřednostněte reprezentativní testovací prostředí. Produkční diagnózu naplánujte se správcem; vrácení transakce není univerzální ochrana.
Má se každá pomalá odpověď ukládat do mezipaměti?
Ne. Nejdřív určete přijatelnou čerstvost, správný klíč, hranice oprávnění a zneplatnění hodnoty. Některé operace potřebují aktuální autoritativní data. Kromě rychlosti zahřáté cache ověřte i cestu bez ní a její výpadek.
Proč je rozhraní pomalé, když API odpovídá rychle?
JavaScript, zpracování dat, rozvržení a vykreslení stále mohou zdržovat výsledek nebo blokovat ovládání. Prohlížeč profilujte na reprezentativním zařízení a datech. Rychlá odpověď je jen část celé uživatelské operace.
O kolik procent optimalizace aplikaci zrychlí?
Důvěryhodné univerzální procento neexistuje. Záleží na rozložení času a práci, kterou lze odstranit. Stanovte měřitelnou hypotézu, porovnejte stejné podmínky a uveďte naměřený výsledek s rozsahem platnosti a zbývajícími omezeními.
14Zdroje a metodika
Technické zdroje ověřeny 23. října 2026. Článek popisuje diagnostický postup, nikoli test konkrétní aplikace. Graf s 1 500 ms a příklad 51 dotazů jsou názorné výpočty. Doporučení PostgreSQL vztahujte k verzi a provozním podmínkám své databáze.
- PostgreSQL: Using EXPLAIN
- PostgreSQL: Introduction to indexes
- PostgreSQL: Multicolumn indexes
- PostgreSQL: LIMIT and OFFSET
- PostgreSQL: pg_stat_statements
- Prisma: Query optimization and performance
- OpenTelemetry: Traces
- Prometheus: Histograms and summaries
- MDN: HTTP caching
- Google web.dev: Web Vitals
- Google web.dev: Optimize INP