Web razvoj
ReactPerformanseProfiliranjeMemoizacijaNext.jsFrontend

React performanse u 2026.: profiliranje, memoizacija i obrasci renderiranja koji stvarno rade

AO
Adrijan Omićević
·13 min čitanja

# Što ćete naučiti#

Ovaj vodič daje ponovljiv workflow za profiliranje performansi i memoizaciju u Reactu u 2026.: prvo mjerite, pronađite stvarno usko grlo, pa primijenite ciljane popravke. Naučit ćete kako koristiti React DevTools Profiler, why-did-you-render i osnovne metrike preglednika za dijagnostiku sporih interakcija, a zatim sigurno primijeniti memoizaciju, stabilne props i virtualizaciju lista.

Ako gradite u Next.js, pročitajte i naš vodič o React Server Components jer prebacivanje posla s klijenta može ukloniti čitave kategorije problema s performansama.

# Zašto React sučelja djeluju sporo u 2026.#

Većina prijava “sporog Reacta” i dalje se svodi na jedno od ovoga:

  • Previše posla po interakciji: skupi renderi, teške izračune ili velika DOM stabla.
  • Previše rendera: aplikacija radi ispravan posao, ali ga ponavlja zbog nestabilnih props ili lošeg smještaja state-a.
  • Previše JavaScripta na main threadu: third-party skripte, hydration, analitika ili veliki bundleovi.
  • Uska grla mreže i asseta: spore slike, fontovi ili API pozivi koji blokiraju ažuriranje UI-ja.

React 18 i 19 poboljšali su scheduling i concurrency, ali automatski ne uklanjaju rasipanje. Vaš je zadatak identificirati što se stvarno događa u vašoj aplikaciji, a ne što pretpostavljate da se događa.

ℹ️ Napomena: “Spor commit” u React Profileru može biti uzrokovan veličinom DOM-a, layout thrashingom ili skupim efektima. Rješenje može biti izvan React koda, pa uvijek potvrdite i browser profiliranjem.

Za širi pristup performansama izvan React renderiranja, pogledajte Optimizacija performansi web stranice.

# Preduvjeti i postavljanje alata#

Koristite ovu checklistu kako biste bili sigurni da su rezultati profiliranja pouzdani.

ZahtjevPreporukaNapomene
React DevToolsNajnoviji stablePotreban Profiler tab
Chrome DevToolsNajnoviji stablePerformance panel, long tasks
Node.js20+Česta osnova za moderne toolchaine
Build modeŠto bliže produkcijiDev mode može prenaglasiti cijene renderiranja
Source mapsUključenoČini traceove čitljivima
why-did-you-renderNajnovijiKoristite samo u developmentu

Profilirajte u okruženju sličnom produkciji#

Ako profilirate u developmentu, mogli biste loviti duhove. React namjerno dodaje provjere i dodatni posao u dev modu.

Praktične opcije:

  1. 1
    Pokrenite production build lokalno i testirajte na njemu.
  2. 2
    Koristite staging okruženje s produkcijskim flagovima.
  3. 3
    Koristite real user monitoring na stvarnom prometu.

Ako koristite Next.js, production build možete pokrenuti ovako:

Bash
npm run build
npm run start

# Korak 1: Definirajte “sporo” kroz osnovne metrike#

Prije nego što dirate kod, definirajte cilj u mjerljivim terminima. Ne treba vam kompletna observability platforma da biste krenuli.

Minimalne metrike koje su bitne#

MetrikaCilj (praktično)Kako mjeriti
Latencija interakcijemanje od 100 ms djeluje trenutačnoručno testiranje + Profiler oznake
Trajanje React commit-aizbjegavati česte commit-e dulje od 16 msReact DevTools Profiler
Long tasksdržati pod kontrolom, izbjegavati “burstove”Chrome Performance panel
Core Web Vitalsgood pragovifield podaci, Lighthouse kao baseline

