React.lazy ve Suspense ile kod bölme

Kullanıcılarınıza gerekenden daha fazla kod göndermenize gerek yoktur. Dolayısıyla, bunun olmaması için paketlerinizi bölün!

React.lazy yöntemi, dinamik içe aktarma işlemlerini kullanarak bir React uygulamasını bileşen düzeyinde kodlamayı kolaylaştırır.

import React, { lazy } from 'react';

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

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

Neden faydalı oldu?

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 ihtiyaç olduğunda yüklemeye çalışmak için çaba harcanmazsa kullanıcılarınız ilk sayfayı yükler yüklemez kullanıcılarınıza 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 iş yüküyle ayrı JavaScript parçalarına ayırmak için yerleşik bir yol sunar. Daha sonra, Suspense bileşeni ile eşleyerek yükleme durumlarını halledebilirsiniz.

Gerilim

Kullanıcılara büyük bir JavaScript yükünün gönderilmesiyle ilgili sorun, özellikle zayıf cihazlar ve ağ bağlantılarında, sayfanın yüklenmesinin tamamlanması için gereken sürenin uzunluğudur. Bu nedenle kod bölme ve geç yükleme son derece yararlıdır.

Bununla birlikte, ağ üzerinden bir kod bölme bileşeni getirilirken kullanıcılara her zaman hafif bir gecikme yaşanır. Bu nedenle, faydalı bir yükleme durumu görüntülemek önemlidir. React.lazy'yi Suspense 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şenini kabul eder. Aşağıdaki örnekte bunun işleyiş şekli gösterilmektedir. Avatar, yalnızca düğme tıklandığında oluşturulur ve askıya alınan AvatarComponent için gerekli kodun alınması için istekte bulunur. Bu arada, yedek yükleme bileşeni gösterilir.

Burada, AvatarComponent kodunu oluşturan kod küçük olduğundan yükleme döner simgesi yalnızca kısa bir süre için görünür. Büyük bileşenlerin yüklenmesi, özellikle zayıf ağ bağlantılarında çok daha uzun sürebilir.

Bunun işleyiş şeklini daha iyi göstermek için:

  • Siteyi önizlemek için Uygulamayı Göster'e, ardından Tam Ekran'a tam ekran basın.
  • 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 şeklinde ayarlanan Kısıtlama açılır listesini tıklayın. Fast 3G'yi seçin.
  • Uygulamadaki Beni Tıkla düğmesini tıklayın.

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

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

Birden çok bileşeni askıya alma

Suspense ürününün bir başka ö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, yalnızca tek bir yükleme durumu gösterirken birden fazla bileşenin oluşturulmasını geciktirmek için son derece faydalı bir yoldur. Tüm bileşenlerin getirilmesi bittikten sonra, kullanıcı bunların tümünün aynı anda görüntülendiğini görür.

Aşağıdaki yerleşik öğe ile bunu görebilirsiniz:

Bu olmadığında, kademeli yükleme sorunu veya kullanıcı arayüzünün farklı bölümlerinin, her biri kendi yükleme göstergesine sahip olan birbiri ardına yüklenmesi gibi sorunlarla karşılaşabilirsiniz. Bu, kullanıcı deneyimini daha da karalayıcı hissettirebilir.

Yükleme hatalarını işleme

Suspense, arka planda ağ istekleri yapılırken geçici bir yükleme durumu göstermenize olanak tanır. Peki bu ağ istekleri bir nedenden dolayı başarısız olursa ne olur? İnternete bağlı olmayabilirsiniz veya web uygulamanız, eski ve sunucu yeniden dağıtımının ardından artık kullanılamayan sürümlü bir URL'yi geç 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ı kullanımı. Belgelerde açıklandığı gibi, herhangi bir React bileşeni, static getDerivedStateFromError() veya componentDidCatch() yaşam döngüsü yöntemlerinden birini (veya ikisini birden) uyguluyorsa hata sınırı olarak kullanılabilir.

Geç yükleme hatalarını tespit edip işlemek için Suspense bileşeninizi hata sınırı görevi gören üst bileşenlerle sarmalayabilirsiniz. Hata sınırının render() yöntemi içinde, herhangi bir hata yoksa alt öğeleri olduğu gibi oluşturabilir veya bir şeyler ters gittiğinde ö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ölmeyi nereden uygulamaya başlayacağınızdan emin değilseniz şu adımları uygulayın:

  1. Rota seviyesinde başlayın. Rotalar, uygulamanızda bölünebilecek noktaları belirlemenin en basit yoludur. React belgeleri, Suspense ile react-router birlikte nasıl kullanılabileceğini gösterir.
  2. Sitenizdeki bir sayfada bulunan ve yalnızca belirli kullanıcı etkileşimlerinde (bir düğmeyi tıklama gibi) oluşturulan büyük bileşenleri belirleyin. Bu bileşenleri bölmek JavaScript yüklerinizi en aza indirir.
  3. Ekran dışındaki ve kullanıcı için kritik olmayan diğer öğeleri bölmeyi düşünün.