7. Oct 2021
FrontendOptimalizácia React SPA aplikácií v benchmark nástrojoch
V tomto článku predstavím riešenia, ktoré môžu pomôcť s optimalizáciou SPA (single page app), primárne postavených na frameworku React. Aplikovanie jednotlivých postupov napomáha so zrýchlením načítania, zlepšením výkonu a získaním vyššieho skóre v benchmark nástrojoch. V prvej časti sa budem venovať kompresii súborov, webovým fontom a CSS.
Tipy uvedené nižšie boli aplikované pre React aplikáciu vytvorenú pomocou Create React App (CRA), ktorá využíva webpack v4. Viacero techník pre lepšiu výkonnosť a rýchlosť aplikácie má CRA predkonfigurovaných. Pre úpravu konfigurácie webpacku v CRA bez vykonania eject príkazu, je potrebné využiť knižnice, ako craco alebo customize-cra. Produkčný build aplikácie je servovaný pomocou web servera Nginx.
Pre zmeranie skóre ohľadom výkonnosti a rýchlosti boli použité nástroje:
Samotné nástroje vo výstupoch navrhujú riešenia, ako jednotlivé problémy odstrániť.
ℹ Nasledujúce postupy nie sú jediné, ako vyriešiť reportovaný problém z nástrojov, viaceré z nich majú alternatívu.
Kompresie
Kompresiu súborov, ktoré servuje web server je možné aplikovať buď na strane servera, alebo staticky pri buildovacom procese.
Compress-create-react-app
Pre statickú kompresiu je možné použiť knižnicu compress-create-react-app ako build skript cez npm. Vykonáva gzip aj brotli kompresiu pre html, css a js súbory. V prípade, že kompresia nie je dostačujúca, prípadne jej konfigurácia nevyhovuje, je možné použiť niektorý z postupov nižšie.
Gzip
Metóda kompresie je menej náročná na CPU, veľkosť komprimovaných súborov je ale väčšia v porovnaní s Brotli. Jednotlivé metódy môžu byť rozšírené ďalšími prepínačmi/parametrami podľa potreby.
Statická kompresia
Je možné ju vykonať pomocou systémovej utility gzip (pre Windows treba doinštalovať) gzip -r -f -k Nakoľko utilita nie je cross-platform predinštalovaná, je vhodnejšie použiť compression-webpack-plugin.
Live kompresia - Nginx
Zapína sa v konfigurácii pre Nginx.
Brotli
Výkonnejšia metóda oproti gzip na úkor CPU.
⚠ Podporované iba cez HTTPS
Statická kompresia
S využitím compression-webpack-plugin
Live kompresia - Nginx
Zapína sa v konfigurácii pre Nginx, ktorý musí mať nainštalovaný modul pre Brotli. Pre Docker je možné použiť napr. image fholzer/nginx-brotli
Imagemin
Nástroj na kompresiu obrázkov. Existuje viacero pluginov pre rôzne formáty. Každý má viacero parametrov pre nastavenie pluginu podľa potreby. Jednotlivé pluginy aj s odkazmi sú v tabuľke. Podporuje bezstratovú (kvalita obrázka po kompresii zodpovedá originálu) alebo stratovú kompresiu. Stratová kompresia je efektívnejšia z pohľadu úspory veľkosti na úkor kvality.
Formát | Plugin so stratovou kompresiou | Plugin s bezstratovou kompresiou |
JPEG | imagemin-mozjpeg | imagemin-jpegtran |
PNG | imagemin-pngquant | imagemin-optipng |
GIF | imagemin-giflossy | imagemin-gifsicle |
SVG | imagemin-svgo | |
WebP | imagemin-webp |
Príklad PNG kompresie cez GULP
npm install gulp gulp-imagemin --save-dev
Bezstratová kompresia (imagemin-optipng)
npm install imagemin-pngquant --save-dev
Stratová kompresia (imagemin-pngquant)
npm install imagemin-optipng--save-dev
Webfonty
Zaistite, aby bol text počas načítania webových fontov viditeľný. Fonty sú často veľké súbory, ktorých načítanie chvíľu trvá. Niektoré prehliadače skryjú text, kým sa nenačíta písmo, čo spôsobí záblesk neviditeľného textu (FOIT) - Lighthouse metrika.
Riešenie - doplniť do @font-face deklaráciu atribútu font-display: swap;
CSS
Pred zobrazením stránky musí prehliadač stiahnuť a analyzovať súbory CSS, čo robí z CSS zdroj blokujúci vykresľovanie. Ak sú súbory CSS veľké alebo sieťové podmienky zlé, požiadavky na súbory CSS môžu výrazne predĺžiť čas potrebný na vykreslenie webovej stránky.
Ak Lighthouse report hlási First Contentful Paint (FCP) problém - "Eliminate render-blocking resource" je vhodné vyskúšať extrakciu kritických (sú aktuálne potrebné pre zobrazenie) a nekritických CSS štýlov. Po optimalizácii sa synchrónne načítajú iba kritické štýly, zatiaľ čo non-critical sa načítajú neblokujúcim spôsobom.
Možné riešenie - html-critical-webpack-plugin
⚠ Plugin používa knižnicu puppeteer s headless prehliadačom Chromium/Chrome - je potrebné sa uistiť, že prostredie, kde PROD build pobeží, má nainštalované potrebné závislosti
html-critical-webpack-plugin analyzujekritické CSS štýly a vytiahne ich do <style></style> v <head> tagu v HTML, čím eliminuje potrebu podať ďalšiu požiadavku na ich načítanie.
ℹ Odporúča sa plugin použiť iba pri produkčnom builde
Ďalšie tipy na optimalizáciu môžeš nájsť v druhom diely, v ktorom sa dozvieš, ako na dynamické importy, refaktoring či odstránenie nepoužívaného kódu.
Pripravený na výzvu? Pridaj sa k nám do Frontend tímu