Koristite ih kao smjernice, ne kao apsolute. Složen dashboard može tolerirati nekoliko commit-a od 30 ms, ali ponavljani commit-i od 30 ms tijekom tipkanja djelovat će kao da je aplikacija pokvarena.

Napravite jedan ponovljiv scenarij#

Odaberite jedan korisnički tok koji jasno djeluje sporo, npr.:

  • tipkanje u search polje
  • otvaranje modala s velikom formom
  • odabir filtera na listi proizvoda
  • širenje retka u data tablici

Zapišite ga kao skriptu kako biste ga mogli ponoviti nakon svake promjene.

💡 Savjet: Snimite kratki screen capture “sporog” ponašanja. Pomaže potvrditi poboljšanja i sprječava da se regresije odbace uz “kod mene je okej”.

# Korak 2: Profilirajte interakciju s React DevTools Profilerom#

React DevTools Profiler odgovara na dva ključna pitanja:

  1. 1
    Koje su se komponente renderirale?
  2. 2
    Koliko je to trajalo i koje su bile rasipne?

Kako snimiti smislen profil#

  1. 1
    Otvorite React DevTools i idite na Profiler tab.
  2. 2
    Kliknite record.
  3. 3
    Izvedite točno tu sporu interakciju jednom ili dvaput.
  4. 4
    Zaustavite snimanje.
  5. 5
    Pronađite commit koji odgovara interakciji.

Fokusirajte se na:

  • skokove u commit duration
  • komponente s visokim self time
  • komponente koje se re-renderiraju više puta tijekom jedne interakcije

Kako interpretirati flamegraph i ranked view#

Koristite oba:

  • Ranked view da vidite koje su komponente bile najskuplje u tom commitu.
  • Flamegraph da vidite put renderiranja i koja grana dominira.

Uobičajen obrazac kod sporih sučelja:

  • mala promjena state-a uzrokuje re-render komponente visokog nivoa
  • taj re-render se kaskadno širi na veliko podstablo: stavke liste, chartove, polja forme
  • mnoge od tih child komponenti se vizualno uopće nisu promijenile

Kako izgledaju “wasted renders”#

Ako se komponenta renderira, ali joj se output ne mijenja, to je odlična meta za:

  • spuštanje state-a niže
  • stabiliziranje props
  • memoizaciju

Ne nagađajte. Potvrdite razlog re-renderiranja prije nego dodate React.memo.

# Korak 3: Potvrdite uzroke re-renderiranja s why-did-you-render#

React DevTools govori što se renderiralo, ali ne uvijek i zašto. why-did-you-render pomaže otkriti koji su se props ili hookovi promijenili i okinuli render.

Instalirajte i uključite why-did-you-render#

Držite ga samo za dev.

Bash
npm install --save-dev @welldone-software/why-did-you-render

Napravite mali setup file i učitajte ga samo u developmentu. Točna lokacija ovisi o vašem stacku, ali ključ je da ga ne šaljete u produkciju.

JavaScript
// wdyr.js
import React from "react";
 
if (process.env.NODE_ENV === "development") {
  const whyDidYouRender = require("@welldone-software/why-did-you-render");
  whyDidYouRender(React, { trackAllPureComponents: true });
}

Označite specifične komponente koje želite pratiti:

JavaScript
// Component.js
import React from "react";
 
function Row(props) {
  return <div>{props.name}</div>;
}
 
Row.whyDidYouRender = true;
 
export default React.memo(Row);

Na što paziti u console outputu#

Tipični krivci:

  • props koji mijenjaju identitet pri svakom renderu: arrayi, objekti, funkcije
  • derived data izračunata inline
  • children koji se nepotrebno ponovno grade
  • context vrijednosti koje se recreiraju pri svakom renderu

Cilj je da uzrok re-renderiranja bude očit i popravljiv, ne da “utišate” logove memoizacijom svega.

