Proč optimalizovat výkon PHP aplikací
Výkon PHP aplikací rozhoduje o uživatelské zkušenosti, infrastrukturních nákladech i obchodních výsledcích. Moderní PHP (8.x) přináší JIT, vylepšení engine a rozsáhlý ekosystém optimalizačních nástrojů. Cílem je dosáhnout nízké latence, vysoké propustnosti a stabilního chování pod zátěží při zachování bezpečnosti a udržovatelnosti kódu.
Strategie: měřit → analyzovat → optimalizovat
- Měření: APM nástroje (OpenTelemetry, New Relic, Datadog), metriky z
php-fpm status, logy Nginx/Apache (p95/p99), obchodní KPI. - Profilace: profilery bezpečné pro produkční prostředí (Blackfire, Tideways), vývojářský Xdebug (mimo produkci), sampling vs. tracing.
- Testování: zátěžové a stresové testy (k6, JMeter, Gatling, wrk), výkonnostní rozpočty v CI/CD, regresní testy.
Upgrade na moderní PHP 8.x
- Výkon jádra: výrazná zlepšení v opcache, garbage collection a optimalizacích bytekódu.
- JIT: u čistě CPU-bound úloh může pomoci; u typické I/O webové zátěže je jeho efekt omezený. Měřte podle konkrétní zátěže.
- Nové funkce: typy, readonly, fibers, lepší
json, optimalizované operace sarray.
OPcache: základní kámen výkonu
- Bytecode cache: eliminuje opakovanou kompilaci skriptů; snižuje latenci a vytížení CPU.
- Doporučené nastavení (produkce):
opcache.enable=1,opcache.enable_cli=0(případně 1 pro dlouho běžící CLI služby).opcache.validate_timestamps=0a řízený opcache reset při vydání nové verze (neměnné sestavení).opcache.memory_consumption256–1024 MB podle kódu,opcache.interned_strings_buffer16–128 MB.opcache.max_accelerated_filespodle počtu skriptů (např. 20000–100000).opcache.preloadaopcache.preload_userpro přednačítání často používaných tříd/funkcí.
- Realpath cache:
realpath_cache_size256k–4M,realpath_cache_ttl300+ pro minimalizaci volání stat().
Composer a autoloading
- Optimalizace autoloaderu:
composer dump-autoload -o(classmap authoritative), minimalizuje diskové I/O. - Redukce závislostí: audit balíčků, nahrazení těžkých knihoven lehčí alternativou, odstranění nepoužívaných.
- Mapování PSR-4 přizpůsobit struktuře; vyhnout se hlubokým stromům složek.
PHP-FPM: ladění procesního manažeru
- Model: FPM používá pro každý požadavek worker; cílem je optimální počet workerů bez využití swapu.
- Klíčové parametry:
pm = dynamic|ondemand,pm.max_children,pm.max_requests,pm.process_idle_timeout. - Postup: změřit RSS jednoho workera při špičce → spočítat
max_children ≈ (RAM - rezerva) / RSS. - Slowlog:
request_slowlog_timeoutaslowlogpro stacktrace blokujících volání.
Webový server a HTTP vrstva
- Nginx + FPM: udržujte malé a rychlé
fastcgi_buffers, správně nastavtefastcgi_read_timeout, bezdůvodně nenastavujte vysokéclient_max_body_size. - Komprese: Gzip/Brotli pro textové assety; u PHP odpovědí používejte kompresi na reverzní proxy, nikoli v PHP.
- Cache:
Cache-Control,ETag,Last-Modified; u API podle idempotence a četnosti změn. - fastcgi_cache pro plně cachovatelné stránky (anonymní obsah), invalidace pomocí klíčů.
Databáze: nejčastější úzké hrdlo
- Indexy: pravidelný audit pomalých dotazů, přidání kompozitních indexů podle vzorců přístupu.
- Problém N+1: eliminovat eager/fetch joiny, dávkovat dotazy, využívat přenos dat v rámci jednoho požadavku.
- ORM: omezit hydration, vybírat sloupce selektivně, použít cache druhé úrovně (Redis/Memcached), vyhnout se náročným transformacím v PHP.
- Připojení: persistentní připojení v PDO používat uvážlivě; u FPM může docházet k neúčelnému držení připojení.
- Read replicas: rozdělení čtení a zápisu, idempotence a konzistence (směrování zohledňující zpoždění).
Cache vrstvy a serializace
- APCu: cache v rámci procesu pro výsledky výpočtů, konfiguraci a malé vyhledávací tabulky (pozor na invalidaci při nasazení).
- Redis/Memcached: sdílená cache pro session, výsledky dotazů, fragmenty renderování; používejte TTL a jmenné prostory.
- Serializer: igbinary nebo msgpack snižují objem dat a zatížení CPU oproti nativní serializaci.
- HTTP cache: reverzní proxy (Varnish/Nginx) pro celé stránky, ESI pro fragmenty.
Sessions a souběh
- Uzamykání: výchozí souborové úložiště session uzamyká požadavky; po přečtení zavolejte
session_write_close(). - Úložiště: Redis s locking a krátkým TTL; vyhněte se sdílení session napříč doménami, pokud to není nutné.
Asynchronní zpracování a škálování
- Fronty: dlouhé operace zpracovávejte přes frontu úloh (RabbitMQ, Redis, SQS, Beanstalkd), v architektuře založené na událostech.
- Dlouho běžící runtime: Swoole/AMPHP/ReactPHP, RoadRunner, Laravel Octane – omezuje režii FPM, vyžaduje pečlivou správu stavu.
- Přesun zátěže: generování PDF, obrázků a exportů mimo webový worker (workers, serverless).
Optimalizace kódu a datových struktur
- Minimální alokace: kvůli čitelnosti i výkonu upřednostňujte
foreachpředarray_map; vyhněte se zbytečnému kopírování polí. - Řetězce: používejte
.=s dostatečnou rezervou ve vyrovnávací paměti neboimplode; minimalizujte použití regulárních výrazů, upřednostňujte např.strpos. - JSON: používejte
json_encodes vhodnými volbami (JSON_UNESCAPED_UNICODE,JSON_INVALID_UTF8_SUBSTITUTE), nepřenášejte nadbytečná pole. - Výpočty: pro velká čísla upřednostňujte
ext-gmppřed funkcemibc*. - Kolekce: u velkých datových sad využívejte generátory (
yield) a iterátory místo úplného načtení do paměti.
Šablonování a rendering
- Cache šablon: Twig/Latte Blade – zapněte kompilaci a cache, minimalizujte dynamiku v šablonách.
- Cache fragmentů: cachujte části stránky s invalidací založenou na klíčích (uživatel, jazyk, verze dat).
Bez I/O navíc: souborový systém a sítě
- Minimalizace stat(): používejte absolutní cesty a realpath cache, vypněte nepotřebná omezení
open_basedir, pokud výkon zpomalují. - HTTP klient: opakované využití TCP/TLS (pooling v Guzzle přes Curl handler), timeouty a circuit breakery.
- Externí služby: hromadné operace, dávková API, idempotentní návrh.
Bezpečnost vs. výkon
- Zakázat Xdebug v produkci, nastavit
assert.active=0, vypnoutzend.assertions> 0. - expose_php=0, vhodné nastavení
session.cookie_secure,SameSitea HTTPOnly bez negativního dopadu na výkon. - Omezování rychlosti na reverzní proxy, nikoli v PHP, snižuje zatížení CPU.
Konfigurace runtime a OS
- Huge pages pro OPcache (pokud jsou stabilní), připínání procesů k CPU pouze po otestování.
- Disk: SSD/NVMe pro logy a dočasná data, rotace logů, žádné synchronní zápisy v rámci požadavku.
- Kontejnerizace: kompilace závislostí při sestavení, neměnné artefakty, warmup opcache ve vstupním bodě.
Monitoring, upozornění a observabilita
- Metriky: latence (p50/p95/p99), propustnost (RPS), míra chyb, saturace (CPU, paměť, I/O), délka fronty FPM.
- Trasování: distribuované trasování (OpenTelemetry) přes web → PHP → DB → cache.
- Logy: strukturované (JSON), korelace s trace-id, sampling při běžném provozu a úplné logování při incidentech.
Poznámky ke konkrétním frameworkům
- Symfony: cache pro prod,
opcache.preload,composer dump-env prod, vypnout debug bundle, HTTP cache s HttpCache nebo CDN. - Laravel:
config:cache,route:cache,view:cache, Horizon pro fronty, Octane pro dlouho běžící runtime. - Nette: production mode, cache šablon Latte, výpis DI kontejneru a zahřátí opcache.
- Doctrine: cache dotazů a výsledků, omezit režimy hydratace, explicitně vybírat sloupce pomocí
SELECT.
Tabulka: rychlá orientační příručka k optimalizacím
| Příznak | Možná příčina | Doporučený krok |
|---|---|---|
| Vysoké vytížení CPU, nízké RPS | Chybějící OPcache, náročné šablony | Zapnout OPcache, zapnout cache šablon, provést profilaci |
| Pomalé p95/p99 | Dotazy N+1, I/O na externí API | Dávkování, cache, timeouty a opakování požadavků s backoff |
| Fronta ve FPM | Nízké max_children, vysoké RSS |
Navýšit RAM/optimalizovat kód, přepočítat max_children |
| Kolísavá latence | GC, cold start, reset opcache | Zahřátí po nasazení, stabilní strategie vydávání verzí |
| Blokující požadavky | Uzamčení session, souborové I/O | session_write_close(), přesunout session do Redis |
Řízení vydávání verzí a spolehlivost
- Nasazení Blue/Green a Canary s metrikami a automatickým návratem k předchozí verzi.
- Neměnné artefakty: po nasazení žádné změny na serveru; zahřátí cache a opcache.
- Příznaky funkcí: řízení zátěže a postupné zapínání náročných funkcí.
Kontrolní seznam: minimální základ pro produkční prostředí
- Zapnutý a správně dimenzovaný OPcache včetně realpath cache.
- Optimalizovaný Composer autoloader a audit závislostí.
- Vyladěný PHP-FPM (
pm.max_children, slowlog, stránka se stavovými informacemi). - HTTP hlavičky cache, komprese na reverzní proxy, fastcgi_cache pro anonymní obsah.
- Indexy DB, odstraněné problémy N+1, cachování opakovaných dotazů.
- APCu/Redis pro runtime cache a session bez uzamykání.
- Monitoring p95/p99, APM traces a upozornění, zátěžový test v CI.
Závěr
Optimalizace výkonu PHP je kontinuální disciplína kombinující změny v architektuře, konfiguraci runtime, databázové vrstvě i kódu. Systematickým měřením, profilací a automatizovaným testováním dosáhnete stabilní latence, lepšího škálování a nižších nákladů. Moderní PHP 8.x s OPcache, pečlivě vyladěným FPM, využitím cache vrstev a promyšlenou prací s I/O poskytuje vynikající základ pro rychlé a spolehlivé webové aplikace.
