Optimalizace výkonu webových aplikací: na co se zaměřit?

✍️ Vláďa Smitka
📅 03. 12. 2015

English version

Tento článek se váže k mé nedávné přednášce na  7. WP konferenci o ladění výkonu WordPress. V článku jsou shrnuty nejdůležitější body přednášky s příklady.

Záznam z akce najdete na Youtube.

Výkon WordPress autor: Vladimír Smitka

Výkonností problémy lze nalézt především ve 4 oblastech:

  1. Načítání statických zdrojů
  2. Výkon aplikace samotné
  3. Výkon serveru
  4. Síťová konektivita

Prvním krokem pro zdárné vyřešení výkonnostních problémů je samozřejmě analýza. V této fázi nám nejpřínosnější informace ukáže analýza načítání stránky, většinou zobrazená ve formě vodopádového grafu.

K této analýze můžeme použít několik nástrojů:

Developerská konzole v prohlížeči:

Firefox - console

Online nástroje:

https://gtmetrix.com - tímto nástrojem lze také získat skóre z Google PageSpeed Insights a Yahoo Yslow, včetně tipů, co na webu zlepšit.

http://www.webpagetest.org/

WebPageTest WaterFall

Vodopádový lze rozdělit na 2 podstatné části - generování kódu a načítání zdrojů. Generování kódu je práce aplikace na straně serveru (PHP skripty), která generuje výsledný HTML kód. Dochází zde k vykonávání serverových skriptů, komunikaci s databází a další režii.

Načítání zdrojů

Vygenerovaný kód dále říká prohlížeči, aby začal stahovat zdroje - tedy kaskádové styly, fonty, javascripty, obrázky a další soubory. Čím více je těchto zdrojů použito a čím jsou objemnější, tím načítání stránky trvá:

GTmetrix bad scode

Je velmi složité doporučit správné hodnoty - když máte fotoblog, budete samozřejmě načítat objemnější obrázky ve větší kvalitě; e-shop bude také pravděpodobně načítat větší množství obrázků k produktům. Kdybych však měl určit orientační hodnoty pro běžné weby, bylo by to:

  • načítání pod 3s
  • velikost pod 2MB
  • počet zdrojů pod 50

Optimalizace zdrojů je často nejrychlejší způsob, jak webové stránky podstatně zrychlit. Začít můžete například optimalizací obrázků - doporučuji vyzkoušet službu https://tinypng.com/, která často dokáže s velikostí obrázku udělat divy. Dalším krokem může být zkombinování více JS a CSS souborů do jednoho (toto není tolik potřeba při použití protokolu HTTP/2). Také se ujistěte se, že máte zapnutou Gzip kompresi (nebo modernější Brotli) a “keep alive”.

Problémy na frontendu vám velmi dobře pomůže analyzovat Yellow Lab Tester.

Více tipů naleznete v prezentaci.

WebApp Performance

Pokud je problém v části generování kódu na serveru, vyžaduje analýza pokročilejší nástroje.

V případě WordPress je velmi častým problémem mnoho SQL dotazů do databáze. Ty jsou většinou způsobeny množstvím pluginů, nebo používáním špatně napsaných pluginů. Pro základní analýzu lze použít plugin Query Monitor, který vám ukáže, jaká část WP provedla nejvíc dotazů a jak dlouho tyto dotazy trvaly.

Query Monitor je opravdu užitečný plugin, který zobrazuje mnoho informací, které se při vývoji WordPress webu hodí. Na to, jak se používá v praxi, se můžete podívat ve WordPress Kuchařce z WordCamp Praha.

Dalším častým problémem je čekání na nějakou externí HTTP komunikaci z PHP (některé případy opět odhalí Query Monitor), nebo mnoho operací se souborovým systémem.

Často je však potřeba podívat se jak kód reálně pracuje mnohem podrobněji. K tomuto účelu jsou vhodné takzvané profilery. Můj nejoblíbenější je BlackFire.io, který krásně vizualizuje co se v kódu děje a co jak dlouho trvá.