⚠️ Upozorenje: Lako je “optimizirati” tako da memoizirate komponentu, a i dalje prosljeđujete nestabilne props. To često pogorša performanse: platite cijenu usporedbe u memoizaciji i svejedno se re-renderirate.

# Korak 4: Popravite “velika tri”: smještaj state-a, stabilni props i derived data#

Prije memoizacije, popravite arhitekturne probleme koji stvaraju render kaskade. Ako je strukturu komponenti već teško pratiti, pogledajte Arhitektura React komponenti za skalabilne design sustave i uskladite granice oko vlasništva nad state-om.

1) Spustite state što niže#

Ako je state filter inputa u parentu koji ujedno renderira veliku listu, svaki pritisak tipke može re-renderirati listu.

Praktičan refaktor:

  • Držite state inputa unutar input komponente.
  • Dižite state samo kada ga više siblinga stvarno treba.
  • URL state ili global state koristite selektivno, ne po defaultu.

2) Stabilizirajte props s useMemo i useCallback samo gdje je bitno#

Nestabilni props forsiraju rendere čak i ako su vrijednosti “logički iste”.

Tip propsČesta greškaRješenje
Object propsoptions={{ a: 1 }} inlineuseMemo za objekt
Array propsitems={data.map(...)} inlineuseMemo za derived arraye
Function propsonClick={() => ...} inlineuseCallback kada se prosljeđuje duboko
Childrensloženi children inlineizdvojiti ili memoizirati podstabla

Primjer: stabilizacija konfiguracijskog objekta.

JavaScript
const columns = useMemo(() => {
  return [
    { key: "name", label: "Name" },
    { key: "price", label: "Price" },
  ];
}, []);

Primjer: stabilizacija handlera samo kad je potrebno.

JavaScript
const onRowClick = useCallback((id) => {
  setSelectedId(id);
}, []);

Ako callback ovisi o vrijednostima, i dalje će se mijenjati kad se promijene dependencies. To može biti u redu. Cilj je zaustaviti nepotrebne promjene, ne “zamrznuti” aplikaciju.

3) Izbjegavajte skupu derived data u renderu#

Ako sortirate, grupirate ili računate agregate na svakom renderu, plaćate ponavljajući trošak.

Tipične skupe operacije:

  • sortiranje velikih arraya
  • izgradnja mapa i indeksa
  • ponavljano parsiranje datuma
  • transformacije s puno regex-a

Premjestite izračun:

  • u useMemo ako su inputi stabilni
  • u selektore ako koristite global state
  • na server, ako je moguće

Ovdje Server Components mogu biti velik dobitak: gurnite skupo formatiranje i agregacije na server i pošaljite podatke spremne za renderiranje. Pogledajte Vodič za React Server Components.

# Korak 5: Smjernice za memoizaciju koje stvarno rade#

Memoizacija je alat, ne strategija. Koristite je tamo gdje profiliranje pokaže rasipanje i gdje props možete držati stabilnima.

React.memo: kada pomaže#

React.memo pomaže kada:

  • komponenta se često renderira
  • renderiranje nije trivijalno
  • props su većinom vremena stabilni
  • re-renderi su uglavnom identičan output

React.memo često ne pomaže kada:

  • props se mijenjaju svaki put zbog promjena identiteta
  • komponenta je mala i jeftina
  • oslanjate se na implicitne re-render-e da UI ostane konzistentan

Primjer:

JavaScript
const PriceCell = React.memo(function PriceCell({ value, currency }) {
  return (
    <span>
      {value} {currency}
    </span>
  );
});

useMemo: koristite za skupe izračune, ne za kozmetiku#

Dobri use caseovi:

  • sortiranje, filtriranje, grupiranje
  • izgradnja lookup mapa
  • memoizacija teških child stabala

Loši use caseovi:

  • memoizacija malih spajanja stringova
  • memoizacija trivijalnih objekata koji se ne prosljeđuju kao props

Pravilo iz prakse: ako se cijena izračuna ne vidi u Profiler self time, nemojte je memoizirati.

