ALGO25 / BLOG

Interviu React senior: performanță măsurată

Pregătește interviul React senior: profilare, useMemo, identitatea datelor și teste de comportament. Învață să justifici optimizările prin măsurători.

La nivel senior, „pagina este lentă” trebuie transformat într-o problemă măsurabilă. Poate fi o cerere lentă, un calcul repetat, prea mult JavaScript sau prea multe elemente în pagină. Aplicarea useMemo peste tot nu identifică automat cauza.

Ce pregătești la acest nivel

Recapitulează efectele și răspunsurile întârziate. Continuă cu localizarea stării, profilare, identitatea props, accesibilitate și teste pe interacțiuni reale. Exemplul de aici folosește React 19 și un catalog local. Nu presupunem activarea React Compiler și nu dăm un procent inventat de accelerare.

Într-un interviu, cere un scenariu reproductibil: ce acțiune, ce volum de date, pe ce dispozitiv și în ce condiții? Notează separat timpul rețelei și timpul de randare. Nu compara fără explicație o versiune de dezvoltare pe laptop cu o versiune de producție pe telefon.

Exemplu: filtrare și o stare independentă

Lista de produse este creată în afara componentei și are o referință stabilă. Butonul de ajutor modifică o stare care nu afectează filtrul. useMemo permite reutilizarea calculului când valoarea căutării nu s-a schimbat; nu elimină randarea componentei și nici costul tuturor elementelor din DOM.

import { useMemo, useState } from 'react';

const products = [
  { id: 'j1', name: 'Java pentru început' },
  { id: 'r1', name: 'React practic' },
  { id: 'j2', name: 'Java concurent' },
];

export default function Catalog() {
  const [query, setQuery] = useState('');
  const [help, setHelp] = useState(false);
  const visible = useMemo(() => {
    const normalized = query.trim().toLowerCase();
    return products.filter(product =>
      product.name.toLowerCase().includes(normalized));
  }, [query]);

  return (
    <section aria-label="Catalog de exercițiu">
      <label>Caută un material
        <input value={query} onChange={event => setQuery(event.target.value)} />
      </label>
      <button type="button" aria-expanded={help}
        onClick={() => setHelp(value => !value)}>Ajutor</button>
      {help && <p>Căutarea ignoră literele mari și spațiile de la capete.</p>}
      <p role="status">Rezultate: {visible.length}</p>
      <ul>{visible.map(product => <li key={product.id}>{product.name}</li>)}</ul>
    </section>
  );
}

Montează componenta într-un proiect React cu JSX. Căutarea java produce două rezultate; REACT produce unul; python produce zero. Deschiderea ajutorului păstrează căutarea. Exemplul mic este pentru verificarea comportamentului. Pentru trei produse, memoizarea probabil nu justifică o optimizare în sine.

De la exemplu la diagnostic

La un catalog mare, măsoară separat filtrarea și actualizarea interfeței. Dacă filtrarea este costisitoare, memoizarea ajută numai când dependențele rămân egale. La fiecare caracter nou, query se schimbă și calculul se execută din nou. Dacă problema este numărul mare de noduri, discută paginarea sau virtualizarea și verifică efectele asupra navigării cu tastatura.

React tratează useMemo ca optimizare, nu ca garanție de corectitudine. Componenta trebuie să producă același rezultat și dacă elimini memoizarea. Nu folosi cacheul hookului drept loc de stocare pentru date care trebuie păstrate semantic. Referință: useMemo.

Cu Profiler poți măsura randarea unui subarbore. actualDuration descrie timpul de randare pentru actualizarea curentă, nu durata completă a interacțiunii, rețelei și afișării browserului. Profilarea adaugă cost, iar buildul obișnuit de producție nu activează implicit această instrumentare. Vezi Profiler.

Un răspuns senior explică și riscul schimbării

Dacă extragi lista într-o componentă cu memo, verifică props: un obiect sau callback nou la fiecare randare poate împiedica reutilizarea. Dacă muți state mai aproape de locul unde este folosit, poți reduce aria actualizării fără să adaugi memoizare peste tot.

Definește un criteriu de acceptare pentru scenariul măsurat și păstrează testele de comportament. O listă mai rapidă care pierde focusul sau afișează rezultate vechi este o regresie. Verifică și cazul fără rezultate, caracterele introduse rapid și revenirea la o căutare goală.

Exersează

  1. Elimină useMemo și verifică aceleași rezultate. Răspuns: comportamentul trebuie să rămână identic.
  2. Explică de ce butonul de ajutor nu schimbă dependența, dar tastarea o schimbă. Nu confunda randarea componentei cu recalcularea filtrului.
  3. Propune un experiment cu multe produse. Notează dispozitivul, buildul, numărul de produse, interacțiunea și măsurătorile înainte și după o singură schimbare.

Autoevaluare și pasul următor

Poți continua dacă legi fiecare optimizare de un cost observat, păstrezi corectitudinea fără cache și verifici accesibilitatea. Urmează React arhitect: granițe și randare.

Întrebări frecvente

useMemo împiedică randarea componentei?

Nu. El poate reutiliza rezultatul calculului. Evitarea unor randări ale copilului este o discuție separată, legată de props și alte surse de actualizare.

Trebuie să folosesc useCallback pentru toate funcțiile?

Nu. Justifică identitatea stabilă printr-un consumator sau o măsurătoare. Altfel adaugi complexitate fără un beneficiu demonstrat.

De ce exemplul are doar trei produse?

Ca rezultatele să fie ușor de verificat. Nu îl folosim pentru afirmații despre performanță la scară mare.

React Compiler schimbă discuția?

Poate automatiza unele optimizări într-un proiect configurat pentru el. Confirmă dacă este activ și măsoară comportamentul proiectului real.

Numărul de randări este singura metrică utilă?

Nu. Contează costul lor și efectul asupra interacțiunii. Multe randări ieftine pot fi mai puțin problematice decât una foarte costisitoare.

Surse și versiuni

React 19. Documentația de mai sus a fost consultată la 12 octombrie 2026. Nu prezentăm măsurători de performanță care nu au fost efectuate.