React Performace Guide

Jak víme, React znovu vykreslí komponentu, kdykoli dojde ke změně stavu nebo rekvizit. Neexistuje žádná magická vazba ani žádný pozorovatel, který sleduje stavovou proměnnou a aktualizuje ji, ve skutečnosti se jedná o opětovné vykreslování komponenty, která aktualizuje uživatelské rozhraní. Každý render má své vlastní rekvizity, stav, posluchače událostí a efekty, to velmi dobře vysvětluje Dan.

Problém

V níže uvedeném kódu má nadřazená komponenta 5 podřízených komponent a všechny jsou vykresleny znovu, i když s nimi změna nesouvisí.

Zde je návod, jak je výkon ovlivněn zbytečným překreslováním komponent.

Řešení

První obrannou linií, jak se vyhnout zbytečnému překreslování, je použití React.memo . React.memo přeskočí vykreslování komponenty a znovu použije poslední vykreslený výsledek.
Pojďme zabalit všechny podřízené komponenty do React.memo .


Podařilo se nám zachránit 3 komponenty před překreslením při změně vstupního pole Name, ale přesto se pole pro zadání adresy znovu vykreslí. React.memo provádí pouze povrchní porovnání změn rekvizit, ale handleAddressChange funkce je znovu vytvořena nová pro každé vykreslení, a protože funkce jsou porovnávány odkazem, React.memo ji nebude moci zastavit v opětovném vykreslení vstupní komponenty, protože je podporována funkcí zpětného volání, která je nová pro každé vykreslení nadřazené komponenty.

Tento scénář lze optimalizovat pomocí useCallback háček.


Nyní máme opětovné vykreslování pouze pro komponenty, které to vyžadují, protože zpětná volání jsou předávána optimalizovaným podřízené komponenty, které spoléhají na referenční rovnost, aby se zabránilo zbytečnému vykreslování

💡 Nyní předpokládejme, že máme další požadavek, kterým je ověření adresy a zobrazení návrhu. Address Validation API může nějakou dobu trvat, uvidíme, jak to funguje

    const isValidAddress = () => {
    console.log(`validating Address... for ${city}`);
    for (let i = 0; i < 10000; i++) {
      //some delay to simualte address validation API
    }
    return city.length < 3 ? false : true;
  };
<!--  markup for address validation-->
 <Input
        target="Address"
        value={city}
        handleChange={memoizedAddressChange}
      />
      <span> Address is {isValidAddress() ? "✅" : "❌"}</span>

Pro tento příklad předpokládejme, že pokud je délka adresy menší než 3, pak je neplatná, jinak je platná.

Nyní isValidAddress() což je drahý fn , se volá, i když měníme název, děje se to kvůli překreslení komponenty kvůli změně stavu názvu.
Můžeme si zapamatovat výsledek funkce addressValidation, když měníme jakýkoli jiný stav, a přepočítat pouze tehdy, když dojde ke změně v poli adresy.

Optimalizované řešení s useMemo šetří čas zbytečného hodnocení jakékoliv drahé funkce. ⤵

Rozdíl mezi useCallback() a useMemo() je, že useCallback je zapamatování/zapamatování funkce zpětného volání, které jsou předány jako rekvizity, a useMemo je užitečné při zapamatování výsledku jakéhokoli drahého výpočtu.

Zde je úplný příklad kódu výše concepts :