Několik příkladů co jsme pomocí BlackFire.io odhalili:

  1. WP spotřebovává značnou část výkonu na načítání lokalizací - proti tomuto faktu můžete bojovat pomocí cachování - jak celého webu, tak využitím ObjectCache a zacachování výsledných lokalizací pomocí https://wordpress.org/plugins/mo-cache/.Můžete také vyzkoušet mé MU Pluginy pro cachování lokalizací.

    Blackfire - gettext

  2. Na jednom z analyzovaných  webů jsme detekovali plugin, který rekurzivně prováděl shortkódy - pro získání cca 30 objektů tak plugin vykonal více než 200 000 volání funkce WP_Object_Cache:get, která zkouší, zda je možné se k data vyčíst z cache. Paradoxně zde použití objektové cache problém mnohonásobně zhoršilo, protože přibyla režie pro vyzvedávání dat z cachovacího enginu - z hrozných 16 vteřin generování kódu se stalo více než 50 vteřin. Náhradou pluginu jsme se dostali opět pod 1 vteřinu.

    Blackfire - shordcode recourse

  3. V konfiguraci zákazníkova VPS jsme detekovali neaktivní rozšíření PHP pro práci s JSON, to způsobovalo použití neoptimálních funkcí pro práci s tímto formátem, kde byla téměř milionkrát volána funkce mb_substring. Funkce json_decode tak zpracovávala požadavky 9.2 vteřiny. Po povolení příslušného rozšíření trvala tato část kódu pouze 25 ms, což je cca 370 násobné zrychlení. ( extension=json.so )

    Blackfire - disables json.so

    Stejná část kódu po opravě:

BlackFire.io přináší rychlý a přehledný pohled na to co vaše aplikace opravdu dělá. Jeho instalace může být pro někoho složitější (je třeba nainstalovat rozšíření pro PHP a agenta na stroj s OS Linux), ale vynaložené úsilí se velmi brzo vrátí.

Můžete si porovnat profily z načítání WordPress v různých stavech:

Pro statičtější weby může být instantním zlepšovákem plugin, který dělá plně stránkovou cache - tím je například WP SuperCache. E-shopy jsou trochu jiná disciplín, protože je třeba řešit unikátní zobrazení pro jednotlivé návštěvníky (např. kvůli košíku). Tento typ pluginu problém s výkonem nevyřeší, ale může ho obejít pro velkou skupinu návštěvníků.

Pokud se o problematice cachování chcete dozvědět více, podívejte se na mou přednášku Cache! z WordCamp Bratislava.

Výkon serveru

Přetížený nebo nevhodně nakonfigurovaný server může být další příčina pomalosti webových stránek. Pokud provozuje vlastní server/VPS je vhodné nasadit monitoring serveru.

Vyplatí se sledovat především system load, využití paměti a zatížení CPU (s hodnotu IOwait).

System Load

Jedná se o velmi užitečnou, ale nepříliš konkrétní hodnotu. Udává kolik procesů čeká ve frontě na zpracování v daný časový okamžik. Tato informace jde jednoduše zjistit například příkazem uptime, který ukáže průměrné hodnoty za 1, 5 a 15 minut. Pokud čeká dlouhodobě ve frontě více procesů než je jader CPU, která by je mohla zpracovávat, je server přetížen.

Proces může čekat z mnoha důvodů - např. procesor zrovna počítá náročnou úloh (poznáme podle zatížení CPU aplikacemi - user), nebo čeká než se načtou data z pevného disku (což bývá nejčastější případ - poznáme většinou podle IO Wait).

Nutno podotknout, že i server s load 2-4x vyšším než počet jader procesoru může stále vcelku uspokojivě fungovat - jede však již na hranici svých možností. Hodnota do 0,7x počet jader CPU ukazuje na plynulý běh s rezervou pro náročnější úlohy.

Zatížení procesoru

Jedná se již o konkrétnější hodnoty, která udává kolik % času pracují jednotlivá jádra CPU. Zobrazení je většinou složeno z několika částí.

Zabbix - CPU utilization
Na grafu si můžete všimnout především náročných zálohovacích úloh mezi 4. a 6. hodinou ( graf ze systému Zabbix).

Využití paměti

Pokud začne serveru docházet operační paměť, musí data ukládat na pevný disk (swap), který je mnohem pomalejší, proto je potřeba využití paměti sledovat, ideálně opět s rozlišením způsobu jejich využití.

Munin - memory usage
Na grafu můžete vidět, že server efektivně využívá dostupnou volnou paměť jako cache, proto jsme v lednu přidali více RAM, přestože aplikace paměť zdaleka plně nevyužívaly (graf se systému Munin)

Vhodné nástroje pro monitoring serveru jsou napříkladMunin, Libre NMS or Zabbix.

Pokud má váš server dostatek RAM, dává smysl ji pro aplikaci využít. Výše v článku byla již zmíněna objektová cache (tou je například Memcache, Redis, APCu, Xcache), s nimi však musí vaše aplikace umět spolupracovat. Pro některá použití však můžete využít ramdisk (tmpfs) a umístit do něj soubory, ke kterým potřebujete vždy rychlý přístup.

