kód splityngTakédělení kódu, lazy loading modulů, dynamický importPokročilý
Definice
Code splitting je technika, při které se JavaScriptový balík aplikace rozdělí na menší soubory (chunky), jež prohlížeč stahuje až ve chvíli, kdy jsou skutečně potřeba. Místo jednoho velkého bundlu se při prvním načtení přenese jen kód nutný pro zobrazenou stránku, zbytek dorazí později na vyžádání.
Příklady z praxe
Odložení editoru textu do vlastního chunku
Administrace e-shopu používá bohatý WYSIWYG editor, který sám o sobě váží přes 200 kB. Editor se otevře jen na stránce úpravy produktu, takže se importuje dynamicky. Úvodní bundle se zmenší a editor se stáhne až při prvním otevření detailu, ideálně s prefetchem po dokončení hydratace.
const Editor = React.lazy(() => import('./RichTextEditor')); function ProductForm() { return ( <React.Suspense fallback={<p>Načítám editor…</p>}> <Editor /> </React.Suspense> ); }Chunk pro jazykovou mutaci
Vícejazyčná aplikace má překlady pro osm jazyků, dohromady stovky kilobajtů JSONu. Statický import by dostal všechny do hlavního bundlu. Dynamický import podle zvoleného locale stáhne jen jeden soubor a bundler z každé větve udělá samostatný chunk.
async function loadMessages(locale) { const module = await import(`./locales/${locale}.json`); return module.default; }
Časté omyly
- MýtusČím víc chunků, tím rychlejší aplikace.
- Ve skutečnostiKaždý chunk znamená vlastní požadavek, vlastní hlavičky a vlastní kolo zpracování. Nad určitou hranicí režie převáží úsporu bajtů a stránka se načítá pomaleji než s jedním rozumně velkým bundlem.
- MýtusCode splitting a tree shaking je totéž.
- Ve skutečnostiTree shaking při buildu vyhodí nepoužitý kód úplně. Code splitting nic nemaže, jen přesune používaný kód do souboru, který se stáhne později. Techniky se používají současně.
- MýtusStačí dynamický import a je hotovo.
- Ve skutečnostiLíné načítání zavádí nový stav aplikace: čekání a selhání. Bez fallbacku, ošetření chyby a strategie prefetchu se zpomalí odezva na klik a po nasazení nové verze mohou staré chunky vracet 404.
Časté dotazy
- Od jaké velikosti bundlu má code splitting smysl?
- Code splitting začíná dávat měřitelný smysl u aplikací, kde JavaScript po kompresi přesahuje zhruba dvě až tři stovky kilobajtů, nebo kde jedna konkrétní knihovna tvoří výraznou část balíku. U malých webů s několika desítkami kilobajtů skriptu je přínos v řádu milisekund, zatímco kód se zesložití o načítací stavy a ošetření chyb. Rozhodujte podle analyzátoru bundlu a podle naměřeného Largest Contentful Paint na pomalém mobilním připojení, ne podle obecného doporučení.
- Jak zabránit blikání spinneru při přechodu mezi stránkami?
- Blikání spinneru řeší prefetch: chunk pro cílovou stránku se stáhne dřív, než na ni uživatel klikne. Běžné spouštěče jsou najetí myší nebo dotyk na odkaz, viditelnost odkazu ve výřezu a nečinnost hlavního vlákna. Next.js a podobné frameworky prefetch odkazů v routeru dělají automaticky. Pomáhá také ponechat starou obrazovku vykreslenou po dobu krátkého načítání a spinner zobrazit až po zpoždění zhruba dvou set milisekund, aby u rychlého připojení nikdy neproblikl.
- Proč se po nasazení nové verze objevují chyby při načítání chunku?
- Chyby při načítání chunku vznikají tím, že uživatel má v prohlížeči otevřenou starou verzi aplikace, která odkazuje na soubory s hashem staré sestavy. Po nasazení a smazání starých souborů z CDN vrátí požadavek 404 a dynamický import selže. Řešením je ponechat několik předchozích sestav na serveru po dobu jejich životnosti, zachytit chybu importu a nabídnout znovunačtení stránky, případně automaticky detekovat novou verzi a stránku obnovit.
- Řeší HTTP/2 potřebu code splittingu?
- HTTP/2 zlevnil paralelní požadavky, takže velký počet chunků není tak drahý jako dřív, ale samotnou příčinu neodstraňuje. Hlavní náklad velkého bundlu není přenos, nýbrž parsování a spouštění JavaScriptu na CPU mobilního zařízení. Ten se multiplexováním nezmenší. Code splitting proto zůstává relevantní i na HTTP/2 a HTTP/3, jen se posouvá optimální velikost chunku a je únosnější mít jich víc.
Zdroje
- JavaScript modules(otevře se v novém okně)
- import()(otevře se v novém okně)
- Lazy Loading Components(otevře se v novém okně)
- ECMAScript Language Specification(otevře se v novém okně)