Zmenšujeme JavaScript

Rychlosti internetových přípojek stále rostou a na nějaký ten megabajt dnes už skoro nikdo nehledí (uživatelé mobilního připojení to mohou vidět jinak). Přesto není příliš přívětivé posílat návštěvníkům stránek velké obrázky nebo skripty o velikosti stovek kilobajtů. V článku si ukážeme, jak zmenšit skripty v JavaScriptu.

V programování se, stejně jako v životě, setkáme se spoustou protichůdných rad, jako je třeba známá dvojice přísloví „Mluviti stříbro, mlčeti zlato“ a „líná huba – holý neštěstí!“ Takovou programátorskou obdobu tvoří dvojice požadavků, kdy jeden říká, že by zdrojový kód programu měl být hojně dokumentovaný, aby se v něm vyznali i ostatní, a proti němu jde požadavek nezatěžovat přenosovou linku nefunkčními zbytečnostmi, přičemž právě dokumentační komentáře jsou z hlediska funkce programu zcela zbytné.

Tento paradox, ostatně jako spousta dalších, je jen zdánlivý. Důležité je aplikovat správné pravidlo ve správné situaci. Tedy: Když píšeme program, tak jej hojně komentujeme a odsazujeme a zpřehledňujeme, ale když jej posíláme na server nebo dokonce klientovi, tak z něj všechny „zbytečnosti“ (věci, které stroj stejně ignoruje) předem vypustíme tak, aby program fungoval stále stejně, ale byl menší. (Na webu, plném interpretovaných jazyků, paradoxně „menší“ znamená často i „rychlejší“.)

Zmenšit lze téměř vše, co se na běžné webové stránce vyskytuje – obrázky, skripty, styly i HTML kód. Zmenšené soubory lze navíc před posláním zkomprimovat např. pomocí gzip, pokud prohlížeč tuto techniku podporuje (většina ano). Ale o téhle metodě v článku řeč nebude. Řeč bude o nástrojích, které zmenší skripty pomocí ekvivalentních úprav – tedy takových, kdy je funkce zachována, ale výsledný kód je menší. Omezíme se na nástroje pro JavaScript, zmenšovače HTML a CSS necháme stranou, i když principiálně jsou metody podobné.

Jak zmenšit skript

První krok ke zmenšení jsme si už řekli: Vypusťte všechny komentáře. Ti nejpečlivější programátoři tak mohou ušetřit i přes 80 procent dat. Vypustíme všechny poznámky, všechny informace o verzi, všechny licenční informace (pokud to lze) – nebo myslíte, že do zdrojového kódu vašeho dynamického menu v JavaScriptu kouká někdo, kdo takové informace ocení?

Druhý krok ke zmenšení je rovněž jasný: Vyhoďte zbytečné mezery, odřádkování, tabelátory, zkrátka veškeré „bílé znaky“. Interpret je stejně přeskakuje, tak mu ušetřete práci (a než mě někdo chytí za slovo, tak dodám, že jsou jazyky, kde odsazení má svou syntaktickou roli, proto zdůrazňuji nadbytečné mezery).

Třetí krok: Zkraťte identifikátory. Z hlediska programátorského stylu je samosebou dobré, pokud se funkce jmenuje kontrolaHodnoty(), ale pokud je volána na patnácti místech (některé formuláře jsou už takové…), tak nám její přejmenování na k() ušetří skoro čtvrt kilobajtu. Přejmenujte proměnné na jednoznakové – ano, přesně tak, jak se to nemá dělat, když píšete kód.

Dovolte odbočku: V jisté firmě jsem narazil na interní pravidlo, které říkalo, že žádná proměnná se nesmí jmenovat i, j, q, abc0 nebo podobné nicneříkající jméno, a vedoucí programátor na tomto pravidle zcela rigidně lpěl, a ani konvenci „interní proměnné cyklu jsou i, j…“ neuznával, takže konstrukce for (var promennaCyklu=0; promennaCyklu<pocet; promennaCyklu++) byla zcela běžná. Pravidlo zvítězilo nad zdravým rozumem… Každopádně: Dovedete si představit úsporu přenášených dat zkrácením jmen proměnných v téhle firmě?

Čtvrtý krok ke zmenšení skriptů je: Napište to jinak, a kratší!

Vedlejším efektem většiny zkracovacích postupů je „znečitelnění“ zdrojového kódu. V hodně zmenšeném kódu už nikdo nic ručně neopraví a pravděpodobně z něj ani nevyčte – což sice přináší nutnost udržovat vedle sebe verze „rozbalené“ a „sbalené“, ale na druhou stranu se může „znečitelnění“ někdy hodit.

Problém těchto metod je, že jsou poněkud pracné na ruční provozování pokaždé, když změníme zdrojový kód. Proto vznikly „zkracovače kódu“, které výše uvedené kroky udělají automaticky za vás. Jsou dostupné v nejrůznějších podobách – od programů přes skripty v PHP, Pythonu atd. až po webové služby. Ukážeme si tři nejznámější nástroje pro zmenšení JavaScriptu: JSPacker, YUI Compressor a Closure Compiler, a lehce porovnáme jejich schopnosti.

JSPacker

