IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

Facebook teste le mode concurrent, un ensemble de nouvelles fonctionnalités qui aident les apps React
à rester réactives et à s'adapter de façon fluide aux capacités et au débit réseau de l'appareil

Le , par Stéphane le calme

54PARTAGES

11  0 
Facebook teste le mode concurrent, un ensemble de nouvelles fonctionnalités qui aident les applis React
à rester réactives et à s’adapter de façon fluide aux capacités et au débit réseau de l’appareil

En 2013, Facebook a proposé React (aussi appelé React.js ou ReactJS), une bibliothèque JavaScript que le réseau social avait utilisée en interne depuis deux ans déjà et dont l’objectif est de faciliter la conception d’interfaces utilisateur interactives. Sur le dépôt GitHub dédié à React, Facebook indique qu’il vous suffit de concevoir des vues simples pour chaque état dans votre application afin que React mette efficacement à jour les bons composants lorsque vos données vont changer. Et de préciser que les vues déclaratives rendent votre code plus prévisible et plus facile à déboguer.

Au fil des années, React a su gagner en popularité, notamment grâce à sa modularité et sa simplicité d’utilisation.

Actuellement, Facebook teste des fonctionnalités en mode expérimental parmi lesquelles le mode concurrent. Il s'agit d'un ensemble de nouvelles fonctionnalités qui aident les applications React à rester réactives et à s’adapter de façon fluide aux capacités et au débit réseau de l’appareil de l’utilisateur.

Le mode concurrent, qu'est-ce que c'est ?

Pour expliquer le mode concurrent, Facebook s'est servi de la gestion de versions comme métaphore. Si vous travaillez en équipe, vous utilisez probablement un système de gestion de versions tel que Git, et travaillez sur des branches. Quand une branche est finalisée, vous pouvez en fusionner le travail dans master afin que d’autres puissent le récupérer.

Avant que la gestion de versions n’apparaisse, les flux de développement étaient très différents. On n’y trouvait aucun concept de branche. Si vous aviez besoin de modifier certains fichiers, il fallait prévenir tout le monde de ne pas y toucher pendant ce temps-là. Vous ne pouviez même pas commencer à travailler dessus en parallèle les uns des autres : vous étiez littéralement bloqué(e) par l’autre personne.

Ce scénario illustre bien la façon dont les bibliothèques d’interface utilisateur (UI) fonctionnent généralement aujourd’hui. Une fois qu’elles démarrent le rendu d’une mise à jour, y compris la création de nouveaux nœuds DOM et l’exécution du code au sein des composants, elles ne peuvent pas être interrompues. Facebook appelle cette approche le « rendu bloquant ».

Avec le mode concurrent, le rendu n’est pas bloquant : il est interruptible. Cela améliore l’expérience utilisateur et en prime cela ouvre la porte à de nouvelles fonctionnalités qui étaient impossibles jusque-là.


Remplace ReactDOM.render(<App />, rootNode) et active le mode concurrent

Rendu interruptible

Prenez une liste de produits filtrable. Vous est-il déjà arrivé de taper dans le champ de filtrage pour ressentir un affichage saccadé à chaque touche pressée ? Une partie du travail de mise à jour de la liste de produits est peut-être incontournable, telle que la création des nouveaux nœuds DOM ou la mise en page effectuée par le navigateur. En revanche, le moment d’exécution de ce travail et la manière dont il est exécuté jouent un rôle crucial.

Une manière courante de contourner ces saccades consiste à « debouncer » la saisie dans le champ. En lissant ainsi le traitement de la saisie, nous ne mettons à jour la liste qu’après que l’utilisateur a cessé de saisir sa valeur. Cependant, il peut être frustrant de ne constater aucune mise à jour de l’UI lors de la frappe. On pourrait plutôt « ralentir » (throttle, NdT) la gestion de la saisie, et ne mettre à jour la liste qu’à hauteur d’une fréquence maximale définie. Mais sur des appareils de faible puissance, nous constaterions toujours une saccade. Tant le debouncing que le throttling aboutissent à une expérience utilisateur sous-optimale.

La raison de cette saccade est simple : une fois que le rendu commence, il ne peut être interrompu. Ainsi le navigateur ne peut plus mettre à jour le texte dans le champ de saisie juste après que vous avez pressé une touche. Peu importent les scores mirifiques que votre bibliothèque UI (telle que React) obtient dans tel ou tel comparatif, si elle recourt à un rendu bloquant, à partir d’une certaine charge de travail sur vos composants vous obtiendrez toujours un affichage saccadé. Et la plupart du temps, il n’existe pas de correctif simple.


