React Performansi: 2026da Kapsamli Bir Rehber
Bilesen olceklendirme, olay yukleme, state yonetim stratejileri, Suspense, Server Bilesenleri ve derleme araclari icin pratik bir kilavuz.
React performansi hakkinda konusurken, cogu makale yalnizca birbirini tekrarlar: useMemo ve useCallback i kullanin, key lerinizi dogru ayarlayin ve gereksiz render lardan kacinin. Bunlar onemli olmakla birlikte, artik baslangic duzeyindedir. React 2026 yilina gelindiginde, butun bir performans stratejisi olusturmak icin gereken araclarin cogu dilin kendisinde yerlesik olarak bulunuyor.
Server Bilesenleri, Suspense ve arti istege bagli olarak sunulan derleyici sayesinde, optimize edilmesi gereken kodun orani hizla azalmaktadir. Ancak dikkat edilmesi gereken nokta, optimizasyon ihtiyacinin ortadan kalktigi degil, dogru optimizasyonun odak noktasinin degismis oldugudur. Bu yazi, gercekten fark yaratan stratejileri, teoriden degil uretimdeki olcumlerden yola cikarak ele alacaktir.
React Derleyicisi: Otomatik olarak nasil calisir
React 19 ile birlikte duyurulan React Derleyicisi (compiler), yeniden render lari otomatik olarak onler. Kodunuzu analiz eder ve bir bilesenin girdilerinin degismedigi durumlarda yeniden render i atlamak icin gerekli useMemo ve useCallback cagrilarini ekler. Gelistirici olarak bu optimizasyonlari manuel olarak yapmaniza gerek kalmaz; derleyici bunlari olusturma sirasinda ekler.
Ancak Derleyici sihirbazlik yapmaz. Is parcaciklari (workers), asenkron veri veya global state gibi reaktivite sisteminin disinda kalan durumlarda manuel optimizasyon hala gereklidir. Ayrica Derleyicinin dogru sekilde optimize edebilmesi icin kodun belirli kurallara uymasi gerekir: ornegin bir bilesenin state inin dogrudan degistirilmemesi (mutasyon).
Derleyici aktif hale getirildiginde dikkat edilmesi gereken en onemli sey, bir optimizasyonun yanlis calisip calismadigini dogrulamaktir. Profiler i kullanarak render sayisini izleyin. Derleyicinin calistigini gormek icin bir bilesenin ikinci bir render da calismamasi gerekir, ancak bu dogrulamayi profil aracinda yapmalisiniz, tahminle degil.
Bilesen bolme ve olceklendirme
Buyuk bilesenleri bolmek, performans acisindan en etkili ve en az anlasilan stratejilerden biridir. Bir bilesenin 200 satir JSX i ve yirmi state degiskeni varsa, en kucuk bir degisiklik tum bileseni yeniden render eder. Bileseni mantiksal parcalara ayirmak, her bir parcayi bagimsiz hale getirir.
Ancak buradaki amac, dosya sayisini artirmak degildir. Asil amac, state in kapsamini daraltmaktir. Bir input alani degistiginde tum sayfanin yeniden render olmasini istemeyiz. Input un state i yalnizca input un kendisinde olmali ve degisiklik yalnizca o bileseni yeniden render etmelidir.
// Before: all state in one component
function SearchPage() {
const [query, setQuery] = useState("");
const [results, setResults] = useState<Result[]>([]);
const [isLoading, setIsLoading] = useState(false);
// ...everything re-renders on every keystroke
}
// After: lift state boundaries
function SearchPage() {
const [query, setQuery] = useState("");
return (
<>
<SearchInput value={query} onChange={setQuery} />
<SearchResults query={query} />
</>
);
}
function SearchInput({ value, onChange }: { value: string; onChange: (v: string) => void }) {
return <input value={value} onChange={(e) => onChange(e.target.value)} />;
}
function SearchResults({ query }: { query: string }) {
// Only re-renders when query changes
return <SlowList query={query} />;
}Bu desen, yalnizca bilesen bolmekten ibaret degildir. State i asagi dogru iterek, Degisikligin yalnizca etkilenen kismi yeniden render etmesini saglariz. SearchResults bileseni, yalnizca query degistiginde yeniden render olur; bu, her tus vurusunda degil, genellikle yazma tamamlandiktan sonra gerceklesir.
State yonetim stratejileri: Gereksiz render lari azaltmak
State yonetimi, React performansinin en buyuk belirleyicilerinden biridir. State bir degistiginde, o state i kullanan her bilesen yeniden render olur. State in kapsami ne kadar genisse, o kadar fazla bilesen gereksiz yere yeniden render olur.
Context API kullanisli olmakla birlikte, dikkatli kullanilmazsa performans sorunlarina yol acabilir. Bir context degerindeki herhangi bir degisiklik, o context i kullanan tum bilesenleri yeniden render eder. Cozum genellikle context i birden fazla parcaya bolmek veya Zustand, Jotai veya Valtio gibi daha hassas abonelik saglayan bir kutuphane kullanmaktir.
Bu kutuphanelerin ortak noktasi, state in parcacikli bir sekilde abone olunmasina izin vermeleridir. Zustand da bir store dan secici (selector) ile bir alan okudugunuzda, bilesen yalnizca o alan degistiginde yeniden render olur. Context in varsayilani olan her seyi yeniden render etme davranisina kiyasla bu buyuk bir fark yaratir.
// Zustand: granular subscriptions
const useStore = create<{ count: number; text: string }>((set) => ({
count: 0,
text: "",
}));
function Counter() {
const count = useStore((s) => s.count);
// Only re-renders when count changes
return <div>{count}</div>;
}
function TextDisplay() {
const text = useStore((s) => s.text);
// Only re-renders when text changes
return <div>{text}</div>;
}State yonetimi icin bir diger strateji de state i mumkun oldugunca sunucuya yakin tutmaktir. React Server Bilesenleri, state in bir kismini dogrudan sunucuda isler ve yalnizca sonucu istemciye gonderir. Bu sayede istemci tarafinda state yonetimi ihtiyaci azalir ve gereksiz render larin onune gecilir.
Suspense ve akis kontrolu
Suspense, React in asenkron bagimliliklari yoneten mekanizmasidir. Bir bilesen veri yuklerken Suspense, bir yedek icerik (fallback) gosterir ve veri hazir oldugunda asil bileseni gosterir. Ancak Suspense in performans acisindan asil degeri, akisi kontrol edebilmesidir.
Suspense in dogru kullanimi, kullaniciya gereksiz yuklenme animasyonlari gostermekten kacinmayi icerir. Iyi bir strateji, birbiriyle iliskili verileri grup halinde yuklemektir. Kullanici bir sayfaya gittiginde, sayfadaki tum verilerin yuklenmesini beklemek yerine, baslangicta yalnizca kritik veri icin bir Suspense siniri koymak, daha sonra diger bolumleri kademeli olarak yuklemek daha iyi bir kullanici deneyimi saglar.
Suspense i kullanirken, her Suspense sinirinin bir yedek icerige sahip olmasi gerekir. Ancak ic ice gecmis Suspense sinirleri, kullanicinin sayfayi parcali bir sekilde gormesine ve her bir bolum hazir oldukca goruntulemesine olanak tanir. Bu, ozellikle yavas baglantilarda buyuk fark yaratir.
React Server Bilesenleri: Dogru yerlesim
React Server Bilesenleri, React 19 ile birlikte olgunlasan bir modeldir. Bir bilesenin yalnizca sunucuda calismasi ve sonucu istemciye HTML olarak gonderilmesi esasina dayanir. Bu, o bilesenin istemci tarafinda calistirilmasina gerek kalmadigi anlamina gelir; dolayisiyla ne JavaScript indirilir ne de istemcide render edilir.
Server Bilesenleri, ozellikle statik icerik, veri tabani sorgulari ve API cagrilari icin idealdir. Bir liste sayfasinda, listeyi sunucuda olusturmak, istemcinin JavaScript yuklemesini, veriyi fetch etmesini ve listeyi render etmesini beklemekten cok daha hizlidir.
Ancak Server Bilesenleri her sorunu cozmez. Kullanici etkilesimi gerektiren bilesenler (state, event handler, efektler) istemcide kalmali veya bir istemci bilesenine aktarilmalidir. Dogru strateji, sayfayi bir Server Bileseni olarak baslatip, yalnizca etkilesim gerektiren alt bilesenleri istemci bileseni olarak isaretlemektir.
Derleme araclari ve bundle optimizasyonu
React performansi yalnizca calisma zamaniyla ilgili degildir; ayni zamanda kullanicinin tarayicisina ne kadar kod gonderdiginizle de ilgilidir. Modern ar acilari (Vite, Turbopack, Rspack), gelistirme ve uretim yapilarini optimize etmek icin cesitli stratejiler sunar.
Kod bolme (code splitting), en temel optimizasyondur. react-router-dom ile birlikte React.lazy ve Suspense kullanarak her sayfayi ayri bir bundle haline getirebilir ve kullanicinin yalnizca o an ihtiyac duydugu kodu indirmesini saglayabilirsiniz. Ancak kod bolmeyi abartmamak gerekir; her bileseni ayri bir dosyaya bolmek, HTTP isteklerinin sayisini artirir ve aslinda performansi dusurebilir.
import { lazy, Suspense } from "react";
const Dashboard = lazy(() => import("./pages/Dashboard"));
const Settings = lazy(() => import("./pages/Settings"));
export function App() {
return (
<Suspense fallback={<PageSkeleton />}>
<Routes>
<Route path="/dashboard" element={<Dashboard />} />
<Route path="/settings" element={<Settings />} />
</Routes>
</Suspense>
);
}Bundle analizi icin sirk alari (Vite visualize, Webpack Bundle Analyzer) kullanmak, hangi kutuphanelerin bundle boyutunu sisirdigini gormek icin onemlidir. Genellikle bir kutuphanenin yalnizca kucuk bir kismini kullanmaniza ragmen tamaminin bundle a eklendigini gorursunuz. Bu durumda, kutuphanenin agac sallama (tree-shaking) uyumlu olup olmadigini kontrol edin veya daha kucuk bir alternatif arayin.
Olcum ve izleme
Performans calismalari, olcumle baslamalidir. React Developer Tools profil aracini kullanarak hangi bilesenlerin gereksiz yere render edildigini gorun. Ancak uretim performansi, gelistirme ortamindan farklidir. Bu nedenle uretimde de performansi izlemek gerekir.
Web Vitals (LCP, FID, CLS), kullanicinin gercek deneyimini olcmek icin standart metriklerdir. React 19 ile birlikte gelen reportWebVitals fonksiyonu, bu metrikleri dogrudan yakalamanizi saglar. Ayrica, kendi performans markirlarinizi ekleyerek, belirli bir bilesenin ne zaman render edildigini ve ne kadar surdugunu olcebilirsiniz.
Performans iyilestirmeleri yaparken, degisikliklerin etkisini olcmek onemlidir. Bir iyilestirme yapmadan once ve sonra ayni metrikleri karsilastirin. Tahminler degil, veriler rehberiniz olsun.