Autorem JSPackeru je známý javascriptový programátor Dean Edwards. Jeho packer nabízí kromě základního zkrácení (vypuštěním komentářů a mezer) i zkrácení identifikátorů a cosi, co nazývá „Base62 encode“, při kterém je celý zdrojový text rozsekán na řetězce, opět složen a zprovozněn pomocí eval()  – takto upravené zdrojové kódy poznáte podle charakteristického „podpisu“: začínají textem eval(function(p,a,c,k,e,r). Pro porovnání jsem vybral zdrojový kód algoritmu SHA-256, který pochází z webu Webtoolkit. Velikost tohoto kódu v nezabalené podobě je 4182 byte. Porovnání jednotlivých metod komprese pak vypadá takto (první sloupec obsahuje název metody, druhý velikost výsledného souboru, třetí kompresní poměr:

JSPacker – porovnání výkonu kompresních metod
Prostá komprese 3073 0.735
Shrink variables 2802 0.67
Base62 3054 0.73
Base62 + Shrink 2962 0.708

Vidíte, že vypuštěním komentářů, vypuštěním mezer a přejmenováním proměnných a funkcí jsme ušetřili třetinu objemu. U takto malého souboru není úspora metodou Base62 vidět, ale např. u velkých knihoven (jQuery) je rozdíl velmi markantní (zmenšení na 0.8 se Shrink vs. zmenšení na 0.55 při použití Base62).

Packer je dostupný i jako aplikace v PHP, Perlu, .NETu a WSH: Packer download.

YUI Compressor

Yahoo nabízí v rámci svého open source projektu YUI (Yahoo User Interface) i kompresor, nazvaný prostě YUI Compressor. Na rozdíl od předchozího nástroje je YUI Compressor aplikace napsaná v Javě a volaná přes příkazový řádek (lze ji tedy použít a zakomponovat do deploy procesu a skripty zmenšovat transparentně až v okamžiku nasazení na server). Nabízí zhruba srovnatelné možnosti jako předchozí packer, výsledky má u velkých knihoven nepatrně horší, u testovací SHA-256 byl o několik bajtů lepši.

Google Closure Compiler

Poměrně novým nástrojem pro zmenšování zdrojových souborů v JavaScriptu je Google Closure Compiler, součást sady Closure Tools. Práce s ním je popsána poměrně podrobně v článku Compressing your JavaScript with Closure Compiler.

Samotný Compiler je open-source nástroj, který si můžete stáhnout. Google jej však nabízí i jako službu, a to jednak přes webové rozhraní, jednak přes RESTful API. Compiler nabízí tři úrovně komprese: První dvě odpovídají předchozím nástrojům (tedy vynechání mezer a komentářů, resp. totéž se zkrácením identifikátorů), třetí (Advanced) realizuje to, co jsme si v úvodu popsali jako bod 4: Přepracujte kód.

Ano, Closure Compiler vaše skripty přepíše: Vynechá nepoužité funkce, některé funkce převede na inline tvar, přejmenuje identifikátory, vyhodnotí zapsané konstantní výrazy, … Přepsáním kódu lze dosáhnout (podle Google) až dvoutřetinové úspory místa. Vedlejším efektem je kontrola správnosti kódu.

S testovacím souborem SHA-256 dosáhl Closure Compiler na úrovni Advanced velikosti 2182 bajtů, což představuje kompresní poměr 0.53.

Při testování pozor! Pokud budete kompilovat pouze soubor s knihovními funkcemi na Advanced, dostanete ultimátní kompresní poměr 0. Vysvětlení je jednoduché: Protože soubor obsahuje pouze funkce, které nejsou nikde volány, usoudí Compiler, že jsou zbytečné, a vyhodí je. Proto je potřeba funkce, které jsou volány odjinud, „exportovat“. Dokumentace doporučuje např. trik s přiřazením do objektu window: window['SHA256'] = SHA256;   čímž se funkce stane „použitou“, a Compiler ji nevyhodí.

Závěrem

Výše popsané metody zmenšování JavaScriptu nejsou rozhodně všechny, ale představují průřez těmi nejznámějšími. Z dalších nástrojů stojí za zmínku dva: Pravděpodobně prvním známějším JS packerem byl JSMIN Douglase Crockforda. Knihovna Dojo používá vlastní minifier s názvem Dojo ShrinkSafe. Srovnání těchto zmenšovačů, JSPackeru a YUI Compressoru nabízí web Javascript Compressor and Comparison Tool.

Samosebou lze výsledky takto zkrácených kódů gzipovat a ušetřit tak další kilobajty přenosového pásma.

Zdánlivě vypadá úspora pár kilobajtů jako nevýznamná; když si ji však vynásobíme počtem návštěvníků webu, objeví se rázem v jiném světle – ušetřených 100 kB se na větším webu celkem rychle promění v gigabajty (zbytečně) přenesených dat… Navíc s rozšiřováním mobilního webu, který je zatím leckdy pomalý a/nebo omezený FUP co do objemu přenesených dat, je úspora přenesených dat rozhodně zajímavá.

Začal programovat v roce 1984 s programovatelnou kalkulačkou. Pokračoval k BASICu, assembleru Z80, Forthu, Pascalu, Céčku, dalším assemblerům, před časem v PHP a teď by rád neprogramoval a radši se věnoval starým počítačům.

Komentáře: 23

Přehled komentářů

Daniel Steigerwald Doplnění, zkušenosti z praxe, užitečné odkazy
Martin Malý Re: Doplnění, zkušenosti z praxe, užitečné odkazy
Daniel Steigerwald Re: Doplnění, zkušenosti z praxe, užitečné odkazy
Martin Malý Re: Doplnění, zkušenosti z praxe, užitečné odkazy
aichi Re: Doplnění, zkušenosti z praxe, užitečné odkazy
msgre Zpátečka
Petr MS minifier
Martin Malý Re: MS minifier
Callo Výkon
krocek Re: Výkon
Martin Malý Re: Výkon
Sadám husa Re: Výkon
* obfuskator
aprilchild gzipujte
František Kučera Re: gzipujte
m. Re: gzipujte
Daniel Steigerwald Re: gzipujte
_r3450n_ Titulek
Martin tabelátor
OneHalf deployment
František Kučera Re: deployment
kvr Re: deployment
aichi Re: deployment
Zdroj: https://www.zdrojak.cz/?p=3197