useCallback: koristite ga da memoizirani children ostanu memoizirani#

useCallback je uglavnom koristan kada:

  • handlere prosljeđujete React.memo child komponentama
  • promjena identiteta handlera uzrokuje re-render childa
  • duboko stablo ovisi o tom handleru

Ne koristite useCallback svugdje “za svaki slučaj”. Dodaje overhead i čini kod težim za čitanje.

Custom usporedbe: rijetko se isplate#

React.memo(Component, areEqual) može pomoći u posebnim slučajevima, ali je maintenance zamka.

Koristite samo kada:

  • props su veliki objekti
  • možete pouzdano usporediti mali podskup
  • imate testove da izbjegnete bugove zastarjelog UI-ja

Ako dodate custom usporedbe, dokumentirajte pretpostavke i provjerite profiliranjem.

# Korak 6: Obrasci renderiranja za velika sučelja#

Kada je DOM velik, memoizacija vas neće spasiti. Morate renderirati manje.

Virtualizirajte duge liste i tablice#

Ako renderirate 1.000 redaka, usko grlo može biti DOM, layout i painting, ne React. Virtualizacija obično renderira samo ono što je vidljivo plus mali buffer.

Praktični znakovi da trebate virtualizaciju:

  • scroll “šteka”
  • commit-i su ok, ali browser je zauzet
  • Performance panel pokazuje puno vremena u layoutu i paintu

Često korištene biblioteke:

  • react-window
  • react-virtualized
  • framework-specifični data gridovi s ugrađenom virtualizacijom

Minimalni primjer s react-window:

JavaScript
import { FixedSizeList as List } from "react-window";
 
function VirtualList({ items }) {
  return (
    <List height={500} itemCount={items.length} itemSize={36} width="100%">
      {({ index, style }) => (
        <div style={style}>{items[index].name}</div>
      )}
    </List>
  );
}

Podijelite skupi UI progresivnim renderiranjem#

Ako otvaranje modala uzrokuje veliki commit, renderirajte shell prvo i odgodite teške sekcije:

  • renderirajte prvo above-the-fold
  • lazy loadajte chartove i editore
  • suspense granice koristite promišljeno

To poboljšava percipiranu brzinu, čak i ako je ukupni posao sličan.

Izbjegnite “global rerender” okidače#

Česti okidači:

  • stavljanje često promjenjivih vrijednosti u React Context
  • prosljeđivanje velikih context vrijednosti koje se često mijenjaju
  • spremanje kratkotrajnog UI state-a u globalne storeove

Ako morate koristiti context, razdvojite contexte po učestalosti promjena i držite vrijednosti stabilnima.

# Korak 7: Potvrdite poboljšanja browser profiliranjem#

React Profiler je nužan, ali nije dovoljan. Promjena u Reactu koja smanji commit time i dalje može ostaviti UI sporim zbog layouta, painta ili long tasks.

Koristite Chrome Performance panel za isti scenarij#

  1. 1
    Otvorite Chrome DevTools Performance.
  2. 2
    Pokrenite snimanje.
  3. 3
    Izvedite interakciju.
  4. 4
    Zaustavite.
  5. 5
    Potražite:
    • long tasks na main threadu
    • teški layout i paint
    • event handlere koji blokiraju input

Uskladite vremenske oznake s React commit-ima. Ako su commit-i mali, ali je main thread zauzet, tražite:

  • skupe obrasce mjerenja DOM-a
  • sinkroni pristup storageu
  • teške third-party skripte
  • velike slike ili font swapove koji utječu na layout

Praktična definicija “gotovo”#

Gotovi ste kada:

  • interakcija djeluje brzo na hardveru srednje klase
  • skokovi u commit duration su smanjeni ili uklonjeni
  • long tasks su smanjeni tijekom interakcije
  • niste uveli regresije u ispravnosti

