React uygulamalarında başlangıç yükünü azaltmanın en etkili yolu, kod parçalama ve tembel yükleme kullanmaktır. React.lazy() ve Suspense, bileşenleri yalnızca gerektiğinde yüklemenizi sağlar. Bu sayede kullanıcılar yalnızca ihtiyaç duydukları kodu indirir, ilk ekran yüklenme süresi belirgin biçimde iyileşir.
Code splitting, uygulamanızı birden fazla parçaya ayırma işlemidir. Geleneksel derleme tek bir JS dosyası oluştururken, code splitting ile her sayfa veya büyük bileşen ayrı bir dosyaya bölünür. React.lazy(), dinamik import'u kullanarak bu parçaları istediğiniz zaman yüklemenizi sağlar. Suspense ise yükleme sırasında düşecek geçici bir UI tanımlamanıza olanak tanır.
React.lazy() Nasıl Çalışır?
React.lazy(), bir fonksiyon alır ve o fonksiyonun bir React bileşeni içeren modülü döndürmesini bekler. Genellikle dinamik import ile birlikte kullanılır. Örneğin:
const LazyComponent = React.lazy(() => import('./MyComponent'));
Bu kod, LazyComponent adında bir tembel yükleme bileşeni oluşturur. İlk render sırasında bu bileşen yüklenmez; ancak LazyComponent gerçekten render edilmeye çalıştığında, içe aktarma işlemi tetiklenir ve modül yüklenir.
Suspense ile Geçiş Yönetimi
React.lazy() tek başına kullanılamaz; bir Suspense bileşeni içinde kullanılmalıdır. Suspense, yüklenmekte olan bileşenler için bir fallback (bekleme) içeriği gösterir. Örnek:
import React, { Suspense } from 'react';
const LazyComponent = React.lazy(() => import('./MyComponent'));
function App() {
return (
<div>
<Suspense fallback={<div>Yükleniyor...</div>}>
<LazyComponent />
</Suspense>
</div>
);
}
Bu yaklaşım, yavaş ağ bağlantılarında kullanıcıya boş ekran yerine anlamlı bir geri bildirim sağlar.
Önemli: React.lazy() yalnızca default export'ları destekler. Named export kullanan bileşenler için bir ara modül oluşturarak default export olarak dışa aktarım yapmanız gerekir.
Code Splitting'in Faydaları
- İlk yükleme süresi azalır, kullanıcılar uygulamayı daha hızlı görmeye başlar.
- Bant genişliğinden tasarruf edilir; yalnızca ihtiyaç duyulan kod indirilir.
- Çok sayıda farklı rotası olan uygulamalarda her rota için ayrı kod parçası oluşturulabilir.
- React.lazy() ile birlikte React Router gibi kütüphanelerle rota bazlı code splitting yapmak kolaydır.
Rota Bazlı Code Splitting
En yaygın kullanım alanı, uygulamanın farklı sayfalarını ayrı kod parçalarına bölmektir. Örneğin bir blog uygulamasında Ana Sayfa, Yazı Detayı ve Hakkımızda sayfaları ayrı ayrı yüklenebilir. React Router ile birlikte kullanım:
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import React, { Suspense } from 'react';
const HomePage = React.lazy(() => import('./pages/HomePage'));
const ArticlePage = React.lazy(() => import('./pages/ArticlePage'));
const AboutPage = React.lazy(() => import('./pages/AboutPage'));
function App() {
return (
<Router>
<Suspense fallback={<div>Sayfa yükleniyor...</div>}>
<Routes>
<Route path="/" element={<HomePage />} />
<Route path="/article/:id" element={<ArticlePage />} />
<Route path="/about" element={<AboutPage />} />
</Routes>
</Suspense>
</Router>
);
}
Bu yapıda her rotaya ait JavaScript dosyası, yalnızca o rotaya gidildiğinde yüklenir. İlk yükleme yalnızca ana sayfanın kodunu içerir.
Named Export Kullanırken Dikkat Edilmesi Gerekenler
React.lazy() yalnızca default export'ları desteklediği için, named export kullanan bileşenlerde ekstra bir modül yazmanız gerekir. Örneğin:
// NamedExportComponent.js
export const NamedExportComponent = () => { /* ... */ };
// LazyWrapper.js
export { default } from './NamedExportComponent';
// Kullanım
const LazyComponent = React.lazy(() => import('./LazyWrapper'));
Ya da doğrudan dinamik import içinde named export'u default'a dönüştürebilirsiniz:
const LazyComponent = React.lazy(() =>
import('./NamedExportComponent').then(module => ({ default: module.NamedExportComponent }))
);
Performans İzleme ve Hata Yönetimi
Suspense fallback'i gösterilirken olası ağ hataları veya bileşen yükleme başarısızlıklarına karşı bir hata sınırı (error boundary) kullanmak iyi bir uygulamadır. React'te hata sınırı oluşturmak için:
import React from 'react';
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
return { hasError: true };
}
render() {
if (this.state.hasError) {
return <h1>Bir hata oluştu.</h1>;
}
return this.props.children;
}
}
Suspense ve hata sınırını birleştirerek eksiksiz bir yükleme deneyimi sunabilirsiniz.
React.lazy() ile ilgili daha fazla bilgi için React State Management: Redux vs Context API vs Zustand yazımıza da göz atabilirsiniz. Ayrıca, performansı artırmak için React'te Debounce ve Throttle Nasıl Uygulanır? yazımızda farklı bir optimizasyon tekniği bulacaksınız.
En İyi Uygulamalar ve Yaygın Hatalar
Doğru
- Büyük üçüncü taraf kütüphaneleri ve nadiren kullanılan bileşenleri tembel yükleyin.
- Her sayfa için ayrı bir kod parçası oluşturun.
- Suspense fallback'i kullanıcı dostu ve küçük olmalıdır.
- Hata sınırı kullanarak yükleme hatalarını yakalayın.
Yanlış
- Her küçük bileşen için lazy load kullanmayın; bu çok sayıda küçük ağ isteği oluşturur.
- Fallback olarak çok ağır bir bileşen kullanmaktan kaçının.
- Named export'ları doğrudan lazy() içinde kullanmayın; hata alırsınız.
React.lazy() ve Suspense ile ilgili daha derinlemesine bilgi için React resmi dokümantasyonuna başvurun. Uygulamanızın büyüklüğüne ve kullanıcı deneyimine bağlı olarak doğru noktalarda code splitting kullanmak, modern web uygulamalarında vazgeçilmez bir tekniktir.
Sık Sorulan Sorular
React.lazy() ile yalnızca default export'lar mı kullanılabilir?
Evet, React.lazy() yalnızca default export'ları destekler. Named export kullanan bileşenler için bir ara modül oluşturarak default export yapmalısınız.
Code splitting her durumda performansı artırır mı?
Hayır. Aşırı sayıda küçük kod parçası oluşturmak, çok sayıda ağ isteği yapılmasına ve ek gecikmeye neden olabilir. Genellikle sayfa veya rota bazlı bölümlendirme en uygunudur.
Suspense fallback'inde yükleme animasyonu gösterebilir miyim?
Evet, fallback prop'una herhangi bir React bileşeni (örneğin bir spinner) verebilirsiniz. Ancak bu bileşenin küçük ve hafif olmasına dikkat edin.
React.lazy() ile birlikte Error Boundary zorunlu mu?
Zorunlu değil ancak şiddetle önerilir. Ağ hatası veya bileşen yükleme başarısızlığında kullanıcıya boş ekran yerine bir hata mesajı göstermek için idealdir.