Vhodným kandidátem pro umístění do ramdisku může být například složka cache ve WordPress, kam své statické soubory ukládají cachovací pluginy jako je WP SuperCache nebo Autoptimize - rapidně se tak zrychlí přístup k těmto souborům a zabráníte opotřebovávání SSD disku častými zápisy. Pokud má vaše aplikace velkou návštěvnost a je náročná na sessions, můžete je také uložit do RAM. Ideální úložiště pro ně může být Memcache nebo Redis, které při doplnění vhodného rozšíření umí PHP využít. Můžete je samozřejmě ukládat i do ramdisku, jen je třeba mít na paměti, že každý soubor zde zabere typicky minimálně 4kB a je proto nutné se zamyslet nad pravidelným číštěním prázdných sessions.

Řádek do fstab pro vytvoření 2G ramdisku:

tmpfs   /ramdisk   tmpfs   nodev,nosuid,noexec,nodiratime,size=2048M   0 0

Výkon sítě

Problémy mohou také nastat již v samotné síťové komunikaci se serverem. Nekvalitní konektivita dokáže komunikaci velmi zbrzdit.

Nejjednodušším testem je ping - tento nástroj změří za jak dlouho data doputují k cíli a zase zpět - odezvu sítě. Roli zde hraje i geografická vzdálenost jednotlivých strojů - odezva mezi datacentry v ČR bude mnohem menší než odezva mezi ČR a USA.

Ping command on Windows

Odezva mezi několika servery, co provozujeme:

Zdroj Cíl Odezva
Praha Hradec Králové 7ms
Praha Frankfurt nad Mohanem 13ms
Praha Miami 108ms

Dalším užitečným nástrojem je příkaz traceroute (tracert na Windows), který ukáže přes jaké sítě se dostanete ke svému serveru. Může se se stát, že k některým zdrojům zbytečně přistupujete přes půlku světa - především při použití cloudových služeb, zde již může být vliv odezvy sítě značný.

Testy odezvy mohou být užitečné i při volbě CDN, ze kterého budete stahovat různé běžné knihovny (např. jQuery), nebo své statické soubory.

Ukázka odezvy různých CDN s knihovnou jQuery (testy byly prováděny z našeho serveru v Praze, z jiných lokalit mohou být časy odlišné a vzhledem k tomu, že většina služeb používá nějakou formu loadblancingu, tak se mohou lišit i v čase)

CDN Odezva PRA Odezva HK Propustnost HK
MaxCDN 9.3ms 14ms 2908 KB/s
Google CDN 20ms 29ms 1640 KB/s
Microsoft CDN 7.1ms 14ms 2052 KB/s
CDNjs (Cloudflare) 1.5ms 5.7ms 4173 KB/s
jsDelivr CDN 1.5ms* 5.9ms 4266 KB/s

* 9ms když na mne vyšel jiný node

Stojíte tak před těžkým rozhodnutím, zda mít statické soubory na svém serveru nebo využít nějaké CDN služby - v tomto případě lze doporučit ty služby mají servery v České Republice (což má například CloudFlare) nebo nedaleko (Fraknfurt, Amsterodam). Pokud budete využívat CDN jen pro knihovny typu jQuery, bude nejlepším řešením zvolit to CDN, které doporučuje tvůrce knihovny jako hlavní - je největší šance, že ho bude mít již v cache nejvíce lidí (u jQuery je to MaxCDN).*

* Update 2020 - v rámci zvyšování soukromí uživatelů se účinnost této techniky podstatně snížila.

Není vhodné testovat odezvu ze svého běžného firemního/domácího připojení, protože tyto linky mají mnohem horší parametry než ty k datacentrům - výsledky tak mohou být velmi zkreslené. Pokud nemáte možnost testu mezi datacentry, můžete zkusit například web http://ping.eu.

Ladění výkonu webových aplikací je velmi komplexní úkol: čím více oblastí jste schopni prozkoumat, tím je větší šance, že naleznete problémy, které je možné opravit.

Celá přednáška je k dispozici na EDU.lynt.

Nepřehlédněte také můj průzkum stavu WordPress v ČR (analyzoval jsem 65 000 webů). Mohla by vás také zajímat má přednáška o bezpečnosti WordPress z WordCamp Praha 2015.

Koukněte určitě také na článek 10 nejčastějších problémů moderních webů.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *


Lynt services s.r.o

Již 12 let vytváříme efektivnější kampaně, zrychlujeme weby a řešíme jejich bezpečnost. Kombinujeme marketing, vývoj a automatizaci.
poptávka služeb