Masarykova univerzita Fakulta informatiky Statické generování a optimalizace načítání webových aplikací ve frameworku DotVVM Bakalářská práce Jiří Jurák Brno, jaro 2016
Masarykova univerzita Fakulta informatiky Statické generování a optimalizace načítání webových aplikací ve frameworku DotVVM Bakalářská práce Jiří Jurák Brno, jaro 2016
Prohlášení Prohlašuji, že tato bakalářská práce je mým původním autorským dílem, které jsem vypracoval samostatně. Všechny zdroje, prameny a literaturu, které jsem při vypracování používal nebo z nich čerpal, v práci řádně cituji s uvedením úplného odkazu na příslušný zdroj. Jiří Jurák Vedoucí práce: Mgr. David Gešvindr i
Poděkování Tímto bych chtěl poděkovat Mgr. Davidu Gešvindrovi za vedení této bakalářské práce. Dále děkuji autorovi frameworku DotVVM Bc. Tomáši Hercegovi za odborné konzultace při implementaci rozšiřující funkcionality frameworku DotVVM a za celkový přínos, jež vedl k dokončení mé práce. ii
Shrnutí Tato práce se zabývá generováním statických HTML souborů a jejich následnou distribucí na CDN servery ve frameworku DotVVM. Dále pak bundlingem a minifikací resource souborů a jejich cacheováním. V práci jsou uvedeny možnosti optimalizace webových aplikací na platformě ASP.NET. Jsou v ní popsány techniky, jak lze docílit snížení zátěže serveru a zvýšení komfortu uživatele na klientské straně. iii
Klíčová slova optimalizace, optimalizace webové aplikace, bundling, minifikace, cacheování, dotvvm, ASP.NET iv
Obsah 1 Úvod................................ 1 2 Optimalizace webových aplikací v ASP.NET......... 3 2.1 Než začneme optimalizovat.................. 3 2.2 Cíle webové optimalizace................... 3 2.2.1 Optimalizace na straně klienta.......... 3 2.2.2 Optimalizace přenosu............... 4 2.2.3 Serverová optimalizace výkonu.......... 6 2.3 Techniky, které vedou k optimalizovaným webovým aplikacím 8 2.3.1 Cacheování..................... 8 2.3.2 Snížení doby, po kterou se stránka načítá.... 13 2.3.3 Načítání JavaScriptových souborů paralelně s ostatními zdrojovými soubory.......... 14 2.3.4 Rychlejší načítání JavaScriptu........... 15 2.3.5 Načítání JavaScriptu na vyžádání......... 18 2.3.6 Vyhnutí se blokaci vykreslování stránky při načítání JavaScriptu.................. 18 2.3.7 Rychlejší načítání souborů s kaskádovými styly 19 2.4 Užitečné nástroje pro optimalizaci webových aplikací.... 21 2.4.1 Diagnostické nástroje klient + přenos...... 21 2.4.2 Diagnostické nástroje webového serveru.... 21 2.4.3 Nástroje určeny pro bundling a minifikaci... 22 3 Framework DotVVM....................... 23 3.1 Motivace pro vývoj webových aplikací ve frameworku DotVVM 23 3.1.1 Pro vývoj webových aplikací je nutná znalost mnoha technologií................. 25 3.1.2 Stránkování, řazení, filtrování........... 26 3.1.3 Validace....................... 26 3.1.4 Zobrazení data a času............... 26 3.1.5 Lokalizace...................... 27 3.1.6 Vytváření vlastních komponent.......... 27 3.2 DotVVM........................... 27 3.2.1 Princip fungování frameworku.......... 28 3.2.2 DotVVM a JavaScript................ 28 3.2.3 Použití frameworku DotVVM v praxi...... 29 4 Implementace........................... 31 v
4.1 Prostředky a použité technologie............... 31 4.2 Generování statických HTML souborů a modifikace frameworku DotVVM pro jejich podporu................. 31 4.2.1 Vytvoření aplikace generující statické HTML soubory....................... 32 4.2.2 Úprava frameworku DotVVM za účelem vytvoření podpory pro možnost implementace statických stránek ve webových aplikacích...... 32 4.3 Bundling a minifikace resource souborů v DotVVM..... 35 4.3.1 Definice bundle souboru ve webové aplikaci.. 35 4.3.2 Vytvoření bundle souboru............. 36 4.3.3 Problémy s embedded resources a jejich řešení. 36 4.3.4 Cacheování nově vzniklého bundle souboru.. 37 4.4 Testování a naměřené výsledky................ 37 5 Závěr................................ 41 Literatura................................ 42 vi
Seznam tabulek 2.1 Redukce velikosti knihovny při použití GZIP komprese. 16 2.2 Redukce velikosti knihovny při použití GZIP komprese a minifikace. 17 4.1 Porovnání velikosti jednotlivých scriptů s bundle souborem. 40 vii
Seznam obrázků 2.1 Schéma zobrazující proxy server v síti [4]. 11 2.2 Příklad zápisu deklarace externích souborů, který umožňuje paralelní stahování souborů s kaskádovými styly spolu s JavaScriptem [4]. 14 2.3 Příklad zápisu deklarace externích souborů, který umožňuje paralelní stahování obrázků spolu s JavaScriptem [4]. 15 3.1 Ukázka komunikace klient server v případě SPA. V prvním kroku si prohlížeč stáhne potřebné soubory (HTML, CSS, JavaScript), a poté již komunikace probíhá pouhým předáváním dat ve formátu JSON. 24 3.2 Ukázka kódu v DOTHTML. 29 3.3 Ukázka třídy ViewModel. 30 4.1 Příklad definice směrovací cesty ve frameworku DotVVM. 33 4.2 Příklad definice směrovací cesty vedoucí ke statickému obsahu. Na obrázku je vidět, že jako první parametr je nutno zadat úložiště statického obsahu, další parametry se poté již shodují s parametry, jež jsou nutny pro definici běžné směrovací cesty ve frameworku DotVVM. 33 4.3 Definice nového bundle souboru s parametry název, URL suffix a pole hodnot ve formátu typu string, jež představuje názvy všech resource souborů určené k minifikaci a bundlingu. 35 4.4 Graf zobrazující průběh testu nepředgenerované aplikace, která má pomalejší průměrnou dobu HTTP odpovědi a menší počet odbavených HTTP požadavků za vteřinu než aplikace předgenerovaná. 38 4.5 Graf zobrazující průběh testu předgenerované aplikace, jež dosahuje lepších výsledků oproti aplikaci dynamicky generované na serveru. 39 viii
1 Úvod V dnešní době jsou webové aplikace velmi populární, a i když by některé z těchto aplikací bylo vhodnější vytvořit v desktopovém provedení, tak atraktivita výhod, které s sebou přináší webové prostředí, je často rozhodujícím faktorem pro zvolení vývoje právě webové aplikace. Nicméně webové aplikace s sebou přináší i problémy, ke kterým je nutno se postavit čelem a v ideálním případě je kompletně odstranit, nebo alespoň omezit jejich dopad na samotný běh aplikace. Takovými problémy jsou například velké přenosy dat či obrovské množství HTTP požadavků na server, čímž se zvyšuje jeho zátěž. A právě touto problematikou se má práce zabývá. Cílem této práce je vytvořit aplikaci pro generování statických HTML souborů, jež bude možno distribuovat na servery Content Delivery Network (CDN) 1. Dále pak ve frameworku DotVVM implementovat funkcionalitu, jež umožní dosažitelnost těchto stránek pomocí vhodně upraveného routingu, a závěrem bude doplněna funkcionalita pro bundling a minifikaci resource souborů, jež budou zároveň i ukládány do cache. To by mělo snížit zatížení serveru a zvýšit rychlost přenosu resource souborů. Ve druhé kapitole této práce je popsána problematika optimalizace webových aplikací. Jsou zde definovány kritické body optimalizace, následně jsou popsány techniky, kterými je možno webovou aplikaci lépe optimalizovat. Závěrem jsou uvedeny nástroje, jež odhalí výkonové rezervy aplikace, které je možno odstranit použitím zmíněných technik optimalizace webových aplikací. Ve třetí kapitole je prezentován framework DotVVM. Tato kapitola seznamuje čtenáře s tímto frameworkem pro vývoj webových aplikací. Jsou zde rozebrány problémy související s dnešním vývojem webových aplikací, a následně je vysvětleno, že spoustu z těchto problémů framework DotVVM řeší. Ve čtvrté kapitole je popsána implementační část této práce a použité technologie. Kapitola se zabývá především úpravou frameworku DotVVM a zároveň je zde popsána aplikace, jež generuje statické HTML soubory. Jsou zde popsány jednotlivé úkoly, jež bylo třeba 1. Dostupné z: https://gtmetrix.com/why-use-a-cdn.html 1
1. Úvod splnit pro správné fungování daného rozšíření. Na konci kapitoly jsou představeny výsledky měření aplikace, jež byla generována staticky a tyto výsledky jsou porovnány s naměřenými výsledky aplikace generované dynamicky. Závěrečná pátá kapitola je zhodnocením celé práce, zpětně popisuje danou problematiku a odráží přínos této práce. Dále je zde možné nalézt další vylepšení, která v budoucnu mohou být implementována. 2
2 Optimalizace webových aplikací v ASP.NET 2.1 Než začneme optimalizovat Při vývoji webových aplikací je třeba se zamyslet, v jakém prostředí daná aplikace poběží a jak bude uspořádáno uživatelské rozhraní. V případě veřejně dostupné webové aplikace je nutno počítat s nepředvídatelnou zátěží, naopak pokud je aplikace nasazena v intranetu, tak se zde typicky nemusí řešit velké objemy přenesených dat či latence, a zároveň jsou aplikace vyvíjeny pro známou množinu webových prohlížečů a zařízení. U veřejně dostupné aplikace je nutné myslet na to, že uživatelé k ní mohou přistupovat z různých prohlížečů a z různých zařízení, jako jsou třeba mobilní telefony, a zde se již musí řešit mnoho aspektů souvisejících s různými platformami [1]. 2.2 Cíle webové optimalizace klient přenos server 2.2.1 Optimalizace na straně klienta Optimalizace na straně klienta znamená dostat na klientskou stranu HTML kód, JavaScript a CSS soubory v takovém stavu, aby jejich odbavení na straně klienta trvalo co nejkratší dobu. Progresivní vykreslení HTML Spočívá v sestavení HTML souboru tak, že již během stahování HTML souboru začne prohlížeč vykreslovat daný kód, i když celý objem dat související s načtením stránky ještě není kompletně stažen. Je vhodné uvádět rozměry obrázků, aby prohlížeč nemusel čekat na stažení celého obrázku, a poté zjišťovat jeho rozměry, ale aby si mohl dopředu vyhradit prostor pro daný obrázek, vykreslit 3
2. Optimalizace webových aplikací v ASP.NET danou stránku a teprve poté, až se obrázek stáhne, se v dané stránce objeví. Odkazy na JavaScriptové knihovny bývá obvykle vhodné umísťovat na konec HTML kódu, aby vykreslení stránky nebylo zpomalováno parsováním JavaScriptových knihoven (více o této problematice je popsáno v části 2.3.4). Parsování JavaScriptu Parsování JavaScriptu je další zátěž, se kterou je nutné počítat, a která může zpracování stránky zpomalit. JavaScriptové knihovny Angular 1 a React 2, které jsou v současnosti velmi populární, mají velikosti v řádech stovek kb. I při využití pouze jedné funkce z velké knihovny se musí zpracovat knihovna celá, a to zpomaluje načtení aplikace na klientské straně, obzvláště pokud klientská strana disponuje slabším hardwarem [2]. Optimalizované knihovny Je dobré vyhnout se vlastnímu řešení standardních scénářů. Autoři webových prohlížečů používají různé metody, jak zjistit místa, která je třeba zoptimalizovat, a zcela jistě velká část těchto testovacích scénářů bude zkoumat, jak rychle se provádí různé funkce z běžně používaných knihoven. Je tedy vhodné používat knihovny, které se používají často, protože to zvyšuje šanci, že prohlížeč bude na tuto knihovnu připraven. Příkladem takové knihovny může být populární JQuery 3. 2.2.2 Optimalizace přenosu Na klientskou stranu je potřeba dostat soubory (HTML, JavaScript, CSS) tak, aby prohlížeč mohl dané soubory co nejrychleji zpracovat, a poté zobrazit uživatelské rozhraní aplikace. K tomu je potřeba tyto soubory přenést ze serveru po přenosové trase. Eliminace přenosu Eliminací přenosu mizí zátěž na straně serveru, dále mizí, nebo se redukuje samotná přenosová trasa. Toho lze dosáh- 1. Dostupné z: https://angularjs.org/ 2. Dostupné z: https://facebook.github.io/react/ 3. Dostupné z: https://jquery.com/ 4
2. Optimalizace webových aplikací v ASP.NET nout využitím cache na straně klienta nebo využitím CDN serverů (více je popsáno v částech 2.3.1 a 2.3.4). Minimalizace objemu přenesených dat HTTP komprese HTTP komprese se využívá v případě, kdy se předpokládá, že klient má dostatečně výkonný procesor na to, aby dekomprimoval komprimovaný soubor rychleji, než by trval přenos dat nekomprimovaných. Je zde určitá zátěž na serveru z důvodu komprimace a poté zátěž na klientské straně, kde se musí soubory dekomprimovat. Nicméně v dnešní době je tato zátěž typicky zanedbatelná a to z důvodu, že i podprůměrný hardware je pro tyto operace naprosto dostačující. Je také nutno zmínit, že na serveru se komprimované soubory mohou již nacházet v cache, a není proto nutné při každém HTTP požadavku na server tyto soubory znovu komprimovat. ViewState V případě webových aplikací vytvořených pomocí technologie ASP.NET Web Forms může být při optimalizaci jedno z problematických míst skryté pole ViewState. Toto pole uchovává informace, které jsou nezbytné pro provedení tzv. postbacku. Při nesprávném použití ViewState je velmi často zbytečně přenášeno velké množství dat. Řešením je úprava kódu ASP.NET stránky tak, aby se pole ViewState používalo pouze pro data, která jsou pro funkčnost stránky zapotřebí. Soubory HTML/JavaScript/CSS Pro přehlednost a dobrou čitelnost kódu je nutné dodržovat určitou strukturu, formátování a kód komentovat. Tím ovšem opět narůstá objem přenesených dat, který je nutno zredukovat. K takové redukci se využívá tzv. minifikace. Minimalizace počtu HTTP požadavků na server Mezi problémové body patří omezený počet paralelně zpracovávaných HTTP požadavků na server webovým prohlížečem. Při načítání JavaScriptu a CSS souborů je třeba počítat s tím, že webové prohlížeče mají poměrně nízký limit na počet souběžných HTTP požadavků, většinou se jedná o jednotky nebo nízké desítky paralelních vláken. V případě, že 5
2. Optimalizace webových aplikací v ASP.NET stránka potřebuje stovky souborů, nemohou se načítat všechny najednou. To při skladbě webové stránky ze spousty drobných obrázků či kaskádových stylů způsobuje sekvenční stahování jednotlivých prvků, kdy maximální počet paralelně zpracovávaných HTTP požadavků je omezen webovým prohlížečem, a vždy, když jeden HTTP požadavek skončí, tak se spustí další, což je další překážkou rychlého odbavení klientské strany [2]. Možná řešení, jež snížují počet HTTP požadavků na server například jsou: 1. Pokud stránka používá větší množství obrázku, dá se použít tzv. spriting, kdy se obrázky spojí do jednoho většího a pomocí CSS vlastnosti background-position se určí, která část obrázku se má ve stránce zobrazit. 2. Menší obrázky se dají převést do formátu data URI, kde jsou binární data obrázku zakódovaná pomocí kódování base64 a jsou přímo součástí URL adresy obrázku prohlížeč tak nemusí dělat HTTP požadavek, ale obrázek rozparsuje z této data URL. 3. Pro běžně používané ikony a symboly se dnes často používají speciální fonty, např. Font Awesome, který obsahuje stovky ikon a piktogramů. Díky tomu se nestahují desítky či stovky obrázků, ale pouze jeden soubor fontu. Navíc jsou tyto ikony vektorové, takže je možné jejich plynulé zvětšování a zmenšování. 2.2.3 Serverová optimalizace výkonu Cílem serverové optimalizace je co nejrychleji odbavit HTTP požadavek na serveru, optimalizace kódu serverové části, cacheování na straně serveru, ale také například optimalizace přístupů do databáze. Zpracování HTTP požadavku na serveru je většinou netriviální proces, který se dá rozdělit do několika kroků (např. v terminologii webového serveru IIS 4 hovoříme o tzv. request pipeline). Parsování HTTP požadavku Směrování (zjištění, který modul má HTTP požadavek obsloužit) 4. Dostupné z: http://www.iis.net/ 6
2. Optimalizace webových aplikací v ASP.NET Zpracování autentizačních hlaviček (jsou-li jaké) Autorizace (kontrola, zda má uživatel právo provést danou operaci) Zpracování HTTP požadavku modulem, což zahrnuje často velmi netriviální operace, jako například kompilaci kódu samotné stránky, dynamické vygenerování uživatelského rozhraní atd. Vystavení a zaslání odpovědi klientovi Správné použití dostupných technologií Některé technologie svádí vývojáře k provádění databázových operací neefektivně. Například komponenta SqlDataSource 5 v technologii ASP.NET Web Forms řeší stránkování databázových tabulek až na úrovni webového serveru, a ne na úrovni databáze, což snižuje výkon aplikace tím, že webový server musí přečíst celou databázovou tabulku, aby z ní nakonec použil jen velmi malé množství dat. Nastavení ASP.NET Nastavení ASP.NET se obvykle provádí v souboru web.config. Výkon aplikace může ovlivnit několik parametrů. Jedním z problémů je například nastavení elementu <compile debug= true >, který by v produkčním prostředí měl být nastaven na hodnotu false. Ponechání této hodnoty na true má negativní vliv na výkon aplikace například proto, že všechny HTTP požadavky na server pro stáhnutí resource souborů nebudou mít zapnuté klientské cacheování, a to způsobí, že při každém HTTP požadavku na server pro stažení například JavaScriptové knihovny, se daná knihovna bude pokaždé znovu a znovu stahovat. Již zmíněný atribut debug ovlivňuje také verzi knihoven, které se posílají na klientskou stranu (například různé verze JavaScriptových knihoven pro debug verzi nebo release verzi). Dalším elementem, který ovlivňuje výkon je element <trace>. Element trace obsahuje parametr enabled, který by měl být nastaven na 5. Dostupné z: https://msdn.microsoft.com/cs-cz/library/system.web.ui. webcontrols.sqldatasource(v=vs.110).aspx 7
2. Optimalizace webových aplikací v ASP.NET hodnotu false v případě, kdy není vyžadováno sledování trasovacích informací. Pokud jsou trasovací informace nezajímavé, je zbytečné jejich sběrem zatěžovat server a tím potencionálně snižovat výkon naší webové aplikace [1]. 2.3 Techniky, které vedou k optimalizovaným webovým aplikacím 2.3.1 Cacheování Jeden z nejdůležitějších faktorů při optimalizaci webových aplikací je schopnost ukládat datové objekty, stránky či části stránek do paměti již při jejich prvním získání. Tyto předměty cacheování se mohou ukládat buď na straně klienta nebo na serveru, popřípadě na cestě daného HTTP požadavku, například v proxy severu. To umožňuje předejít opakovanému získávání informací, o které již bylo dříve žádáno. Tím je šetřen procesorový čas, síťová konektivita a případně další zdroje [3]. Výhody cacheování Redukuje se čas pro získání HTTP odpovědi ze serveru Redukují se nároky na procesorový čas serveru Méně přístupů do databáze v případě, že si server databázová data cacheuje Méně odeslaných HTTP požadavků na server v případě, že je použito cacheování prohlížečem nebo cacheování na proxy serveru Cacheování umožňuje ukládat webové stránky jak na klientské, tak na serverové straně. Umožňuje také ukládat datové objekty v serverové paměti. Díky tomuto přístupu není nutno pokaždé generovat celé webové stránky při každém HTTP požadavku na server. Důsledkem je zlepšení odezvy a nižší vytížení procesoru a také databáze [1]. Cacheování je v ASP.NET velmi snadnou záležitostí, které typicky vyžaduje napsání jednoho řádku kódu pro nacacheování celé webové 8
2. Optimalizace webových aplikací v ASP.NET stránky. Na straně serveru je paměť relativně levná (pokud nebereme v úvahu častěji navštěvované aplikace, kde se využívá cacheování do souborů na disku či do dokumentové databáze) a na klientské straně nestojí vůbec nic. To dělá z cacheování velmi levný, nicméně velmi mocný nástroj pro optimalizaci webových aplikací [4]. Typy cacheování Cacheování prohlížečem Umožňuje ukládat soubory přímo v prohlížeči, tudíž není nutné pro získání těchto souborů znovu vysílat HTTP požadavek na server. Cacheovací proxy Slouží ke zrychlení odpovědi na dotaz. Při HTTP požadavku na server mohou být data odeslána již z proxy serveru, ale jen za podmínky, že stejný HTTP požadavek již daným proxy serverem prošel a při získávání dat ze servere si daný proxy server tyto data uložil do své cache. Výstupní cacheování Výstupní cacheování spočívá v tom, že výstupní data aplikace (vykreslený HTML kód, obrázek, soubor ke stažení) se ukládají pro opakované použití. Datové cacheování Snaha o uchování dat pro serverovou část (data z databází, webových služeb a jiných služeb třetích stran) tak, aby je bylo možné opakovaně použít. Cacheování prohlížečem Server může požádat prohlížeč o nacacheování obsahu na klientském počítači skrze hlavičku odpovědi serveru cache-control 6. Takto nacacheované soubory v prohlížeči přináší následující výhody: Rychlé načítání souborů prohlížeč nacacheované soubory již znovu nemusí získávat ze serveru 6. Dostupné z: https://devcenter.heroku.com/articles/ increasing-application-performance-with-http-cache-headers 9
2. Optimalizace webových aplikací v ASP.NET Snížené náklady na šířku pásma a snížení zátěže serveru prohlížeč odešle méně HTTP požadavků na server Výborná škálovatelnost čím větší je provoz, tím více klientských počítačů cacheuje naše data Cacheování prohlížečem zahrnuje ovšem i nevýhody: Nepředvídatelná životnost vzhledem k tomu, že více webových stránek se snaží nacacheovat své soubory do prohlížeče na straně klienta, tak v určitém okamžiku se prohlížeč může rozhodnout, že soubory získané z daného serveru odstraní, a to z důvodu omezené velikosti přidělené paměti pro všechny webové stránky. Zastaralý obsah je nutno reagovat na aktualizovaný obsah souborů. Vhodným řešením pro soubory obsahující obrázky, JavaScript či kaskádové styly je označení jejich verze v názvu souboru. Případně lze využít hlavičky HTTP požadavku a jejího parametru If-Modified-Since. Dále lze využít hlavičky HTTP odpovědi serveru zahrnující parametr Etag, který obsahuje hash obsahu souboru, jenž je možné využít k ověření platnosti dat uložených v cache. Bezpečnostní rizika soubor uložený na klientském počítači může přečíst neoprávněná osoba, která má k tomuto počítači přístup. Cacheovací proxy HTTP požadavky na server a odpovědi z něj mohou procházet skrze proxy servery na své cestě mezi serverem a prohlížečem. Tyto proxy servery mají možnost cacheování obsahu, který může být použit pro odbavení HTTP požadavků ostatních návštěvníků webových stránek. Například poskytovatel internetového připojení může používat proxy pro cacheování obsahu. Díky tomu se minimalizuje počet HTTP požadavků na server vyslaných skrze internet, jak je znázorněno na schématu (viz obr. 2.1) [4]. 10
2. Optimalizace webových aplikací v ASP.NET Obrázek 2.1: Schéma zobrazující proxy server v síti [4]. Využití cacheovaní proxy serverem má následující výhody: Pokud proxy server ukládá soubor, zatím co daný soubor putuje ke koncovému uživateli, může tento soubor sloužit pro jiného uživatele se stejným HTTP požadavkem. Z toho plyne, že jsou obslouženi dva klienti za cenu zatížení serveru pouze jedním klientem. Rychlejší načítání souborů geograficky je klientský prohlížeč mnohem blíže proxy serveru nežli danému webovému serveru, ze kterého se pokouší daná data získat. Stejně jako u cache prohlížeče, je také u cache proxy serveru snižována zátěž webového serveru, dále jsou snižovány náklady na šířku pásma a je zajištěna dobrá škálovatelnost. Nicméně cacheování na straně proxy serveru má i nevýhody: 11
2. Optimalizace webových aplikací v ASP.NET Bezpečnostní rizika proxy server by mohl zaslat data určená pro specifického klienta klientovi jinému, pro nějž by tato data nemusel být určena. Proxy servery obvykle necachují soubory obsahující řetězec dotazu. Cacheování proxy serverem nelze využít v případě, pokud je v odpovědi serveru zahrnuto nastavení nějaké cookie. Stejně jako cache prohlížeče i cache proxy serveru může kdykoliv smazat již nacacheovaná data z důvodu uvolnění místa pro data z jiných webových serverů. Stejně je tomu i u aktualizovaných souborů na serveru, které se v cache aktualizovat nedají. Výstupní cacheování Výstupní cacheování umožňuje ukládat na webovém serveru celé stránky nebo jejich části. Výstupní cacheování má následující výhody: Flexibilita podporuje ukládání různých verzí souborů pomocí řetězce dotazu, hlavičky HTTP požadavku či vlastní proměnné. Umožňuje ukládat do cache pouze části stránek. Životnost prvků v cache je předvídatelná, protože o paměť nesoupeří jiné webové stránky. To ovšem neplatí pro sdílený webový hosting, kde mnoho webových stránek používá stejný webový server. Výstupní cacheování má ovšem také nevýhody: Výstupní cacheování není vhodné pro cacheování specifických stránek pro konkrétního návštěvníka, protože je pak ukládáno velké množství stránek s minimálním využitím. Využívá se paměti nebo jiných zdrojů serveru. Je problém cacheovat mezi servery, protože se celá cache nachází pouze v paměti serveru. Například u serverových farem, kde každý server má svou vlastní cache, může vznikat duplicita dat 12
2. Optimalizace webových aplikací v ASP.NET na ostatních serverech. To vede k možné nekonzistenci mezi verzemi takto uložených souborů v jednotlivých cacheích každého serveru. Vyvarovat se problémů s nekonzistencí je možno použitím distribuované cache, kdy při změně dat jedním serverem se změněná položka v cache může stát nevalidní, a tak nekonzistence nenastane. Pokud se jedná o cache v operační paměti procesu webového serveru, tak v případě restartu webového serveru, ale také při recyklaci aplikačního poolu 7, obsah cache na serveru zmizí. Poslední dvě nevýhody mohou být řešeny přesunutím cache na oddělené cacheovací servery. Datové cacheování Datové cacheování je zaměřeno na cacheování individuálních objektů, které jsou užívány kódem v běhovém prostředí webové aplikace. Datové cacheování umožňuje ukládat dvojce klíčhodnota, které jsou přístupné typicky pro všechny HTTP požadavky na server dané webové aplikace [4]. 2.3.2 Snížení doby, po kterou se stránka načítá Jeden z kroků, který je vhodný pro zlepšení výkonu webové aplikace, je přesun funkcionality ze serveru do prohlížeče. Místo počítání výsledku či validaci formuláře na serveru je vhodné použít JavaScriptový kód, který poběží v prohlížeči. V důsledku toho méně uživatelských akcí způsobuje odeslání HTTP požadavku na server, a tím odpadá čekání na odpověď, což významně ovlivňuje zpětnou odezvu dané stránky. Nutno ovšem zmínit, že se validace na stranu klienta nepřesouvá, ale pouze duplikuje, aby se snížil počet HTTP požadavků. Vše co je odesláno na server, je opětovně validováno z důvodu bezpečnosti. Nevýhodou tohoto přístupu je, že kód se fyzicky musí dostat ze serveru do prohlížeče. To může ovlivnit dobu načítání stránky, zvláště pokud jsou použity velké JavaScriptové knihovny. Je potřeba najít jistý kompromis mezi rychlostí načítání stránky a její odezvou po načtení. Velké množství návštěvníků webových stránek danou stránku opustí, 7. Dostupné z: http://www.c-sharpcorner.com/uploadfile/225740/ introduction-to-application-pool-in-iis/ 13
2. Optimalizace webových aplikací v ASP.NET pokud bude mít příliš dlouhé načítací časy [4]. Snížení doby načítání stránek umožní následující postupy: Načítání JavaScriptových souborů paralelně s ostatními zdrojovými soubory Rychlejší načítání JavaScriptu Načítání JavaScriptu na vyžádání Vyhnutí se blokaci vykreslování stránky při načítání JavaScriptu Rychlejší načítání kaskádových stylů 2.3.3 Načítání JavaScriptových souborů paralelně s ostatními zdrojovými soubory Tento krok se zaměřuje na rychlejší vykreslení webové stránky využívajícího paralelního načtení souborů s kaskádovými styly, obrázky a JavaScriptem. Při použití tohoto přístupu se kaskádové styly s obrázky načtou dříve, než doběhne načtení JavaScriptu, nebo alespoň nebude jejich načítání trvat tak dlouho po dokončení načítání JavaScriptu [4]. K tomu, aby bylo možné načítat paralelně sobory s kaskádovými styly spolu s JavaScriptem stačí nejprve načíst soubory s kaskádovými styly a až poté JavaScriptové soubory (viz obr. 2.2). Obrázek 2.2: Příklad zápisu deklarace externích souborů, který umožňuje paralelní stahování souborů s kaskádovými styly spolu s JavaScriptem [4]. Načítání obrázků zároveň s JavaScriptem je o něco složitější, protože obrázky bývají součástí těla stránky (element <body> v HTML kódu), tudíž jejich deklarace se nenachází v hlavičce. 14
2. Optimalizace webových aplikací v ASP.NET Aby načítání obrázku začalo před načítáním JavaScriptu, je možné použít jednoduchý JavaScriptový kód (viz obr. 2.3), který spustí načítání obrázků dříve. Tato technika se označuje jako image preloading [4]. Obrázek 2.3: Příklad zápisu deklarace externích souborů, který umožňuje paralelní stahování obrázků spolu s JavaScriptem [4]. 2.3.4 Rychlejší načítání JavaScriptu Dalším krokem je rychlejší načtení stejného JavaScriptového souboru, což umožní návštěvníkům stránek trávit méně času čekáním, než se stránky kompletně načtou. Existují následující techniky, které vedou k rychlejšímu načítání JavaScriptových souborů. Existují následující techniky, které vedou k rychlejšímu načítání JavaScriptových souborů: Techniky související s obrázky, jako je cacheování či paralelní stahování Použití Content Delivery Network (CDN) GZIP komprese 8 Minifikace Kombinování nebo dělení JavaScriptových souborů Odstranění nepoužívaného kódu 8. Dostupné z: http://tomaserlich.cz/gzip-komprese-css-a-js/ 15
2. Optimalizace webových aplikací v ASP.NET Techniky související s obrázky Stejně jako soubory s kaskádovými styly, tak i soubory s JavaScriptem jsou statické. To znamená, že mnoho technik, které lze aplikovat na obrázky, lze aplikovat i na JavaScriptové soubory, jež zahrnují cacheování a paralelní načítání. Použití Content Delivery Network Přiblížením statických souborů návštěvníkům stránek způsobí rychlejší odpovědi na HTTP požadavky. Toho lze docílit umístěním statických souborů umístěných na serverech CDN. CDN je světová síť serverů, které přibližují statický obsah webových stránek blíže návštěvníkům. Například pokud je daný webový server umístěn v Evropě a dané webové stránky bude chtít navštívit návštěvník sídlící v USA, tak pro stažení statického obsahu se využije jeden ze serverů sítě CDN, který je nejblíže tomuto návštěvníkovi. Distribuce statických souborů skrze CDN může velmi redukovat dobu stahování statických souborů, a to v případech, kdy servery CDN jsou blíže návštěvníkům daných stránek, než je tomu u daného webového serveru. GZIP komprese Webový server IIS umožňuje komprimovat obsah odeslaný do prohlížeče, jenž zahrnuje soubory s JavaScriptem a kaskádovými styly. Komprese může přinést dramatické rozdíly ve velikosti přenášených souborů. Na příkladu produkční verze knihovny jquery můžeme vidět, jak moc se změní velikost komprimovaného souboru (viz tabulka 2.1). Bez komprese jquery v1.3.2 120KB 35KB GZIP komprese Tabulka 2.1: Redukce velikosti knihovny při použití GZIP komprese. Minifikace JavaScriptových souborů Aby byla zajištěna přehlednost JavaScriptového kódu, obsahují JavaScriptové soubory mnoho komentářů a bílých znaků, které jsou pro prohlížeč nadbytečné. Minifikace JavaScriptových souborů odstraní tyto nepotřebné komentáře a bílé znaky, což vede ke zmenšení těchto souborů a zkrácení doby pro jejich stažení ze serveru. Také vývojáři nemusí mít obavy, že přidáním 16
2. Optimalizace webových aplikací v ASP.NET dalších komentářů zvětší velikost daného souboru a tím zvýší nároky na přenos takto zvětšeného souboru. Některé nástroje pro minifikaci souborů zkracují i názvy proměnných. To je velmi užitečné v případě, že daný server nepoužívá GZIP kompresi. V případě, že je komprese na serveru zapnuta, zmíněné zkracování názvů proměnných bude mít jen malý vliv na zmenšení samotného souboru, protože algoritmy použity pro kompresi jsou velmi dobře vyladěny na zkracování opakujících se řetězců, jako jsou například již zmíněné názvy proměnných [4]. Dopad minifikace Jak moc velký vliv má minifikace ve srovnání s GZIP kompresí? Zde je uvedeno srovnání těchto dvou přístupů na příkladu nekomprimované knihovny jquery ve verzi 1.3.2, kdy pro minifikaci byl použit nástroj YUI Compressor verze 2.4.2 (viz tabulka 2.2). Z výsledků vyplývá, že nejvhodnější je kombinace minifikace s GZIP kompresí. I když již samotná GZIP komprese je dosti účinná. Bez komprese Neminifikovaná 120KB 35KB Minifikovaná 74KB 21KB GZIP komprese Tabulka 2.2: Redukce velikosti knihovny při použití GZIP komprese a minifikace. Kombinování nebo dělení JavaScriptových souborů Častým krokem ke snížení doby načítání JavaScriptových souborů je kombinování více souborů do jednoho velkého souboru, díky čemuž je načítán pouze jeden velký JavaScriptový soubor. Alternativou je naopak z velkého JavaScriptového souboru udělat více malých souborů a ty načítat paralelně. Oba přístupy se vyplatí vždy v jiném případě. V okamžiku, kdy existuje velké množství jednotlivých souborů, které značně převyšuje maximální počet paralelně stahovaných souborů, jenž je dán prohlížečem, v tom případě je vhodné uvažovat o zkombinování některých souborů do jednoho velkého. Naopak, pokud počet načítaných souborů je nižší, v tom případě je vhodné větší soubory rozdělit na více menších. 17
2. Optimalizace webových aplikací v ASP.NET Mít soubory rozdělené je také vhodné v situaci, kdy je aplikace velmi rozsáhlá a ne všechny soubory se využívají na všech stránkách. Pokud běžný uživatel využije jen malou část ze všech dostupných stránek, je vhodné na to reagovat smysluplným rozdělením souborů, aby byl distribuován pouze kód, jenž dané stránky využívají. Odstranění nepoužívaného kódu Z důvodu, že JavaScriptový kód je oddělen od HTML elementů uživatelského prostředí, je velmi jednoduché zapomenout odstranit kód, který již nebude nadále třeba. 2.3.5 Načítání JavaScriptu na vyžádání JavaScriptový kód se zpravidla dělí na dvě části. Kód potřebný pro vykreslení stránky a kód, který obsluhuje uživatelské rozhraní (například události typu click ). Kód vykreslující stránku slouží pro lepší vzhled stránky samotné a také pro napojení jednotlivých ovládacích prvků (například tlačítek). Vykreslující kód vyžaduje načtení spolu se stránkou, zatímco kód obsluhující uživatelské rozhraní může být načten teprve v okamžiku, kdy je potřeba zareagovat na nějakou událost (například zmíněnou událost typu click ). Tím se redukuje množství načítaného kódu při pouhé návštěvě stránky. Nicméně pokud je třeba volat kód obsluhující uživatelské rozhraní, je nutno počítat se zdržením a návštěvníkovi stránek sdělit, že se kód načítá (více o možnostech jakým způsobem uživatele informovat o načítání kódu je popsáno v sekci Indikace načítání stránky). 2.3.6 Vyhnutí se blokaci vykreslování stránky při načítání JavaScriptu Idea je načíst téměř všechny skripty tak, aby neblokovaly vykreslování stránky. Důsledkem toho je dřívější zobrazení vykreslené webové stránky uživateli. Existují následující cesty jak tomuto jevu předejít, případně je třeba seznámit uživatele se vzniklou situací: Přesunutí všech HTML elementů <script> na konec stránky 18
2. Optimalizace webových aplikací v ASP.NET Oddělení vykreslovacího kódu od kódu obsluhujícího uživatelské rozhraní Indikace načítání stránky Přesunutí všech HTML elementů <script> na konec stránky Na základní úrovni je zabránění blokace vykreslování stránek velmi jednoduché. Jednoduše se přesunou HTML elementy <script> z elementu <head> na konec elementu <body>. Díky tomu se stránka vykreslí dříve, než element <scrtipt> dostane šanci cokoliv blokovat. Oddělení vykreslovacího kódu od kódu obsluhujícího uživatelské rozhraní Kód potřebný pro vykreslení stránky obvykle bývá mnohem menší, než je tomu u kódu obsluhujícímu uživatelské rozhraní. A abychom předešli zobrazení našich stránek v surovém stavu, je vhodné načíst kód vykreslující stránku předem. Sice bude pozdrženo vykreslování samotné stránky, nicméně v tomto případě je to žádoucí. Kód obsluhující uživatelské rozhraní se načte až nakonec, nebo jak bylo zmíněno výše, na vyžádání. Nicméně uživatel již před načtením oddělených skriptů obsahující obsluhu uživatelského rozhraní vidí ovládací prvky tohoto rozhraní, a při stisku některého z tlačítek se mu může jevit, že stránka nefunguje. Z toho důvodu je vhodné o načítání stránky uživatele informovat [4]. Indikace načítání stránky Aby byl uživatel informován, že stránka ještě není zcela načtena, je vhodné mu zobrazit indikátor načítání stránky do doby, než bude stránka v použitelném stavu. Toho lze docílit jednoduše. Stačí k tomu obyčejný element <div>, který bude obsahovat text Načítá se..., nicméně je možné využít i sofistikovanější způsoby. Po načtení kódu stačí jednoduše tento indikátor skrýt [4]. 2.3.7 Rychlejší načítání souborů s kaskádovými styly Stejně jako JavaScript, tak i kaskádové styly blokují vykreslování stránky. To způsobuje, že návštěvník stránek vidí prvky až v jejich stylované podobě, což je žádoucí. Načítání souborů s kaskádovými styly také blokuje načítání JavaScriptových souborů, a to z důvodu možné existence 19
2. Optimalizace webových aplikací v ASP.NET referencí uvnitř JavaScriptových souborů na definice v souborech s kaskádovými styly. Je tedy žádoucí, aby soubory s kaskádovými styly byly načítány co nejrychleji. K tomu je vhodné použít následující techniky: Techniky související s obrázky, jako je cacheování či paralelní stahování Použití Content Delivery Network (CDN) GZIP komprese Kombinování nebo dělení souborů s kaskádovými styly Minifikace Odstranění nepoužívaného kódu Všechny tyto techniky již byly popsány v kapilole 2.3.4, proto jsou níže popsány pouze techniky, které se odlišují v principu samotného kódu. Minifikace Minifikace souborů s kaskádovými styly je velmi podobná jako minifikace JavaScriptových souborů. Minifikace zahrnuje odstranění nadbytečných bílých znaků a komentářů. Také je možné využít nahrazení hodnot jednotlivých vlastností za kratší zápis. Například barva s hodnotou #ff0000 může být nahrazena kratší hodnotou red. Dopad minifikace Dopad minifikace závisí na tom, zda je povolena komprese na serveru. V případě že povolena není, je dopad minifikace výrazný. V opačném případě je redukce velikosti souboru jen velmi malá [4]. Odstranění nepoužívaného kódu Protože kód s kaskádovými styly je oddělen od stránek, ve kterých je používán, je velmi jednoduché zapomenout smazat již nepoužívaná pravidla, která v souboru zbyla po odstranění HTML elementů, jež se k těmto pravidlům vázaly. 20
2. Optimalizace webových aplikací v ASP.NET Pro odhalení a zároveň pro odstranění nepotřebných selektorů v souborech s kaskádovými styly existují nástroje ve formě rozšiřujících doplňků do prohlížečů. Tyto nástroje dokáží odhalit, zda některá ze stránek nevyužívá na první pohled nepotřebný selektor, a po důkladné analýze nevyužívané selektory smaže. Příkladem těchto nástrojů je například Dust-Me Selectors určen pro prohlížeč Firefox, či nástroj CSS remove and combine doplněk prohlížeče Chrome [4]. 2.4 Užitečné nástroje pro optimalizaci webových aplikací 2.4.1 Diagnostické nástroje klient + přenos Fiddler Jednoduchý nástroj, který se spustí na straně klienta, kde se chová jako proxy server a zachytává HTTP komunikaci [5]. YSlow Nástroj pro analýzu webových stránek, který dokáže zobrazit konkrétní příčiny pomalého běhu webových stránek a na základě získaných dat přidělí dané stránce hodnocení [6]. 2.4.2 Diagnostické nástroje webového serveru ASP.NET <trace/> Přehled o tom, co se děje na serverové části nám může dát zapnuté trasování. Výstup trasovacích informací obsahuje čas strávený v jednotlivých fázích životního cyklu webové stránky, což nám umožňuje lokalizovat, kde dané zpracovávání není optimální a zda je to vůbec problém serveru. V trasovacích informacích je obsažena i velikost ViewState, která je dána jednotlivými HTTP požadavky a je možné zde odhalit, problémy právě pramenící z velké velikosti ViewState [1]. WCat Nástroj WCat dokáže paralelně spustit několik klientů, kteří budou jednotlivě generovat sekvenční zátěž na zaznamenanou sérii HTTP požadavků. Je zde možnost nastavit počet virtuálních klientů, možnost nastavit, vůči kterému serveru se bude aplikace spouštět a možnost nastavit dobu trvání daného testu [7]. 21
2. Optimalizace webových aplikací v ASP.NET RedGate ANTS Profiler Tento nástroj funguje tak, že se připojí na již běžící webovou aplikaci, případně si ji spustí sám. Po dobu připojení na danou aplikaci snímá veškerá data vyjadřující chování dané aplikace, zejména trasování kódu, a poté zobrazí počet volání jednotlivých metod a dobu, kterou daný proces v dané metodě strávil. Při nastavení detailního trasování je možné určit časovou ztrátu na úrovni řádků kódu, kdy je možné zobrazit informaci o tom, kolik milisekund se strávilo na nejdéle vykonávaném řádku kódu a jaká je procentuální hodnota této časové ztráty z celkového času po který aplikace běžela. Je nutno zmínit, že tento nástroj velmi ovlivňuje výkon samotné aplikace, tudíž z naměřených výsledků by nás měl spíše zajímat procentuální čas jednotlivých akcí nežli skutečná naměřená hodnota v jednotkách času [2]. PerfView Nástroj pro sběr informací z produkčního serveru. Na produkčním serveru si nemůžeme dovolit spustit výše zmíněný RedGate ANTS Profiler, jež zásadně ovlivňuje výkon měřené aplikace. PerfView se nijak nepřipojuje na danou aplikaci, ale jen sbírá data z událostí systému Windows, kterých je takové množství, že se můžeme dovědět srovnatelné informace jako z již zmíněného nástroje RedGate ANTS Profiler. Zpomalení serveru je tvořeno pouze vlastní režií, jež je tvořena odchytáváním dat, které se ukládají do paměti a poté na pevný disk. Čili je zde potřebné počítat s drobným zpomalením serveru, které ale většinou nebývá pro provoz nijak zásadní [2]. 2.4.3 Nástroje určeny pro bundling a minifikaci Microsoft Ajax Minifier Nástroj byl původně vytvořen jako interní nástroj společnosti Microsoft, který byl ovšem časem uvolněn pro volné užití. Jedná se o velmi efektivní nástroj pro minifikaci JavaScriptových souborů a souborů s kaskádovými styly [2]. Microsoft.Web.Optimization.dll Knihovna pro bundling a minifikaci JavaScriptových souborů či souborů s kaskádovými styly. 22
3 Framework DotVVM 3.1 Motivace pro vývoj webových aplikací ve frameworku DotVVM Součástí platformy ASP.NET jsou technologie ASP.NET Web Forms 1, ASP.NET MVC 2 a ASP.NET Web API 3. Web Forms jsou v dnešní době již zastaralé, MVC a Web API se dnes typicky používají v kombinaci s populárními JavaScriptovými frameworky Angular nebo React, ovšem je zde několik problémů, se kterými tyto technologie v ASP.NET prostředí naráží. Požadavky na dnešní webové aplikace nejčastěji jsou, aby byly responsivní, atraktivní, interaktivní a aby byly načteny v co nejkratším čase. Neexistuje pádný argument, aby se každá webová stránka celá znovu načítala po triviálních operacích, jakou je například odeslání formuláře metodou POST pomocí tlačítka typu submit. Běžně se totiž stává, že při změně jen části webové stránky se musí celá stránka znovu překreslit, což není uživatelsky přívětivé [8]. Při těchto požadavcích brzy zjistíme, že používáním zavedených frameworků, kterými bezesporu jsou ASP.NET MVC nebo ASP.NET WebForms, není možné dostatečně naplnit výše zmíněné požadavky. Respektive možné to je, nicméně to vyžaduje značné úsilí s využitím AJAX (Asynchronous JavaScript and XML) [8]. Pokud porovnáme aplikaci, která na stisk tlačítka reaguje klasickým HTTP POST požadavkem, s aplikací, jež reakci na tlačítko odbaví pomocí JavaScriptu a AJAXového volání, je druhá varianta pro uživatele mnohem přirozenější a přívětivější. Tato druhá varianta též přenáší typicky méně dat, protože se celá stránka nestahuje znovu, nýbrž si klient se serverem pouze vymění data, která se ve stránce mají změnit, typicky ve formátu JSON nebo XML [8]. Velké množství zákazníků, kteří si chtějí nechat vyvinout webovou aplikaci, často požaduje pouze Single Page Application 4 (dále jen SPA), 1. Dostupné z: http://www.asp.net/web-forms 2. Dostupné z: http://www.asp.net/mvc 3. Dostupné z: http://www.asp.net/web-api 4. Dostupné z: http://arxiv.org/ftp/arxiv/papers/1502/1502.03530.pdf 23
3. Framework DotVVM protože nechtějí, aby se jim neustále znovu načítaly webové stránky a skripty. Při navštívení SPA se načte hlavní stránka a všechny skripty, které jsou potřeba, a poté si již klient se serverem vyměňuje data ve formátu JSON, případně si stahuje jen relevantní části uživatelského rozhraní v HTML. Data jsou typicky do HTML vkládána pomocí JavaScriptového kódu, nebo je JavaScirptem generovaná podstatná část DOM stromu. SPA může obsahovat mnoho stránek s komplexními formuláři. Tyto aplikace jsou většinou psané s využitím frameworků/knihoven, jež například jsou ReactJS, AngularJS nebo KnockoutJS 5. Na straně serveru se běžně používá ASP.NET WebAPI nebo také ASP.NET MVC v kombinaci s ASP.NET WebAPI. Obrázek 3.1: Ukázka komunikace klient server v případě SPA. V prvním kroku si prohlížeč stáhne potřebné soubory (HTML, CSS, JavaScript), a poté již komunikace probíhá pouhým předáváním dat ve formátu JSON. 5. Dostupné z: http://knockoutjs.com/ 24
3. Framework DotVVM 3.1.1 Pro vývoj webových aplikací je nutná znalost mnoha technologií Problém dnešních aplikací psaných ve frameworcích jako je AngularJS, ale i dalších, je mnoho zbytečného JavaScripteového kódu, který ve skutečnosti nedělá nic zvláštního, pouze obsahuje volání API, které přečte odpovědi ze serveru, popřípadě zpropaguje data ze serveru do uživatelského rozhraní. Přitom většina takto psaného JavaScriptového kódu by mohla být generována. Je to problém také pro začínající vývojáře, kteří se musí naučit mnoho programovacích jazyků, mnoho frameworků, ale také znát mnoho knihoven [8]. V roce 2005, kdy jednou z předních technologií pro vývoj webových aplikací byly ASP.NET WebForms, stačila pouze znalost programovacího jazyka C# a znalost HTML. Takto vytvořené aplikace sice nebyly srovnatelné s dnešními aplikacemi, jež jsou vyvíjeny pomocí výše zmíněných frameworků, nicméně pro vývoj jednoduché webové aplikace nebylo potřebné znát tolik technologií a pro začátečníky byl vývoj velmi dobře uchopitelný [8]. Dnes vývojář musí znát některý z výše uvedených frameworků, které zajišťují běh aplikace na straně klienta, měl by použít jquery UI, nebo jiný druh ovládacích prvků a widgetů, protože ovládací prvky v čistém HTML nejsou příliš uživatelsky přívětivé a ve většině případů nefungují přesně dle představ uživatelů. Z uvedených informací plyne, že jsou potřeba knihovny například pro komponentu Date- TimePicker 6 nebo pro vzhledově přijatelný combobox a další jiné součásti webové aplikace. Je potřebná také znalost konceptů pro vývoj v JavaScriptu (např. RequireJS). Velké množství vývojářů nerozumí JavaScriptu do hloubky, dokáží pouze deklarovat funkci a proměnnou, ale nemají přehled o tom, jak fungují objekty či prototypy. V situaci, kdy je nutno psát velké množství JavaScriptového kódu, je vhodné naučit se Typescript, pro snadnější implementaci JavaScriptového kódu. Frameworky Angular a React se bez pokročilých znalostí JavaScriptu používat téměř nedají [8]. 6. Dostupné z: http://demos.telerik.com/kendo-ui/datetimepicker/index 25
3. Framework DotVVM 3.1.2 Stránkování, řazení, filtrování Pokud potřebujeme efektivní stránkování, řazení či filtrování dat z databázových tabulek, které budou zobrazeny uživateli, není vhodný způsob načíst miliony záznamů na klientskou stranu a poté je filtrovat. Zde je většinou nutné použití vlastního řešení skrze vlastní API, jež bude zahrnovat parametry jako je velikost stránky, index stránky nebo funkci například pro řazení sloupců. Alternativně je možno například využít protokol OData 7, který se snaží tento problém řešit. V případě použití protokolu OData je nuntno pro něj mít podporu ve vlastním API a také je nutno použít další knihovnu, díky které bude možné s protokolem OData pracovat na klientské straně. Navíc je nutno počítat s omezenými možnostmi například při složitějším filtrování [8]. 3.1.3 Validace Další problematikou je validace. Vše je nutno validovat na straně serveru, a to z důvodu bezpečnosti. Nicméně vhodná je i validace na straně klienta. Není ideální, aby uživatel například při odeslání formuláře čekal na odpověď ze serveru, která by mu jen oznámila, že některé z polí je nesprávně vyplněno. Z toho důvodu je vhodné doplnit validaci některých formulářů validací JavaScriptovou. Tato validace neslouží jako náhrada za serverovou, nýbrž ji jen duplikuje pro přívětivější vnímání uživatelského rozhraní [8]. Existují ovšem i situace, kdy validaci na klientovi provést není možné, například když kontrolujeme unikátnost e-mailové adresy uživatele, k čemuž potřebujeme přistupovat do databáze. Je tedy užitečné mít v aplikaci mechanismus, který umí s validačními pravidly a chybami pracovat jednotně, ať už jsou na serveru, či na klientovi. Toto opět kombinace technologií Angular a ASP.NET Web API neřeší a je nutné tento problém řešit vlastními silami [8]. 3.1.4 Zobrazení data a času Jedním z dalších častých problémů je zobrazení data a času ve formátu přirozeném pro uživatele. Bylo by vhodné, kdyby formát data a času 7. Dostupné z: http://www.odata.org/ 26
3. Framework DotVVM byl formátován stejným způsobem, jak na serverové části, tak na klientské, v různých zemích s různými pravidly. K tomu účelu je možno využít knihovnu Globalize.js 8, která umí zachovat stejné formátovací pravidla na straně klienta i na straně serveru. Tato knihovna nicméně existuje v mnoha verzích a obsahuje mnoho nepříjemných chyb, které její použití zásadně ztěžují [8]. 3.1.5 Lokalizace Určité části aplikace jsou lokalizovány na serveru, kde se nacházejí nějaké RESX soubory, které obsahují přeložené texty. Je mnoho nástrojů, které po načtení RESX souboru daný text přeloží a vygenerují lokalizovaný text. Čili zde není nutné řešit vlastní způsob lokalizace. Nicméně na straně klienta je nutno vytvořit vlastní řešení. Existují sice knihovny pro lokalizaci na klientské části, nicméně je nutné je napojit na data z RESX souborů skrze nějaké API, které je opět nutné řešit vlastními prostředky [8]. 3.1.6 Vytváření vlastních komponent Ve větších aplikacích je často třeba mít vlastní komponenty, které obsahují JavaScriptový kód nebo soubory s kaskádovými styly, a tyto komponenty poté sdílet mezi několika projekty. S dnešními technologiemi je to velmi obtížné, protože je nutno zahrnout jednak serverový kód komponenty samotné, dále skripty, soubory obsahující kaskádové styly, a to vše se musí distribuovat do různých aplikací, což měla svého času poměrně dobře řešena technologie ASP.NET Web Forms. Bohužel aktuálně preferované ASP.NET MVC tento problém uspokojivě neřeší [8]. 3.2 DotVVM DotVVM je open source framework kompatibilní s technologií ASP.NET. Jeho cílem je vyřešit problémy zmiňované v předcházející kapitole, a poskytnout kompletní platformu, která umožní vývoj moderních webových aplikací splňující současné nároky uživatelů, a zároveň 8. Dostupné z: https://github.com/jquery/globalize 27