React.lazy ve Suspense ile kod bölme

Kullanıcılarınıza gerekenden fazla kod göndermeniz gerekmez. Bu durumun hiç yaşanmaması için paketlerinizi bölün.

React.lazy yöntemi, dinamik içe aktarma işlemleri kullanarak bir React uygulamasının kodunu bileşen düzeyinde bölme işlemini kolaylaştırır.

import React, { lazy } from 'react';

const AvatarComponent = lazy(() => import('./AvatarComponent'));

const DetailsComponent = () => (
  <div>
    <AvatarComponent />
  </div>
)

Bu neden yararlı?

Büyük bir React uygulaması genellikle birçok bileşen, yardımcı program yöntemi ve üçüncü taraf kitaplığından oluşur. Bir uygulamanın farklı bölümlerini yalnızca gerektiğinde yüklemek için çaba gösterilmezse kullanıcılar ilk sayfayı yükler yüklemez tek ve büyük bir JavaScript paketi gönderilir. Bu durum sayfa performansını önemli ölçüde etkileyebilir.

React.lazy işlevi, uygulamadaki bileşenleri çok az işlemle ayrı JavaScript parçalarına ayırmak için yerleşik bir yol sağlar. Ardından, Suspense bileşeniyle birlikte kullanırken yükleme durumlarını yönetebilirsiniz.

Gerilim

Kullanıcılara büyük bir JavaScript yük göndermenin sorunu, özellikle daha zayıf cihazlarda ve ağ bağlantılarında sayfanın yüklenmesinin tamamlanması için gereken süredir. Bu nedenle kod bölme ve yavaş yükleme son derece yararlıdır.

Ancak, kod bölme bileşeni ağ üzerinden getirilirken kullanıcıların her zaman biraz beklemesi gerekir. Bu nedenle, faydalı bir yükleme durumu göstermek önemlidir. React.lazySuspense bileşeniyle kullanmak bu sorunu çözmeye yardımcı olur.

import React, { lazy, Suspense } from 'react';

const AvatarComponent = lazy(() => import('./AvatarComponent'));

const renderLoader = () => <p>Loading</p>;

const DetailsComponent = () => (
  <Suspense fallback={renderLoader()}>
    <AvatarComponent />
  </Suspense>
)

Suspense, herhangi bir React bileşenini yükleme durumu olarak görüntülemenize olanak tanıyan bir fallback bileşeni kabul eder. Aşağıdaki örnekte bu işlemin nasıl çalıştığı gösterilmektedir. Avatar yalnızca düğme tıklandığında oluşturulur. Ardından, askıya alınmış AvatarComponent için gerekli kodu almak üzere bir istek gönderilir. Bu sırada yedek yükleme bileşeni gösterilir.

Burada, AvatarComponent öğesini oluşturan kod küçüktür. Bu nedenle, yükleme spinner'ı yalnızca kısa bir süre gösterilir. Özellikle zayıf ağ bağlantılarında büyük bileşenlerin yüklenmesi çok daha uzun sürebilir.

Bunun nasıl çalıştığına dair daha iyi bir örnek vermek için:

  • Siteyi önizlemek için Uygulamayı Görüntüle'ye, ardından Tam Ekran'a tam ekran basın.
  • Geliştirici Araçları'nı açmak için "Kontrol+Üst Karakter+J" (veya Mac'te "Komut+Option+J") tuşlarına basın.
  • sekmesini tıklayın.
  • Varsayılan olarak Kısıtlama yok olarak ayarlanmış Kısıtlama açılır menüsünü tıklayın. Hızlı 3G'yi seçin.
  • Uygulamadaki Beni Tıkla düğmesini tıklayın.

Yükleme göstergesi artık daha uzun süre gösterilecek. AvatarComponent öğesini oluşturan tüm kodun ayrı bir parça olarak nasıl getirildiğine dikkat edin.

Bir chunk.js dosyasının indirilmesini gösteren DevTools ağ paneli

Birden çok bileşeni askıya alma

