Developpement web
ReactJS
Remix
Guides techniques

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

Virgile Rietsch
Par Virgile RIETSCH·Fondateur Algomax · Ex-CTO
4 minutes de lecture95 vues
PartagerXLinkedInWhatsApp
Comment différer le chargement des données en React ?

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

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é client

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

index.tsx
1
import { useEffect, useState } from 'react';
2
3
type UserType = { id: number; email: string };
4
5
const loadUsers = async () => {
6
const response = await fetch('https://jsonplaceholder.typicode.com/users');
7
const users = (await response.json()) as UserType[];
8
return users;
9
};
10
11
const Component = () => {
12
const [users, setUsers] = useState<UserType[]>([]);
13
useEffect(() => {
14
loadUsers().then((data) => setUsers(data));
15
}, []);
16
17
return (
18
<ul>
19
{users.map((user) => (
20
<li key={user.id}>{user.email}</li>
21
))}
22
</ul>
23
);
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 Remix

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
1
import { json } from '@remix-run/node';
2
import { useLoaderData } from '@remix-run/react';
3
type UserType = { id: number; email: string };
4
const loadUsers = async () => {
5
const response = await fetch('https://jsonplaceholder.typicode.com/users');
6
const users = (await response.json()) as UserType[];
7
return users;
8
};
9
export const loader = async () => {
10
const users = await loadUsers();
11
return json(users);
12
};
13
const Component = () => {
14
const users = useLoaderData<typeof loader>();
15
return (
16
<ul>
17
{users.map((user) => (
18
<li key={user.id}>{user.email}</li>
19
))}
20
</ul>
21
);
22
};
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 Remix

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
1
import { defer } from '@remix-run/node';
2
import { Await, useLoaderData } from '@remix-run/react';
3
import { Suspense } from 'react';
4
type UserType = { id: number; email: string };
5
const loadUsers = async () => {
6
const response = await fetch('https://jsonplaceholder.typicode.com/users');
7
const users = (await response.json()) as UserType[];
8
return users;
9
};
10
export const loader = async () => {
11
const usersPromise = loadUsers();
12
return defer({ usersPromise });
13
};
14
const Component = () => {
15
const { usersPromise } = useLoaderData<typeof loader>();
16
return (
17
<Suspense fallback={<span>Chargement des utilisateurs</span>}>
18
<Await
19
resolve={usersPromise}
20
errorElement={<span>Erreur lors du chargement des utilisateurs</span>}
21
>
22
{(users) => (
23
<ul>
24
{users.map((user) => (
25
<li key={user.id}>{user.email}</li>
26
))}
27
</ul>
28
)}
29
</Await>
30
</Suspense>
31
);
32
};
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 !

Pages utiles pour approfondir

Si ce sujet vous concerne, ces pages vous aideront à comparer les options, cadrer un budget et choisir la bonne direction produit.

Vous voulez un SaaS ?

Plateforme SaaS sur mesure. Réservez un appel découverte gratuit.

Reste informé

Abonne-toi à notre newsletter pour recevoir les dernières mises à jour et insights.