Ako možete, validirajte field podacima. Lighthouse je baseline; stvarni korisnici su završni test.

# Česte zamke u radu na React performansama#

  1. 1
    Preuranjena optimizacija — Memoizacija bez profiliranja često povećava kompleksnost i može pogoršati performanse zbog dodatnih usporedbi.
  2. 2
    Stabiliziranje svega — Pretjerivanje s useMemo i useCallback otežava održavanje i ne garantira manje rendera.
  3. 3
    Ignoriranje toka podataka — Loš smještaj state-a stvara render kaskade koje memoizacija ne može u potpunosti sakriti.
  4. 4
    Pogrešna upotreba contexta — Stavljanje brzo promjenjivih vrijednosti u context re-renderira sve consumere.
  5. 5
    Miješanje render time-a i ukupnog vremena — Brz React render i dalje može rezultirati sporim DOM ažuriranjima zbog layouta i painta.
  6. 6
    Mjerenje u dev modu — Dev-only provjere iskrivljuju rezultate i mogu vas navesti da popravljate nepostojeće probleme.

🎯 Ključna poruka: Profiliranje nije jednokratna aktivnost. Stvorite naviku: mjerite, promijenite jednu stvar, ponovno mjerite i držite kratku listu scenarija koji moraju ostati brzi.

# Checklist korak po korak koju možete ponovno koristiti#

Koristite ovaj redoslijed za svaki performance ticket:

  1. 1
    Definirajte skriptu spore interakcije i ciljnu metriku.
  2. 2
    Profilirajte s React DevTools Profilerom i identificirajte top self time komponente.
  3. 3
    Potvrdite razloge re-renderiranja s why-did-you-render.
  4. 4
    Popravite smještaj state-a i stabilizirajte props tamo gdje utječu na memoizirane granice.
  5. 5
    Dodajte memoizaciju samo tamo gdje profiliranje pokaže rasipanje.
  6. 6
    Virtualizirajte liste ili smanjite DOM ako je UI velik.
  7. 7
    Validirajte u Chrome Performance i pratite long tasks.
  8. 8
    Ponovno testirajte istu skriptu i dokumentirajte što se promijenilo.

# Ključne poruke#

  • Prvo profilirajte stvarnu interakciju uz React DevTools Profiler, pa se fokusirajte na top self time komponente i skokove commit-a.
  • Koristite why-did-you-render da potvrdite zašto se komponente re-renderiraju, posebno kod nestabilnih object, array i function props.
  • Radije popravite smještaj state-a i stabilizirajte props nego da radite blanket memoizaciju; memoizirajte samo tamo gdje su rasipni renderi dokazani.
  • Koristite virtualizaciju kada je veličina DOM-a usko grlo; memoizacija ne može kompenzirati renderiranje tisuća čvorova.
  • Validirajte poboljšanja browser profiliranjem, ne samo React metrikama, i izbjegavajte odluke temeljene na mjerenjima u development modu.

# Zaključak#

React performanse u 2026. i dalje se svode na osnove: mjerite stvarne interakcije, smanjite nepotreban posao i renderirajte manje kada je DOM usko grlo. Ako želite drugo mišljenje o vašim Profiler traceovima ili trebate pomoć da ove obrasce pretvorite u dosljedan timski pristup, Samioda može napraviti audit vaše aplikacije i implementirati ciljane popravke u Reactu, Next.js ili Flutteru.

Kontaktirajte nas putem samioda.com i podijelite jednu snimku spore interakcije plus Profiler export, a mi ćemo odgovoriti s konkretnim planom optimizacije.

FAQ

Share
A
Adrijan OmićevićOsnivač i senior developer

Osnivač i senior developer u Samiodi. 8+ godina iskustva u izradi React, Next.js, Flutter i n8n rješenja za klijente diljem Europe.

Trebate pomoć s projektom?

Gradimo prilagođena rješenja koristeći tehnologije iz ovog članka. Senior tim, fiksne cijene.