Suspense'ün bir diğer özelliği de, tümü yavaş yüklenmiş olsa bile birden fazla bileşenin yüklenmesini askıya almanıza olanak tanımasıdır.

Örneğin:

import React, { lazy, Suspense } from 'react';

const AvatarComponent = lazy(() => import('./AvatarComponent'));
const InfoComponent = lazy(() => import('./InfoComponent'));
const MoreInfoComponent = lazy(() => import('./MoreInfoComponent'));

const renderLoader = () => <p>Loading</p>;

const DetailsComponent = () => (
  <Suspense fallback={renderLoader()}>
    <AvatarComponent />
    <InfoComponent />
    <MoreInfoComponent />
  </Suspense>
)

Bu, yalnızca tek bir yükleme durumu gösterirken birden fazla bileşenin oluşturulmasını geciktirmek için son derece kullanışlı bir yöntemdir. Tüm bileşenler getirildikten sonra kullanıcı, bunların hepsini aynı anda görüntüleyebilir.

Bunu aşağıdaki yerleşik öğeyle görebilirsiniz:

Bu olmadan kademeli yükleme sorunuyla veya kullanıcı arayüzünün farklı bölümlerinin her birinin kendi yükleme göstergesiyle birbiri ardına yüklenmesiyle karşılaşmak kolaydır. Bu durum, kullanıcı deneyimini daha can sıkıcı hale getirebilir.

Yükleme hatalarını işleme

Suspense, ağ istekleri yapılırken geçici bir yükleme durumu göstermenize olanak tanır. Ancak bu ağ istekleri herhangi bir nedenle başarısız olursa ne olur? İnternete bağlı olmayabilirsiniz veya web uygulamanız, sunucu yeniden dağıtımı sonrasında artık kullanılamayan ve güncel olmayan bir sürümlü URL'yi yavaş yüklemeye çalışıyor olabilir.

React, bu tür yükleme hatalarını sorunsuz bir şekilde ele almak için standart bir kalıba sahiptir: hata sınırı kullanma. Belgelerde açıklandığı gibi, static getDerivedStateFromError() veya componentDidCatch() yaşam döngüsü yöntemlerinden birini (veya ikisini birden) uygulayan tüm React bileşenleri hata sınırı olarak kullanılabilir.

Yavaş yükleme hatalarını algılayıp işlemek için Suspense bileşeninizi hata sınırı görevi gören bir üst bileşenle sarabilirsiniz. Hata sınırının render() yönteminde, hata yoksa çocukları olduğu gibi oluşturabilir veya bir sorun oluşursa özel bir hata mesajı oluşturabilirsiniz:

import React, { lazy, Suspense } from 'react';

const AvatarComponent = lazy(() => import('./AvatarComponent'));
const InfoComponent = lazy(() => import('./InfoComponent'));
const MoreInfoComponent = lazy(() => import('./MoreInfoComponent'));

const renderLoader = () => <p>Loading</p>;

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 <p>Loading failed! Please reload.</p>;
    }

    return this.props.children;
  }
}

const DetailsComponent = () => (
  <ErrorBoundary>
    <Suspense fallback={renderLoader()}>
      <AvatarComponent />
      <InfoComponent />
      <MoreInfoComponent />
    </Suspense>
  </ErrorBoundary>
)

Sonuç

React uygulamanıza kod bölme özelliğini nereden uygulayacağınızdan emin değilseniz aşağıdaki adımları uygulayın:

  1. Rota düzeyinden başlayın. Rotalar, uygulamanızda bölünebilecek noktaları belirlemenin en basit yoludur. Tepki dokümanları, Suspense'nin react-router ile birlikte nasıl kullanılabileceğini gösterir.
  2. Sitenizdeki bir sayfada yalnızca belirli kullanıcı etkileşimlerinde (ör. bir düğmenin tıklanması) oluşturulan büyük bileşenleri tanımlayın. Bu bileşenleri bölmek, JavaScript yüklerinizi en aza indirir.
  3. Ekran dışında olan ve kullanıcı için kritik olmayan diğer tüm öğeleri bölmeyi düşünün.