Optimalizace výkonu Laravel aplikace

Pomalá aplikace odrazuje uživatele i Google. Ukazuji, jak v Laravelu odstranit N+1 dotazy, správně cachovat a zrychlit databázi, aby web létal i pod zátěží.
Publikováno 10.08.2026

Optimalizace výkonu Laravel aplikace

Publikováno

· Autor: · Pod kapotou · Výkon · 3 min čtení

Obsah článku

Pomalá aplikace odrazuje návštěvníky i Google. Dobrá zpráva je, že většina zpomalení v Laravelu má pár opakujících se příčin a nejde o žádnou černou magii. Zkušenost mě naučila, že za devět z deseti pomalých stránek můžou databázové dotazy, ne pomalé PHP. Výkonová rezerva navíc pomáhá, aby web nespadl ve špičce — o příčinách výpadků píšu v článku proč web spadl a jak tomu předejít. Projdu příčiny, které řeším nejčastěji, a ukážu je na kódu.

Zbavte se N+1 dotazů

Nejčastější výkonnostní problém vůbec. Aplikace v cyklu sáhne do databáze pro každý řádek zvlášť. Místo dvou dotazů jich najednou běží stovky.

// ŠPATNĚ: N+1 dotazů
$posts = Post::all();
foreach ($posts as $post) {
    echo $post->author->name; // dotaz pro každý příspěvek
}

// SPRÁVNĚ: eager loading, jen dva dotazy
$posts = Post::with('author')->get();

Rozdíl je brutální: kde dřív běželo dvě stě dotazů, teď běží dva. Na malé tabulce si toho nikdo nevšimne, ale jakmile dat přibude, aplikace se začne plazit. Proto N+1 hlídám od začátku, ne až když si zákazník stěžuje.

Cachujte, co se nemění

Opakovaný výpočet nebo dotaz, jehož výsledek se skoro nemění, je zbytečná zátěž. Cache ho odloží stranou a příště jen vrátí hotový výsledek, aniž by se znovu ptala databáze. Rozdíl mezi dotazem na databázi a čtením z paměti je řádový — z desítek milisekund se stanou desetiny.

use Illuminate\Support\Facades\Cache;

// Výsledek se uloží na hodinu
$sluzby = Cache::remember('sluzby', 3600, function () {
    return Service::orderBy('sort_order')->get();
});
  • Cachujte číselníky, nastavení a náročné agregace.
  • Na produkci cachujte konfiguraci i routy příkazem artisan optimize.
  • Nezapomeňte cache při změně dat zneplatnit.

Právě zneplatnění je nejčastější zdroj chyb — zapomenete smazat cache po úpravě a zákazník vidí staré ceny. Proto cachuji hlavně data, která se mění zřídka a předvídatelně. U často měněných dat se cache spíš vyplatí navázat na konkrétní událost, která ji sama zruší.

Zrychlete databázi

I dobře napsaný dotaz je pomalý, když databáze musí projít celou tabulku. Tady pomáhají indexy nad sloupci, podle kterých filtrujete.

// Migrace: index nad často filtrovaným sloupcem
Schema::table('posts', function (Blueprint $table) {
    $table->index('published_at');
    $table->index(['category_id', 'is_published']);
});
  • Indexujte cizí klíče a sloupce ve where a order by.
  • Vybírejte jen potřebné sloupce místo select *.
  • Dlouhé operace přesuňte do fronty, ať uživatel nečeká.

Měřte, než začnete ladit

Optimalizace naslepo je ztráta času. Nejdřív najděte úzké hrdlo, teprve pak ho řešte.

A na závěr férově: neoptimalizujte, dokud nemusíte. Předčasná optimalizace umí kód zbytečně zamotat a přinést chyby tam, kde předtím nebyly. Dokud aplikace běží svižně a data se vejdou do rozumných mezí, nechte ji být. Ladit má smysl tehdy, když měření ukáže konkrétní úzké hrdlo. Máte aplikaci, která se pod zátěží zadýchává? Napište mi a najdeme, kde ztrácí čas.