- Comme avec un JPEG progressif, les données JSON peuvent aussi être envoyées d’abord dans un état incomplet afin que le client puisse exploiter progressivement l’ensemble du contenu
- Le parsing JSON classique souffre d’une inefficacité : aucune opération n’est possible tant que toutes les données n’ont pas été entièrement reçues
- Avec une approche en breadth-first, les données sont découpées en plusieurs chunks (fragments) ; les parties pas encore prêtes sont représentées par des Promise puis remplies progressivement dès qu’elles le sont, ce qui permet au client d’utiliser aussi des données incomplètes
- Ce concept est l’innovation centrale des React Server Components (RSC), qui utilisent
<Suspense> pour contrôler des états de chargement intentionnellement échelonnés
- En séparant le streaming de données du flux intentionnel de chargement de l’UI, on peut offrir une expérience utilisateur plus flexible
L’idée du JPEG progressif et du JSON progressif
- Un JPEG progressif, au lieu de charger l’image d’un seul coup de haut en bas, affiche d’abord l’ensemble de façon floue puis l’affine progressivement
- De la même manière, appliquer une approche progressive à la transmission de JSON permet d’utiliser immédiatement une partie des données sans attendre que l’ensemble soit complet
- Dans l’exemple de structure de données JSON, l’approche habituelle ne permet le parsing qu’après réception de jusqu’au dernier octet
- Le client doit donc attendre que tout soit transmis, y compris les parties lentes du serveur (par exemple le chargement des commentaires depuis une base de données lente), ce qui constitue le standard actuel très inefficace
Les limites d’un parseur JSON en streaming
- L’introduction d’un parseur JSON en streaming permet de créer un arbre d’objets de données incomplet (intermédiaire)
- Mais lorsque seuls certains champs d’un objet (par ex.
footer, plusieurs éléments d’une liste de comment, etc.) sont transmis, cela entraîne des incohérences de type et rend difficile de savoir ce qui est réellement complet, ce qui réduit fortement l’utilité
- Comme pour le rendu HTML en streaming, traiter le flux dans l’ordre fait qu’une seule partie lente peut retarder l’ensemble du résultat
- C’est l’une des raisons pour lesquelles le streaming JSON est en général peu utilisé
Proposition de structure pour un JSON progressif
- Au lieu du streaming classique en profondeur, c’est-à-dire parcourir et transmettre l’intérieur de l’arbre jusqu’aux niveaux inférieurs, on adopte une approche breadth-first (en largeur)
- Seul l’objet de plus haut niveau est envoyé d’abord ; les valeurs enfants sont laissées comme placeholders de type Promise, puis remplies au fur et à mesure dans des chunks séparés
- Par exemple, à chaque fois que le serveur termine un chargement de données asynchrone, il envoie le chunk correspondant, et le client peut exploiter uniquement ce qui est prêt
- Cela permet une réception asynchrone des données (chargement précoce), sans attendre que plusieurs parties lentes soient toutes terminées
- Si le client est conçu pour bien gérer une réception de chunks hors séquence ou partiellement séquentielle, le serveur peut appliquer avec souplesse différentes stratégies de découpage en chunks
Inlining et Outlining : une transmission de données plus efficace
- Un format de streaming JSON progressif peut aussi éviter de dupliquer les objets réutilisés (par ex. la même information
userInfo référencée à plusieurs endroits) en les extrayant dans un seul chunk et en les référençant depuis plusieurs emplacements
- On peut isoler uniquement les parties lentes et les envoyer comme placeholders, tout en remplissant immédiatement le reste pour obtenir un flux de données plus efficace
- Lorsqu’un même objet apparaît plusieurs fois, il est possible de ne l’envoyer qu’une seule fois puis de le réutiliser (Outlining)
- Avec cette approche, les références circulaires (une structure où un objet se référence lui-même) peuvent elles aussi être sérialisées naturellement via une structure de références indirectes entre chunks, sans les difficultés habituelles du JSON standard
Mise en œuvre du streaming progressif dans les React Server Components (RSC)
- Les React Server Components sont en pratique un exemple représentatif d’application du modèle de streaming JSON progressif
- Le serveur utilise une architecture qui charge des données externes (par ex.
Post, Comments) de manière asynchrone
- Côté client, les parties non encore arrivées sont représentées par des Promise, puis l’UI est rendue progressivement selon l’ordre de disponibilité
- React permet de définir des états de chargement intentionnels avec
<Suspense>
- Pour éviter des sauts d’affichage inutiles du point de vue de l’expérience utilisateur, on n’expose pas immédiatement l’état Promise (les « trous ») et on peut orchestrer un chargement par étapes via le fallback de
<Suspense>
- Même si les données arrivent rapidement, le développeur peut contrôler l’exposition progressive de l’UI selon les étapes prévues par le design
Résumé et implications
- L’innovation centrale des React Server Components réside dans le streaming progressif des propriétés (
props) de l’arborescence de composants depuis l’extérieur vers l’intérieur
- Il n’est donc pas nécessaire d’attendre que le serveur ait préparé toutes les données : on peut afficher progressivement les parties importantes en contrôlant finement les états d’attente
- Au-delà du simple streaming, un support structurel est nécessaire, notamment via un modèle de programmation qui l’exploite, comme
<Suspense> dans React
- Cela permet d’atténuer les goulots d’étranglement des approches classiques, notamment lorsqu’une seule portion de données lente retarde tout le reste
1 commentaires
Avis Hacker News
JSON.parse