Výkonnostní opatření Admineru
Školení, která pořádám
Při vývoji Admineru kladu velký důraz na výkonnost. Co se za tím skrývá?
- Adminer je k dispozici v jediném minimalizovaném skriptu, takže odpadají časově náročné diskové operace při čtení vkládaných souborů.
- Přestože je všechno zabaleno v jediném skriptu, statické soubory (JavaScript, styl a obrázky) se nepřenášejí spolu s HTML kódem (což by šlo pomocí značek
<script>
, <style>
a protokolu data:
), ale stahují se samostatným požadavkem, který je u každé verze kešován po dobu jednoho roku. JavaScript a styl jsou minimalizované.
- Stránky jsou vytvořeny v HTML a ne v XHTML, takže lze vynechat řadu koncových značek. Problém byl jenom se značkou
<p>
, jejíž konec si Internet Explorer příliš nedokáže domyslet.
- Levá navigace je v HTML kódu umístěna až po hlavním obsahu stránky, takže se uživatel rychleji dozví, co ho zajímá. Příjemným postranním efektem je to, že když hlavní stránka provede nějaké změny, v navigaci se automaticky projeví.
- Adminer nepoužívá rámy, což urychlí první načtení (místo tří stránek stačí stáhnout jednu). Další načtení to může urychlit (pokud by bylo potřeba obnovit navigaci), ale i zpomalit (v opačném případě). Hlavně jde ale díky tomu každou stránku snadno uložit do oblíbených položek.
- Jakmile Adminer nepotřebuje zapisovat do session proměnných, tak je uzavře. Výchozí úložiště session totiž datové soubory zamyká, takže pokud jeden skript pracuje se session daty, nelze s nimi pracovat jinde (třeba v jiném panelu prohlížeče). Adminer dokonce session zavírá někdy i v případě, že s ní ještě pracovat bude – pokud se dá očekávat provádění dlouhotrvající operace. Po jejím provedení si session pomocí malého triku zase otevře.
- Před provedením dlouhotrvajících operací se uživateli odešle dosavadní výstup.
- Dlouhé operace, na kterých není závislé zobrazení zbytku stránky, se provádějí asynchronně JavaScriptem. Momentálně jde o počet tabulek v databázích a detailní informace o tabulkách v jejich přehledu. Původně se tyto informace odesílaly skriptem vloženým přímo na konec stránky (před čímž se odeslal dosavadní výstup), to ale způsobovalo pozdržení zobrazení stránky při zapnutém Firebugu. Proto se tyto informace stahují samostatným HTTP požadavkem.
- Asynchronně se provádí také kontrola nové verze a externí zvýraznění kódu v SQL příkazech.
- Kliknutí na řádek způsobí jeho zaškrtnutí. K tomu není navázaná JavaScriptová událost na každý řádek, ale pouze jedna společná pro celou tabulku.
- Velký důraz je samozřejmě kladen také na efektivní pokládání SQL dotazů, což je důležité hlavně při výpisu velkých tabulek. Pro zjištění počtu záznamů Adminer buď spočte vrácené řádky, nebo položí samostatný dotaz
SELECT COUNT(*)
, nebo použije modifikátor SQL_CALC_FOUND_ROWS, nebo se podívá do statistických informací o tabulce. Získání dat pro editaci se provádí s klauzulí LIMIT 1
, která je použita i při vyhledávání textů ve všech tabulkách. Adminer Editor používá pro získání vazebních dat konstantní počet dotazů.
- Pokud přijde dovnitř aplikace uživatel nepřihlášen, tak se mu rovnou zobrazí přihlašovací formulář. Není tedy nejprve přesměrován jinam.
- Kód je lineární, neboli funkce se používají jen pro zapsání opakovaného kódu a třídy pro sdružení souvisejících funkcí.
Co se naopak neprovádí?
- Neposílá se hlavička Last-Modified. Tuto hlavičku mám ve velké oblibě a z aplikací se ji vždy pokouším odesílat, Adminer ji ale nedokáže rozumně naplnit. I kdyby třeba v tabulce byl sloupec typu
timestamp
, tak jeho zachování nemusí znamenat, že se data nezměnila, hlavně se ale mohou změnit třeba i tabulky zobrazené v navigaci. Navíc se dá předpokládat, že většina stránek zobrazených v Admineru bude obsahovat nové informace.
- Adminer respektuje konfiguraci uživatele. To znamená, že nevolá funkci ob_start, která může mírně zdržet zobrazení prvního kousku stránky a naopak zrychlit její celkové načtení. Nezapíná ani komprimaci výstupu, která jednak nemusí být k dispozici, ale hlavně si ji správce může povolit sám.
- Adminer také zatím nepoužívá AJAX. S myšlenkou na jeho zavedení si pohrávám, i když by to trochu narušilo jednoduchost návrhu.
Největší vliv na rychlost má ale podle mě ergonomie uživatelského rozhraní, o kterou se snažím. K provedení požadované operace prostě vede co nejmíň kliknutí.
Přijďte si o tomto tématu popovídat na školení Výkonnost webových aplikací.
Diskuse
Malý dotaz stranou - můžeme se v blízkém budoucnu těšit na využití některých novinek z HTML5 ? Konkrétně mám na mysli třeba SessionStorage, LocalStorage a IndexedDB. Ty by pro použití Admineru mohli být zajímavé ..
Můžeš to prosím trochu rozebrat? Na co by se jednotlivé technologie daly použít?
David Grudl:
Na nic, ale bylo by to cool a fungovalo by to v Chrome :-)
Já si dovedu představit že by se v admineru dal aktivovat něco jako "offline mode" (třeba i jen pro vybranné tabulky), s tím že by se data databáze stáhli lokálně, uživatel by pracoval a vyvíjel.. a po dokončení prací by to opět synchronizoval na ostrý server.
Věřím že by to využilo plno programátorů při vytváření a úvodní editaci různých webů atd. Rozhodně by to byl však jen doplněk a uživatel by musel vědět co dělá a že si to v ten okamžik "může dovolit".
Vždyť když něco vyvíjím, tak potřebuji kompletní kopii struktury databáze, kterou můžu využívat i ve vyvíjené aplikaci, ne jen nějakou její virtuální podobu v Admineru. A když to potřebuji nahrát zpátky, můžu použít ALTER export, který Adminer nabízí.
Navrhované použití by se hodilo snad jen pro uživatele, kteří s databází nepotřebují pracovat zvenku Admineru a těch asi opravdu nebude moc.
To ja take.. ja pouzivam desktop aplikace typu SQLyog... ale tak z nekolika nemalo rozhovoru s vyvojari na hostingu mam pocit ze by se jim nekdy siklo kdyby si dali treba clanky do "offline modu" a upravovali dle libosti nebo kdyby si zalozili DB "offlinove", v ni si naklikali plno veci a pak jen klikli na synchro...
Je jasne ze pres Alter apod. to jde take. A urcite je fakt, ze je to hromada prace pro mensinu, takze to delat urcite nebudete.. Ale prijde vam ta myslenka uz od zakladu spatna?
Smysl by to mohlo dávat v Adminer Editoru, kde může být takovýhle scénář přirozený. Ale pak se najednou musí řešit i problémy synchronizace – že někdo změnil data během toho, co jsem je editoval i já. Do toho se pouštět nebudu.
Emil:
Nic ve zlém příteli, ale raději si nejprve opravte Váš web (co stránka to notfound) a pak navrhujte featury Admineru..
Ona moje stranka ma s adminerem nejakou souvislost ?
pokud to nebylo plácnutí do větru, tak mohl myslet to, že by s ním šlo pracovat offline, jako natáhnout vše?? do paměti, a kdyby ses náhodou odpojil, tak by se to zaznamenalo lokálně, dokud by ses nepřipojil.
Ano, offline mód mě taky napadl.
Co jsem měl přímo na mysli - Při každém načtení stránky by se nemusely přenášet údaje o tabulkách, stačilo by je načíst jen jednou a používat lokální cache, která by sesynchronizovala jen na základě jejich úprav (vytvoření tabulky, úpravy tabulky a smazání). A jelikož by se tyto údaje přenášely jen při prvním načtení, tak by nebylo od věci načíst i tabulky ze všech databází na serveru. Tím pádem by přepínání mezi databázemi nemuselo nutně znamenat refresh stránky, stačil by zobrazit tabulky změněné databáze Javascriptem.
Jako cool feature bych bral uložit si některé oblíbené/často používané dotazy do lokální cache. Je pravda, že by to znamenalo si je uložit ještě někde jinde (jiný prohlížeč, jiné PC, vymazání cache, atd..), ale byly by aspoň na jednom počítači u kterého člověk nejvíc sedí, hned po ruce.
U toho narážíme na tradiční problém kešování – když se nakešovaný obsah změní, tak se musí refreshnout. A změnit se může bez jakéhokoliv varování.
To už bych raději použil starý dobrý AJAX – při vybraných operacích se obnoví jen vnitřek stránky a navigace zůstane stejná.
Co se oblíbených dotazů týče, dají se uložit normálně do bookmarků. Využívá to například odkaz Upravit u SQL příkazu zobrazeného ve výpisu dat.
ad "tradiční problém kešování" - v případě admineru ale lze poměrně dobře odhadovat jestli došlo ke změně struktury DB a tabulek. Pokud prováděný dotaz obsahuje "drop, alter, create, ..." tak se s aktuální stránkou pošlou data s novou strukturou. Takže toto bych nepovažoval za problém vyřešit.
Jediný problém, co zůstává z mého pohledu je situace kdy databázi spravuje více lidí současně (většinou je jeden správce DB, za mé praxe jsem se nesetkal s tím, že by byli 2 a nebo více správců jedné databáze). To by se dalo zase docela elegantně řešit zobrazením stavu v rozhraní Admineru, že je přihlášen další uživatel nebo uživatelé z daných IP adres (stejně jako to třeba dělá Gmail). Ve chvíli, kdy víme, že tento stav nastal, tak se buď Adminer může přepnout sám nebo se zeptat, zda se má přepnout do režimu "online", tedy stavu, kdy se při každém requestu bude přenášet informace o struktuře DB a tabulek, tedy současný stav.
Nezdá se mi, že by to byl ten správný směr, kterým by se vývoj měl ubírat. Navíc si ani moc dobře neumím představit, jak by to fungovalo s vypnutým JS.
Mnohem lepší mi přijde ten AJAX, který má snadný bez-JS fallback, nepotřebuje žádnou keš a při refreshi stránky prostě stáhne seznam tabulek znovu. V neposlední řadě funguje ve všech prohlížečích.
Seznam tabulek se může změnit i mimo Adminer. Dost už, že se kešuje seznam databází (jehož získání je opravdu velmi pomalé). Seznam tabulek se naopak získá rychle.
No myslel jsem to jako dobrý námět na zlepšení, ale nevěděl jsem, že bez-JS fallback je předpokladem pro jeho tvorbu.
Jen tak ze zajímavosti, jaké množství uživatelů Adminer používá v shellu přes links ? Nebo je jiný možný příklad, kde by mohl běžet bez podpory JS ? A pokud si někdo vypíná JS v klasickém prohlížeči, tak to upřímně nechápu ...
Řeknu to naopak – neznám jediný důvod, proč by Adminer s vypnutým JS neměl fungovat.
Ok, beru to jako rozhodnutí autora, ikdyž já osobně s ním nesouhlasím :-)
To využití cool feature je ale nepřeberné, co třeba zmíněný offline mód ? Mějme příklad, kdy na špatném připojení či slabé baterce v Admineru píšu náročný dotaz (nebudu brát v potaz, že bych měl mít baterku nabitou a připojení kvalitní). Dojde mi baterka těsně před odesláním dotazu nebo při jeho odeslání mi vypadne wifi signál. O dotaz tím pádem přijdu. Kdyby se využila lokální cache, mohl by se tento dotaz průběžně ukládat jako draft a o dotaz bych tak nepřišel.
Řešit došlou baterku opravdu nebudu. Adminer asi nebudou zadávat žádní ťulpíci, kterým by se to běžně stávalo. A s vypadlým připojením žádný problém není. Stačí po jeho nahození stránku obnovit.
A vybitou baterku řeší automatická hibernace, je-li povolena a je-li dostatečně velký swapák.
Ale jestli chceš, můžeš napsat nějaký doplněk.
cucací potřeby:
Ahoj, Jakube.
> K provedení požadované operace prostě vede co nejmíň kliknutí.
To mi připomnělo - nezměnil jsi názor sjednocení řádku s tabulkovými odkazy i na stránky "Pozměnit tabulku" a "Nová položka"? (Tam výše uvedená věta zatím neplatí.)
Diskuse je zrušena z důvodu spamu.