7. Oct 2021Frontend

Optimalizá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.

Ján CvenčekFrontend Develooper

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 kompresiouPlugin s bezstratovou kompresiou
JPEGimagemin-mozjpegimagemin-jpegtran
PNGimagemin-pngquantimagemin-optipng
GIFimagemin-giflossyimagemin-gifsicle
SVGimagemin-svgo 
WebPimagemin-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

Ján CvenčekFrontend Develooper