Retour aux articles

Comment différer le chargement des données en React ?

Chargement différé avec Remix
4 minutes de lecture- 39 vues

Comment activer le chargement différé des données avec Remix (defer)Header Icon

En développant une application React, vous avez surement déjà eu avoir à charger des données depuis une API externe. Pour ce faire, plusieurs solutions s'offrent à vous :

  • les charger côté client (dans un useEffect)
  • les charger côté serveur (avec un framework comme Remix ou NextJS)

Mais il existe une troisième option (si vous utilisez Remix) : Déclencher le chargement des donnés côté serveur, mais ne pas attendre la réponse du serveur pour afficher la page à l'utilisateur. Découvrons comment avec des exemples :

Chargement côté clientHeader Icon

Voici la syntaxe pour des données côté client

index.tsx

_24
import { useEffect, useState } from 'react';
_24
_24
type UserType = { id: number; email: string };
_24
_24
const loadUsers = async () => {
_24
const response = await fetch('https://jsonplaceholder.typicode.com/users');
_24
const users = (await response.json()) as UserType[];
_24
return users;
_24
};
_24
_24
const Component = () => {
_24
const [users, setUsers] = useState<UserType[]>([]);
_24
useEffect(() => {
_24
loadUsers().then((data) => setUsers(data));
_24
}, []);
_24
_24
return (
_24
<ul>
_24
{users.map((user) => (
_24
<li key={user.id}>{user.email}</li>
_24
))}
_24
</ul>
_24
);
_24
};

On affiche une liste d'utilisateurs, suite à un appel à l'API de JsonPlaceholder. Comme le chargement se fait côté client, la page va se charger très vite. Cependant, le visiteur ne verra pas tout de suite la liste des utilisateurs. Il faut attendre que l'API externe envoie une réponse positive, contenant la donnée.

Il y aura ensuite du Cumulative Layout Shift (CLS). Au chargement de la donnée, la liste va s'afficher et les éléments en dessous de la liste seront décallés vers le bas.

Certaines applications affichent même des indicateurs de chargement pour expliquer au visiteur qu'il y aura bientôt la donnée.

Pour remédier à ce problème, il suffit de charger la donnée côté serveur. Elle apporte trois améliorations :

  • Plus besoin d'afficher d'indicateur de chargement
  • Plus besoin de gérer la logique de chargement des données côté client
  • Pas de CLS (La liste aura toujours été là, il n'y aura plus de décallage

Chargement côté serveur avec RemixHeader Icon

Pour charger notre liste côté serveur en utilisant Remix, il suffit de déplacer la logique de chargement dans une méthode loader.

index.tsx

_23
import { json } from '@remix-run/node';
_23
import { useLoaderData } from '@remix-run/react';
_23
type UserType = { id: number; email: string };
_23
const loadUsers = async () => {
_23
const response = await fetch('https://jsonplaceholder.typicode.com/users');
_23
const users = (await response.json()) as UserType[];
_23
return users;
_23
};
_23
export const loader = async () => {
_23
const users = await loadUsers();
_23
return json(users);
_23
};
_23
const Component = () => {
_23
const users = useLoaderData<typeof loader>();
_23
return (
_23
<ul>
_23
{users.map((user) => (
_23
<li key={user.id}>{user.email}</li>
_23
))}
_23
</ul>
_23
);
_23
};
_23
export default Component;

Nous utilisons ensuite le hook spécial de Remix, useLoaderData pour récupérer les données renvoyées par le serveur (suite à l'exécution de la méthode loader).

Malgré les avantages énumérés plus haut, cette optimisation nous rajoute un inconvénient :

Nous devons attendre que les données soient chargées avant d'afficher la page. Le visiteur devra attendre plus longtemps devant une page blanche. Sauf que l'équipe de développement de Remix y a pensé. Nous pouvons utiliser la méthode defer pour les requêtes lentes et secondaires.

Implémenter le chargement différé de RemixHeader Icon

Pour charger nos données en différé, nous avons besoin de remplacer la méthode json de Remix par une méthode *defer.

De plus, au lieu d'utiliser await pour attendre le chargement de la donnée directement, nous l'appelons sans le mot-clé. Cela signifie que n'attendons pas la réponse de l'API avant de renvoyer notre donnée.

index.tsx

_33
import { defer } from '@remix-run/node';
_33
import { Await, useLoaderData } from '@remix-run/react';
_33
import { Suspense } from 'react';
_33
type UserType = { id: number; email: string };
_33
const loadUsers = async () => {
_33
const response = await fetch('https://jsonplaceholder.typicode.com/users');
_33
const users = (await response.json()) as UserType[];
_33
return users;
_33
};
_33
export const loader = async () => {
_33
const usersPromise = loadUsers();
_33
return defer({ usersPromise });
_33
};
_33
const Component = () => {
_33
const { usersPromise } = useLoaderData<typeof loader>();
_33
return (
_33
<Suspense fallback={<span>Chargement des utilisateurs</span>}>
_33
<Await
_33
resolve={usersPromise}
_33
errorElement={<span>Erreur lors du chargement des utilisateurs</span>}
_33
>
_33
{(users) => (
_33
<ul>
_33
{users.map((user) => (
_33
<li key={user.id}>{user.email}</li>
_33
))}
_33
</ul>
_33
)}
_33
</Await>
_33
</Suspense>
_33
);
_33
};
_33
export default Component;

Nous avons également utilisé le composant Suspense, qui est nécessaire pour utiliser le chargement différé. Analysons maintenant la syntaxe du composant Await. Durant le chargement des données, le composant Suspense affiche un message de chargement (déclaré dans le prop fallback). Une fois le chargement terminé, le composant Await qui reçoit en prop notre promesse usersPromise va nous afficher le composant enfant : notre liste d'utilisateurs.

Regardez-là sur YouTube dès maintenant !

Articles similaires
Gère les erreurs avec le framework Remix.js
6 minutes de lecture - 326 vuesRemixReactJS

Comment gérer les erreurs avec Remix ? (ErrorBoundary)

Avoir des erreurs Javascript ne fait jamais plaisir. Mais il existe le composant ErrorBoundary). Dans ce guide, tu vas découvrir comment afficher un composant d'erreur personnalisé en pour protéger toutes les pages de ton application.

Rejoins la

newsletter