Remplace ReactDOM.render(<App />, rootNode) at active le mode bloquant.

Le mode concurrent corrige cette limitation fondamentale en utilisant un rendu interruptible. Ça signifie que lorsque l’utilisateur presse une touche, React n’a pas besoin d’empêcher le navigateur de mettre à jour le champ de saisie. Il va plutôt laisser le navigateur afficher cette mise à jour, et continuer le rendu de la liste à jour en mémoire. Quand le rendu sera fini, React mettra à jour le DOM, et les modifications seront ainsi reflétées à l’écran.

Conceptuellement, vous pouvez imaginer que React prépare chaque mise à jour « sur une branche ». Tout comme vous êtes libre d’abandonner le travail d’une branche ou de passer d’une branche à l’autre, React en mode concurrent peut interrompre une mise à jour en cours afin de prioriser une tâche plus critique, puis revenir à ce qu’il était en train de faire. Cette technique n’est pas sans rappeler le double buffering des jeux vidéos.

Les techniques du mode concurrent réduisent le besoin de debouncing et de throttling dans l’UI. Le rendu étant interruptible, React n’a plus besoin de différer artificiellement du travail afin d’éviter les saccades. Il peut commencer le rendu immédiatement, et interrompre ce travail si nécessaire afin de préserver la réactivité de l’appli.


Suspense permet à vos composants « d’attendre » que quelque chose ait lieu avant qu’ils procèdent à leur rendu, en affichant dans l’intervalle une interface utilisateur (UI) de repli

Séquences de chargement intentionnelles

Nous disions plus haut que pour comprendre le mode concurrent, on peut imaginer que React travaille « sur une branche ». Les branches ne sont pas seulement utiles pour des correctifs à court terme, mais aussi pour des fonctionnalités plus longues à écrire. Parfois vous pouvez travailler sur une fonctionnalité qui va mettre des semaines avant d’être « assez finie » pour être fusionnée dans master. Ici aussi, la métaphore de la gestion de versions s’applique bien au rendu.

Imaginez que vous naviguiez entre deux écrans d’une appli. Parfois, nous n’aurons peut-être pas assez de code et de données pour afficher un état de chargement « assez fini » à l’utilisateur au sein du nouvel écran. Transiter vers un écran vide (ou doté d’un gros spinner) n’est pas une expérience agréable. Et pourtant, il arrive fréquemment que les chargements du code et des données nécessaires ne prennent en fait que peu de temps. Ne serait-il pas plus agréable que React puisse rester sur l’ancien écran un tout petit peu plus longtemps, pour ensuite « sauter » l’état de « chargement désagréable » lors de la bascule vers le nouvel écran ?

C’est certes possible aujourd’hui, mais au prix d’une orchestration délicate. Avec le mode concurrent, cette fonctionnalité est directement disponible. React commence à préparer le nouvel écran en mémoire d’abord — ou, pour revenir à notre métaphore, « sur une autre branche ». Ainsi, React peut attendre que davantage de contenu ait été chargé avant de mettre à jour le DOM. Avec le mode concurrent, nous pouvons dire à React de continuer à afficher l’ancien écran, pleinement interactif, avec peut-être un indicateur de chargement dans un coin. Et lorsque le nouvel écran est prêt, React peut nous y amener.

Concurrence

Résumons les deux exemples ci-avant pour voir comment le mode concurrent en unifie le traitement. Avec le mode concurrent, React peut travailler à plusieurs mises à jour de l’état en exécution concurrente, tout comme les branches permettent à divers membres d’une équipe de travailler indépendamment les uns des autres :
  • Pour les mises à jour dépendantes du processeur (CPU, telles que la création des nœuds DOM et l’exécution du code des composants), la concurrence permet à une mise à jour plus urgente « d’interrompre » le rendu qui a déjà démarré.
  • Pour les mises à jour dépendantes des entrées/sorties (I/O, telles que le chargement de code ou de données à partir du réseau), la concurrence permet à React de commencer le rendu en mémoire avant même que les données n’arrivent, et de sauter des états de chargement désagréables.

Ce qui est critique, c’est que la façon dont vous utilisez React reste inchangée. Les concepts tels que les composants, les props et...
La fin de cet article est réservée aux abonnés. Soutenez le Club Developpez.com en prenant un abonnement pour que nous puissions continuer à vous proposer des publications.

Une erreur dans cette actualité ? Signalez-nous-la !