Skip to main content

Optimalizace Core Web Vitals v Reactu

V tomto textu nabídneme několik optimalizačních technik pro zlepšení metrik Core Web Vitals u webů, které jsou postavené na Reactu. Zaměříme se hlavně na Interaction to Next Paint (INP), tedy rychlost odezvy na interakce.

Optimalizovat rychlost webů postavených na Reactu spočívá v optimalizaci dlouhých úloh v JavaScriptu, které jsou úzce spojené s tím jak React interně funguje a jsou vidět mimo jiné v metrice TBT.

Web na Reactu je automaticky rychlý? Omyl

Interně používá React několik chytrých technik, které rychlosti webů nebo webových aplikací pomáhají.

Efektivně aktualizuje a vykresluje pouze komponenty, ve kterých se změní data. Systém hooků zase částečně chrání web od nechtěných přepočtů layoutu a tzv. layout thrashingem.

Znamená to tedy, že web postavený na Reactu bude automaticky rychlý? Odpověď je jednoduchá: NE.

Deklarativní komponenty sice činí kód předvídatelnějším a snáze pochopitelným, zároveň ale neopatrná manipulace se stavem nebo množstvím komponent téměř jistě vede k pomalé interaktivitě.

Je to nástroj jako každý jiný a vždy záleží, jak dobře jej vývojář zná.

Pojďme nyní na tipy pro optimalizaci Reactu, které vám doporučujeme na základě naší práce pro klienty. Jak udržet Reactí kód pod kontrolou?

1) Zmenšete velikost DOMu

Velikosti DOMu a jeho optimalizace je základ. Co v DOMu není, není potřeba renderovat a prohlížeč může odpočívat.

V Reactu tato pravda platí dvojnásob. Méně elementů znamená méně komponent, to znamená méně JavaScriptu na stahování i zpracování.

V případě SSR (renderování na serveru) dojde i k optimalizaci času potřebného k sestavení první HTML odpověď. Ta má navíc i menší datovou velikost. Prostě win-win na všechny strany.

Vyjměte komponenty, které nejsou důležité pro SEO, úplně z DOMu a načtěte je pomocí lazy loadingu:

import { lazy } from 'react';

const MarkdownPreview = lazy(() => import('./MarkdownPreview.js'));

2) Tvořte jednoduché a bohaté berze komponent

I když je komponenta nebo její obsah pro SEO nebo přístupnost důležitá, neznamená to, že musí být při prvním vykreslení v plné vizuální kvalitě. Zvlášť pokud komponenta není vidět v prvním viewportu.

Optimalizace pomocí rozdělení na jednoduchou a bohatou komponentu je zvlášť efektivní u prvků, které se na stránce opakují vícekrát. To jsou typicky rozcestníkové stránky, výpis produktů nebo jiných nabídek, jako vidíte na obrázku:

Ukázka nahrazení jednoduché komponenty, bohatou Ukázka komponenty, která při načtení stránky poskytuje jen pro SEO důležitá data. Uživateli je tento stav vizuálně skrytý. „Rich varianta“ se aktivuje zobrazením komponenty ve viewportu.

3) Používejte <Suspense>

Značka <Suspense> se v Reactu primárně používá pro zobrazení zástupného obsahu během načítání líných komponent.

Málokdo už ale ví, že její skrytá superschopnost <Suspense> je, že zapíná konkurenční rendering. Stránku a její komponenty tak lze rozdělit na důležité a méně důležité části.

Vizualizace rozděleného react stromu komponent Strom komponent rozdělení pomocí značky <Suspense>. Červené komponenty jsou právě touto značkou označené za méně důležité.

V případě  použití SSR (server sider renderingu) je effekt značky <Suspense> značky naprosto zásadní.

Hydratace, tedy oživení oživení stránky, je okamžik kdy se server-sider generovaný kód oživí na straně klienta v prohlížeči.  Je to téměř vždy dlouhá javascritová úloha, takže použití <Suspense> pomůže.

Ale pozor! Nikdy touto značkou neobalujte velký blok, spíše jen menší části. Zároveň se <Suspense> šetřete u prvků, které jsou vidět v prvním viewportu. V opačném případě může být kontraproduktivní.

4) Pozor na chyby hydratace

Na konci hydratace proběhne ověření, zda výsledný strom elementů (DOM), odpovídá stavu na serveru. Pokud ne, dojde k chybě a hlášení:

Ukázka chyby hydratace v konzoli Zobrazení chyby hydratace v konzoli prohlížeče.

V tu chvíli React invaliduje všechny komponenty na stránce a proběhne jejich update klientským JavaScriptem, což zhoršuje výkon a může to nepříjemně zpozdit metriku LCP.

5) Pozor na useEffect()

useEffect není vždy asynchronní. Pokud uživatel vyvolá vstup (například klikne), je veškerý kód Reactu proveden synchronně a to včetně „effect hooků“.

Pokud se hook užívá k faktickému odložení úlohy do následujícího renderovacím cyklu, je nutné použít setTimeout nebo jinou metodu.

useEffect(() => {
// Defer work to a separate task:
setTimeout(() => {
sendAnalytics();
}, 0);
}, []);

6) Server Components

Server Components jsou funkcí, které je v Reactu relativně nová. Umožňují psát komponenty, které nejsou dostupné v klientskému JavaScriptu, ale jen na serveru.

To znamená, že klient obdrží již vykreslený obsah a nemusí spouštět znovu JavaScript k tomu, aby se obsah zobrazil nebo oživil.

Závěr

React je jen nástroj. Základ je dobře ho poznat. V tomto ohledu velmi doporučujeme sérii článků React Internals Deep Dive.

Podívejte se na další metody optimalizace INP.