Jak udržet velikost produkčního JavaScriptu na uzdě
S masivním rozvojem JavaScriptu drží krok i mnoho dalších zajímavých technologíí, bez kterých by se budování rozlehlých frontendových JavaScriptových aplikací neobešlo. Jednou z nich je třeba i webpack (v aktuální verzi 3). Nedávno jsem potřeboval tuto technologii použít pro vytvoření produkčního bundlu a setkal jsem se s mnoha návody a doporučeními, jak to udělat co nejlépe. Nakonec mi vlastně žádná rada nepomohla, protože jsem zjistil, že je problém jinde.
Webpack je velmi zajímavá hračička, která nám umožní podle námi definovaných pravidel vytvořit ze souborů naší aplikace jakýsi výsledný super balík, který obsahuje vše, co je potřeba. Tedy klidně i obrázky, fonty nebo css styly. Mimo to, dokáže navíc myslet i na věci, jako je překlad ECMA6 syntaxe pro starší prohlížeče, minifikaci či odstranění nepoužívaných částí kódu. Díky tomu nemusíme při vývoji na takové věci myslet a to vám ušetří hodně času i starostí. Motivace je jednoduchá. Naši appku chceme psát krásně a srozumitelně. Chceme mít rozdělené třídy, psát objektově a čitelně nazývat naše proměnné. Krásný a srozumitelný kód není ale z hlediska velikost dat příliš vhodný. Ve chvíli, kdy je naše aplikace stahována klientským prohlížečem, je důležité, aby byl stahovaný soubor co nejmenší. A také aby naše aplikace fungovala se vším všudy, nehledě na to, jaký prohlížeč klient používá.
Tenhle článek ale není ani tak o webpacku. Nedávno jsem řešil případ, kdy velikost vývojového bundlu javascriptové aplikace měl téměř 15 MB. Pro produkční javascript nemyslitelné. Když se dostanete do takové situace, nezoufejte. I kdyby se s tím nedalo nic dělat, minimálně díky webpacku zvládnete takového hrocha rozsekat na menší části (chunks), které jsou načítány postupně nebo dle potřeby. Může tak vzniknout například patnáct 1 MB souborů, které si klient stahuje dynamicky dle potřeby, protože opravdu málo kdy je třeba mít celou aplikaci rovnou k dispozici „v jednom kuse“. Prioritou je ale vždy snažit se v první řadě náš soubor zmenšit. V předchozích verzích webpacku na to byly různé produkční konfigurace, nově je to ale velmi jednoduché.
webpack -p
Tento parametr automaticky vloží process.env.NODE_ENV="'production'"
, dále použije UglifyJsPlugin
v doporučeném nastavení a dokonce i LoaderOptionsPlugin
. Po použití tohoto příznaku mi rázem velikost bundlu klesla o 90% na 1,5MB. Ale to je bohužel stále celkem dost. Strávil jsem potom hodně času vyhledáváním různých návodů, produkčních konfigurací a best praktices, ale nikdy se nepodařilo velikost balíku znatelně snížit. Nakonec jsem narazil na velmi zajímavý plugin webpack-bundle-analyzer.
Webpack bundle analyzer je výtečný nástroj, který vám umožní procházet obsah vytvořeného bundlu a sledovat, kolik místa co zabírá.
npm install --save-dev webpack-bundle-analyze
Ve Vašem webpack.config.js
pak přidáte jako plugin
var BundleAnalyzerPlugin = BundleAnalyzerPlugin ...
plugins:

Po dalším spuštění buildu dojde k automatickému otevření grafického náhledu s datovým rozložením kódu ve vašem výsledném balíku. V našem případě (viz obrázek) byl problém hlavně v našem kódu. Používali jsme lodash kvůli zjednodušení pár iterací, vkládali jsme do balíku i locales pro moment.js, vkládali jsme celý bootstrap, i když jsme potřebovali pouze pár věcí,… Po nápravě velikost balíku klesla z původních 15Mb na 1Mb a klidně by se i dalo ještě v hubnutí pokračovat.