React.lazy ve Suspense ile kod bölme

Kullanıcılarınıza asla gerekenden fazla kod göndermeniz gerekmez. Bu nedenle, bunun gerçekleşmediğinden emin olmak için paketlerinizi bölün.

React.lazy yöntemi, dinamik içe aktarmaları kullanarak bir React uygulamasını bileşen düzeyinde kodlara bölmeyi kolaylaştırır.

import React, { lazy } from 'react';

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

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

Neden yararlıdır?

Büyük bir React uygulaması genellikle birçok bileşen, yardımcı yöntem ve üçüncü taraf kitaplığından oluşur. Bir uygulamanın farklı bölümlerini yalnızca gerektiğinde yüklemeye çalışılmazsa kullanıcılarınız ilk sayfayı yüklediği anda onlara tek ve büyük bir JavaScript paketi gönderilir. Bu durum, sayfa performansını önemli ölçüde etkileyebilir.

React.lazy işlevi, bir uygulamadaki bileşenleri çok az çabayla ayrı JavaScript parçalarına ayırmak için yerleşik bir yöntem sunar. Ardından, Suspense bileşeniyle birlikte kullandığınızda 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ının uzun sürmesidir. Bu nedenle kod bölme ve geç yükleme son derece yararlıdır.

Ancak, ağ üzerinden kod bölünmüş bir bileşen getirilirken kullanıcıların her zaman kısa bir gecikme yaşaması gerekir. Bu nedenle, faydalı bir yükleme durumu göstermek önemlidir. React.lazy'yı Suspense bileşeniyle kullanmak bu sorunu çözmenize 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şenini kabul eder. Aşağıdaki örnekte bu özelliğin nasıl çalıştığı gösterilmektedir. Avatar yalnızca düğme tıklandığında oluşturulur. Bu durumda, 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 simgesini oluşturan kod küçüktür. Bu nedenle yükleme çarkı yalnızca kısa bir süre gösterilir. Daha büyük bileşenlerin yüklenmesi, özellikle zayıf ağ bağlantılarında çok daha uzun sürebilir.

Bu özelliğin işleyiş şeklini daha iyi göstermek için:

  • Siteyi önizlemek için Uygulamayı Görüntüle'ye basın. Ardından Tam Ekran'a basın. tam ekran
  • Geliştirici Araçları'nı açmak için `Control+Shift+J` (veya Mac'te `Command+Option+J`) tuşlarına basın.
  • sekmesini tıklayın.
  • Varsayılan olarak Kısıtlama yok olarak ayarlanan Kısıtlama açılır listesini tıklayın. Hızlı 3G'yi seçin.
  • Uygulamada Click Me (Beni Tıkla) düğmesini tıklayın.

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

Bir chunk.js dosyasının indirildiğini gösteren Geliştirici Araçları ağ paneli

Birden çok bileşeni askıya alma

Suspense'nın bir diğer özelliği de tümü geç 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, birden fazla bileşenin oluşturulmasını geciktirirken yalnızca tek bir yükleme durumu göstermek için son derece kullanışlı bir yöntemdir. Tüm bileşenler getirme işlemini tamamladığında kullanıcı, bunların hepsini aynı anda görüntüleyebilir.

Bunu aşağıdaki yerleştirme ile görebilirsiniz:

Bu olmadan kademeli yükleme sorunuyla karşılaşmak kolaydır. Diğer bir deyişle, kullanıcı arayüzünün farklı bölümleri, her biri kendi yükleme göstergesine sahip olacak şekilde birbiri ardına yüklenir. Bu durum, kullanıcı deneyiminin daha rahatsız edici olmasına neden olabilir.

Yükleme hatalarını yönetme

Suspense, arka planda 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? İnternet bağlantınız olmayabilir veya web uygulamanız, sunucu yeniden dağıtımı sonrasında artık kullanılamayan ve güncel olmayan bir sürüm oluşturulmuş URL'yi geç yüklemeye çalışıyor olabilir.

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

Geç yükleme hatalarını algılamak ve işlemek için Suspense bileşeninizi hata sınırı görevi gören bir üst bileşenle sarmalayabilirsiniz. Hata sınırının render() yönteminde, hata yoksa alt öğeleri 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ızda kod bölmeyi uygulamaya nereden başlayacağınızdan emin değilseniz aşağıdaki adımları uygulayın:

  1. Rota düzeyinden başlayın. Rotalar, uygulamanızın bölünebilecek noktalarını belirlemenin en basit yoludur. React belgelerinde, Suspense ile react-router'ın nasıl kullanılabileceği gösterilmektedir.
  2. Sitenizdeki bir sayfada yalnızca belirli kullanıcı etkileşimlerinde (ör. bir düğmeyi tıklama) oluşturulan büyük bileşenleri belirleyin. 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 deneyin.