Nie musisz wysyłać do użytkowników więcej kodu niż to konieczne, więc podziel swoje pakiety, aby mieć pewność, że nigdy tak się nie stanie.
Metoda React.lazy
ułatwia dzielenie kodu aplikacji React na poziomie komponentu za pomocą importów dynamicznych.
import React, { lazy } from 'react';
const AvatarComponent = lazy(() => import('./AvatarComponent'));
const DetailsComponent = () => (
<div>
<AvatarComponent />
</div>
)
Dlaczego to jest przydatne?
Duża aplikacja React zwykle składa się z wielu komponentów, metod pomocniczych i bibliotek innych firm. Jeśli nie uda się załadować różnych części aplikacji tylko wtedy, gdy są potrzebne, użytkownicy otrzymają jeden duży pakiet kodu JavaScript, gdy tylko wczytają pierwszą stronę. Może to znacząco wpłynąć na wydajność strony.
Funkcja React.lazy
zapewnia wbudowany sposób na oddzielanie komponentów aplikacji do oddzielnych fragmentów kodu JavaScript przy minimalnym nakładzie pracy. Następnie możesz zadbać o wczytywanie stanów, gdy połączysz komponent Suspense
.
Suspens
Problem z przesyłaniem dużych ładunków JavaScriptu do użytkowników polega na tym, że wczytywanie strony trwa długo, zwłaszcza na słabszych urządzeniach i przy słabszych połączeniach sieciowych. Dlatego dzielenie kodu i opóźnione wczytywanie są bardzo przydatne.
Jednak zawsze występuje niewielkie opóźnienie, gdy komponent podzielony na części jest pobierany przez sieć, dlatego ważne jest wyświetlanie przydatnego stanu wczytywania. Aby rozwiązać ten problem, użyj komponentu React.lazy
z elementem Suspense
.
import React, { lazy, Suspense } from 'react';
const AvatarComponent = lazy(() => import('./AvatarComponent'));
const renderLoader = () => <p>Loading</p>;
const DetailsComponent = () => (
<Suspense fallback={renderLoader()}>
<AvatarComponent />
</Suspense>
)
Suspense
przyjmuje komponent fallback
, co umożliwia wyświetlanie dowolnego komponentu React jako stanu wczytywania. Poniższy przykład pokazuje, jak to działa.
Tylko po kliknięciu przycisku następuje renderowanie awatara, a następnie wysyłane jest żądanie kodu niezbędnego do zawieszenia AvatarComponent
.
W międzyczasie wyświetlany jest komponent wczytywania zastępczego.
Kod, który tworzy AvatarComponent
, jest mały, dlatego ładujący się wskaźnik wyświetla się tylko przez krótki czas. Wczytywanie większych komponentów może potrwać znacznie dłużej, zwłaszcza w przypadku słabych połączeń sieciowych.
Aby lepiej zrozumieć, jak to działa:
- Aby wyświetlić podgląd witryny, kliknij Wyświetl aplikację, a następnie naciśnij Pełny ekran .
- Aby otworzyć Narzędzia dla programistów, naciśnij `Control+Shift+J` (lub `Command+Option+J` na Macu).
- Kliknij kartę Sieć.
- Kliknij menu Ograniczanie, które jest domyślnie ustawione na Bez ograniczania. Wybierz Szybka sieć 3G.
- W aplikacji kliknij przycisk Kliknij mnie.
Wskaźnik wczytywania będzie wyświetlał się dłużej. Zwróć uwagę, że cały kod, z którego składa się AvatarComponent
, jest pobierany jako osobny fragment.
Zawieszanie wielu komponentów
Kolejną funkcją Suspense
jest możliwość zawieszenia wczytywania wielu komponentów nawet wtedy, gdy są one wczytywane z opóźnieniem.
Na przykład:
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>
)
Jest to niezwykle przydatny sposób opóźnienia renderowania wielu komponentów przy jednoczesnym wyświetlaniu tylko jednego stanu wczytywania. Gdy wszystkie komponenty zostaną pobrane, użytkownik zobaczy je wszystkie wyświetlone w tym samym czasie.
Możesz to sprawdzić, korzystając z tego kodu embedowania:
Bez tego łatwo napotkać problem przerywanego wczytywania lub wczytywania różnych części interfejsu po kolei, z własnym wskaźnikiem wczytywania. Może to sprawić, że wrażenia użytkowników będą bardziej przykuwające uwagę.
Obsługa błędów wczytywania
Suspense
pozwala wyświetlić tymczasowy stan wczytywania, gdy w tle wysyłane są żądania sieciowe. Co jednak, jeśli te żądania sieciowe z jakiegoś powodu się nie powiodą? Możesz być offline lub Twoja aplikacja internetowa próbuje zlazy-loadować adres URL wersji, który jest nieaktualny iniedostępny po ponownym wdrożenie serwera.
React ma standardowy wzorzec radzenia sobie z takimi błędami wczytywania: korzysta z granicy błędów. Jak opisano w dokumentacji, każdy komponent React może pełnić funkcję granicy błędów, jeśli implementuje jedną (lub obie) z metod cyklu życia static getDerivedStateFromError()
lub componentDidCatch()
.
Aby wykrywać i rozwiązywać błędy leniwego ładowania, możesz opakować komponent Suspense
razem z komponentami nadrzędnymi, które pełnią funkcję granicy błędów. W metodzie render()
granicy błędu możesz wyrenderować elementy podrzędne w niezmienionej formie, jeśli nie będzie błędów, lub wyświetlić niestandardowy komunikat o błędzie, jeśli coś pójdzie nie tak:
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>
)
Podsumowanie
Jeśli nie wiesz, od czego zacząć stosowanie podziału kodu w aplikacji React, wykonaj te czynności:
- Zacznij od poziomu trasy. Trasy to najprostszy sposób na identyfikację punktów aplikacji, które można podzielić. W dokumentach React znajdziesz informacje o tym, jak używać
Suspense
w połączeniu zreact-router
. - Określ wszystkie duże komponenty na stronie w Twojej witrynie, które renderują się tylko w przypadku określonych interakcji użytkowników (np. kliknięcia przycisku). Podział tych komponentów pozwoli zminimalizować ładunki JavaScript.
- Zastanów się nad podziałem innych elementów, które znajdują się poza ekranem i nie są kluczowe dla użytkownika.