React Advanced London (depuis nos canapés)

Nous avons eu la chance de pouvoir assister à la conférence React Advanced London en remote, voici ce que nous en avons retenu de ces deux jours intenses !

Section intitulée react-internalsReact internals

C’était le slogan de la conférence cette année : « We will be diving deep » et nous n’avons pas été déçues. Plusieurs conférenciers nous ont parlé de ce qui se passe réellement sous le capot quand on utilise React.

Section intitulée quot-understanding-react-s-fiber-architecture-quot-tejas-kumar« Understanding React’s Fiber Architecture » – Tejas Kumar

Tejas Kumar nous a expliqué en plongeant dans le code le fonctionnement de React Fiber, le nouvel algorithme de réconciliation, introduit dans React 16 pour rendre notre librairie préférée plus rapide et performante. Résumé grossièrement, les Fiber sont une sorte de structure de données, que React conserve pour garder une trace de ce qui se passe dans nos applications. Elles ont donc une durée de vie longue par opposition aux Element qui eux sont éphémères. Fiber Reconcilier, l’algorithme de réconciliation, maintient en permanence deux arbres, le courant et le « work in progress », boucle sur tous nos composants en partant du haut pour détecter ce qui a changé, ajoute des flags sur ce qui doit être mis à jour, ce qui changé, etc. puis bascule sur le deuxième arbre qui devient alors la nouvelle source de vérité. Il réconcilie ensuite cet arbre avec l’environnement hôte (navigateur, application mobile) pour mettre à jour l’UI. Cette nouvelle architecture permet ainsi un rendu incrémentiel de nos applications.

Les deux arbres créés par React Fiber

Ainsi décortiqué, le fonctionnement interne de React ne semble plus si complexe. Une plongée passionnante à voir dès qu’elle sera disponible. En attendant nous vous recommandons sa conférence Deconstructing React si vous n’avez pas encore eu l’occasion de la voir).

Section intitulée deep-diving-on-concurrent-react-matheus-albuquerqueDeep diving on concurrent React – Matheus Albuquerque

Durant l’exécution de certaines tâches trop longues, le thread principal de JavaScript se retrouve bloqué. Ces blocages sont gênants, d’autant plus pour les utilisateurs sur mobile pour qui ils peuvent durer 7 à 12 fois plus longtemps. Il s’agit d’un problème réel, qui en plus d’être désagréable pour vos utilisateurs a également un fort impact sur le taux de conversion de vos applications. Pour éviter de bloquer le thread principal, il existe trois stratégies principales : le parallélisme, l’exécution concurrente et le scheduling (planification).

Trois stratégies pour ne pas bloquer le thread principal

React 18 introduit des nouveautés intéressantes sur le sujet. Nous pourrons par exemple traiter plus efficacement les gros volumes de données en priorisant les render (grâce à l’API startTransition), limiter les renders inutiles avec le hook useSyncExternalStore, prioriser le chargement des zones d’interaction pour diminuer le first input delay (hydration sélective) ou encore monitorer les performances des applications grâce au profiler qui sera capable d’indiquer quelles opérations trop gourmandes pourraient bénéficier de startTransition.

Matheus a conclu avec quelques mises en garde, le scheduling n’implique pas forcément de meilleures performances et il n’y a pas de solution miracle. Il faut identifier les métriques qui sont fondamentales pour nos applications et partir de là. Enfin il a brièvement évoqué le futur de React : un composant built-in <Cache> pour la récupération de données, à utiliser avec <Suspense>.

Section intitulée compositionComposition

Section intitulée code-crimes-for-good-component-api-siddharth-kshetrapalCode Crimes For Good Component API – Siddharth Kshetrapal

Quelles sont les qualités d’une bonne interface utilisateur ? Elle doit être intuitive, accessible et cohérente. Il en va de même pour l’API de nos composants. Siddharth Kshetrapal nous a expliqué à travers plusieurs exemples comment il fait en sorte, quitte à utiliser quelques hacks, que ses APIs de composants respectent ce contrat.

La leçon que nous en retenons est le fil rouge de la conférence : Hacks that make the code easier to read and author... are okay

Ce qui donne en français : les hacks qui rendent le code plus facile à lire et à modifier, et qui aident les développeurs à faire du bon travail rapidement, en respectant des contraintes raisonnables du système, sont ok.

Section intitulée react-slots-a-new-way-of-composition-neo-nieReact Slots: a New Way of Composition – Neo Nie

Qui ne s’est pas retrouvé un jour à devoir maintenir un composant TextInput avec plus d’une quinzaine de props, ou un composant Message qui gère une dizaine de cas d’usages différents ? Neo Nie a fait un état des lieux des problèmes inhérents à la composition avec React que nous avons tous rencontrés au moins une fois dans notre carrière.

Exemple de composants avec trop de props

Ces différents problèmes l’ont amené à s’intéresser aux différents patterns de composition qui existent, et notamment à l’utilisation dans React du pattern Slots.

Définition en anglais du pattern Slots

Ce pattern permet de définir des sortes de placeholder, identifiés par un attribut unique, dans un template et qui peuvent être utilisés ensuite pour définir n’importe quel contenu. Vous avez probablement déjà utilisé ce pattern sans même le savoir, à chaque fois que vous utilisez des props nommées pour rendre des parties d’un composant.

const TextInput = ({ name, error, label }) => (
<div className="form-group">
	<span className="form-label">{label}</>
<input type="text" name={name} />
{error && <span className="form-error">{error}</span>}
</div>

Ici, error et label sont des slots. Pour mettre en place les slots dans ses projets, Neo a créé la librairie create-slots qui s’utilise en définissant des slots et des hosts (un composant qui a un layout formé de plusieurs slots).

Utilisation de react-slots dans le code

La librairie est encore relativement jeune mais le concept semble prometteur. À suivre !

Section intitulée accessibiliteAccessibilité

Section intitulée creating-an-accessible-web-together-in-5-simple-steps-shruti-kapoorCreating an Accessible Web Together in 5 Simple Steps – Shruti Kapoor

Shruti Kapoor nous a présenté ses astuces pour un Web plus accessible. Après avoir rappelé l’importance de l’accessibilité, elle nous offre un moyen mnémotechnique avec l’acronyme STARK pour se souvenir de 5 choses à toujours garder en mémoire :

S pour Semantic HTML : utiliser les balises qui correspondent à ce que vous en faites (button pour des actions, a pour des liens, mais aussi nav, header, main…) et bien les utiliser (une balise a a toujours un href, img a un alt, ne pas créer de « faux » titres en CSS). Les lecteurs d’écrans risqueraient autrement de donner la mauvaise information à leurs utilisateurs. Utiliser les balises natives à bon escient vous offre donc une accessibilité à bas coût.

T pour tabindex : Il est important de définir un tab order logique. Par ailleurs Shruti rappelle que le tabindex ne doit pas être supérieur à 0, pour ne pas perdre les lecteurs d’écran. Il est possible de débugger son tab order avec Firefox par exemple.

A pour Aria tags : label, aria-described-by, checked, expanded, haserrormessage, aria-hidden… Nous ne les présentons plus et pourtant nous ne pensons pas toujours à les utiliser. Chez JoliCode, nous aimons aussi les utiliser dans notre CSS, ce qui permet de ne pas les oublier et de faire d’une pierre deux coups !

R pour Role : attribut à utiliser dès lors que nous ne pouvons pas utiliser les balises natives qui correspondent à notre besoin

Enfin K pour Keyboard navigation & screen readers : il faut toujours s’assurer par exemple que le focus est visible à l’écran. Shruti recommande de tester soi-même en utilisant seulement tab, la barre d’espace, Enter et Echap.

Checklist d'accessibilité

Elle nous recommande ensuite quelques outils pour faire nos tests, les extensions navigateurs aXe et Wave, les outils intégrés à Firefox ou à Chrome, les outils au build comme axe-core ou jsx-a11y, ou encore l’outil de CI accesslint pour identifier les soucis d’accessibilité directement dans les PRs GitHub.

N’hésitez pas également à tester la navigation clavier, les lecteurs d’écran, et les tests automatisés. Enfin rien ne vaut un test avec des utilisateurs réels.

Nous pouvons même aller plus loin en proposant des raccourcis clavier pratiques pour l’édition, ou encore des focus trap dans certaines zones de l’application.

Section intitulée tips-et-bonnes-pratiquesTips et bonnes pratiques

Section intitulée the-weird-things-about-react-nik-grafThe Weird Things About React – Nik Graf

Cette conférence est l’occasion de souligner certaines bizarreries de React, connues ou moins connues, à commencer par les versions de React, passées brutalement de 0.14.7 à 15.0.0 (pour l’explication c’est par ici), mais aussi de nous donner quelques protips pour utiliser React. Saviez-vous par exemple qu’il est possible d’utiliser la prop key pour forcer un composant à être remonté ? On y apprend aussi qu’on peut utiliser la fonction flushSync pour re-rendre de manière synchrone lorsque nous recevons une mise à jour de données (pas encore documenté mais discuté par exemple ici), que React 18 autorise nos composants à renvoyer undefined ou encore que les hooks peuvent être utilisés conditionnellement, à condition d’ignorer le warning de React (mais c’est mal, ne faites pas ça chez vous). Il est également possible de tricher pour utiliser un export nommé avec React.lazy().

Utilisation de React lazy avec un export nommé

Le type React.FunctionComponent (et son alias React.FC) souvent décrié par les développeurs TypeScript pour sa prop children implicite, perd cette prop en React 18, ce qui veut dire que nous pouvons maintenant l’utiliser avec une prop children obligatoire.

En conclusion de sa conférence, Nik nous a présenté react-reduce-stress, une petite librairie qu’il a développé et qui permet de masquer certains warnings et erreurs de React comme le fameux warning sur l’ordre des hooks ou encore celui du mode strict de React 18 qui nous informe que les useEffect seront exécutés 2 fois au premier rendu d’un composant. Nous ne pouvons que vous conseiller au passage de tester le mode strict de React 18 pour détecter les composants qui ne sont pas à jour et les effets de bord.

Section intitulée using-useeffect-effectively-david-khourshidUsing useEffect Effectively – David Khourshid

Dans cette très bonne conférence, David Khourshid nous réapprend à utiliser useEffect, ou plutôt ce que nous devrions utiliser à la place et dans quelles situations :

  • Nous n’avons pas besoin de useEffect pour transformer de la donnée. Il vaut mieux utiliser un useMemo ou mieux, n’utiliser aucun hook et passer à useMemo seulement en cas de problème de performance avéré ;
  • Pas de useEffect non plus pour communiquer avec le parent. Dans ce cas mieux vaut exécuter notre effet directement dans la gestion de l’évènement ;
  • Pas de useEffect pour souscrire à un store externe. L’injustement méconnu useSyncExternalStore est là pour ça ;
  • Pas besoin de useEffect pour fetcher de la donnée. La librairie react-query dispose de hooks terriblement efficaces pour ça, avec Next.js on peut également utiliser useSWR() ou simplement use() avec du cache ;
  • Initialiser un singleton global (configurer un client Axios, s’authentifier sur un store externe, etc) sera plus efficace sans useEffect, en-dehors du composant ;
  • Enfin, n’utilisez pas useEffect pour gérer les actions de l’utilisateur. Il vaut bien mieux exécuter les effets dans les event handler directement. Nous pouvons par exemple utiliser une state machine :

Exemple de state machine

De manière générale, useEffect doit être utilisé pour les effets « d’activité », pour la synchronisation. Pour les effets « d’action » il est plus adapté (et souvent plus simple) de les mettre au plus près des événements qui les causent, ce qui implique souvent de ne pas utiliser useEffect.

Section intitulée treat-your-users-right-with-segmented-rendering-eric-burelTreat Your Users Right with Segmented Rendering – Eric Burel

Toutes nos applications rencontrent un jour des problématiques de personnalisation ou segmentation, que ce soit pour les adapter à différentes langues, à différents types d’utilisateurs (payants ou non), pour mettre en place de l’A/B testing, etc. C’est pourquoi il est nécessaire de pouvoir rendre du contenu adapté à l’utilisateur actuel. La plupart de nos frameworks JavaScript actuels proposent différents modes de rendu plus ou moins statiques pour améliorer les performances. Comment en tirer profit tout en évitant d’avoir des invités riches et des clients pauvres (bonnes performances seulement pour les utilisateurs non payants qui ne nécessitent pas de personnalisation) ? Eric Burel nous propose une solution simple et facile à mettre en place. Dans l’exemple de Next.js, le contenu peut être rendu côté serveur, côté client ou dans un mode intermédiaire « static site generation ». Les deux premiers modes sont dynamiques mais lents, alors que le dernier est très performant, mais comme son nom l’indique il est statique.

Une solution possible est d’utiliser des URLs avec des paramètres différents pour chaque segment mais cela pose de nombreux autres problèmes, le paramètre est visible par les utilisateurs, les URLs peuvent être changées à la main et elles peuvent vite devenir très longues.

Problèmes posés par la personnalisation dans les URLs

La deuxième solution est d’utiliser un serveur proxy qui lit un cookie (ou un header par exemple) et réécrit l’url. La réécriture n’étant pas une redirection, l’utilisateur ne peut ni voir ni modifier l’URL. Avec Next.js, le serveur proxy est un simple middleware.

Exemple de serveur proxy avec Next.js

Une bonne astuce à garder en mémoire pour tous vos problèmes de personnalisation.

Section intitulée performancesPerformances

Section intitulée automated-performance-regression-testing-with-reassure-michal-pierzchalaAutomated Performance Regression Testing with Reassure – Michał Pierzchała

Michał part d’un constat auquel nous avons tous dû faire face un jour : les performances de nos applications tendent naturellement à se dégrader avec le temps et les développements successifs. Il est donc important de mettre en place des tests de non-régression des performances, au moins sur les parties qui risquent le plus d’impacter nos utilisateurs.

En analysant la fréquence de chacune des principales causes des problèmes de performance, il lui est apparu assez clairement que la plupart des problèmes sont liés à JavaScript plutôt qu’à React ou à React Native.

Causes principales des problèmes de performance avec React

Ne trouvant pas de librairie de test adaptée à son besoin assez spécifique, Michał a choisi de créer sa propre librairie : reassur. Celle-ci a donc été conçue pour s’intégrer avec les librairies de tests existantes afin de tester les performances des render, en mesurant leur durée et leur nombre. Elle permet aussi de générer des rapports, et s’intègre avec les CI les plus connues. Les tests de performance sont lancés sur la branche courante et sur la branche principale et les résultats sont comparés en utilisant l’analyse statistique.

Écrire les tests est relativement simple, il suffit de copier un test fonctionnel et d’y ajouter quelques lignes de code.

Exemple d'un test avec reassure

Résultat du test avec reassure

La présentation de la librairie était très convaincante, nous avons hâte de la tester chez nous !

Section intitulée typescriptTypeScript

Section intitulée typescript-and-react-secrets-of-a-happy-marriage-matt-pocockTypeScript and React: Secrets of a Happy Marriage – Matt Pocock

Cette conférence nous a particulièrement intéressées. Matt Pocock expose certains des problèmes que tout utilisateur de TypeScript rencontre un jour et nous en donne une solution élégante. En voici quelques uns :

  • Le typing dynamique, qui consiste à avoir une variable pouvant être soit un type A soit un type B, peut poser des problèmes lorsque l’on cherche à accéder à une propriété spécifique à un des deux types :

Exemple de composant utilisant du typing dynamique

La solution est d’utiliser l’opérateur in, par exemple if (‘href’ in props) , TypeScript saura grâce à ce test que nos props sont d’un certain type.

  • Deux props qui dépendent toutes les deux du même type, que nous ne pouvons pas connaître à l’avance, par exemple row: unknow[] et renderRow: (row: unknow) => React.ReactNode. La solution ici est d’utiliser les types génériques. En plus, lorsque nous ne spécifions pas le type TRow, celui-ci sera inféré automatiquement par TypeScript.

Exemple de types génériques

Nous pouvons aussi utiliser extends pour forcer certaines propriétés :

Exemple de type générique utilisant extends

  • Les types de React sont écrits et maintenus en dehors de la lib, dans @types/react et ils peuvent parfois présenter de légères différences qui peuvent être ennuyantes. Par ailleurs certaines fonctions comme les hooks useState et useRef ont différents overloads, c’est-à-dire qu’ils ont plusieurs signatures et les types inférés par TypeScript dépendent de l’overload utilisé :

Exemple d'utilisation de useRef pour un élément HTML

Différentes utilisations possibles de useRef

Par ailleurs certains de ces comportements peuvent paraître incohérents, par exemple, ne pas fournir de valeur initiale pour useRef va inférer un type number | undefined. Pour ne pas être perdu face à ces différences, la meilleure solution reste de bien comprendre le fonctionnement de ces fonctions, n’hésitez donc pas à aller jeter un oeil aux types !

Section intitulée l-experience-du-remoteL’expérience du remote

Regarder des conférences depuis le confort de son canapé est certes appréciable, mais plusieurs aspects des conférences live nous ont toutefois un peu manqué. Assister à des conférences c’est aussi l’occasion de discuter avec d’autres développeurs de tous horizons, et même si les organisateurs avaient fait de leur mieux pour nous proposer différentes plateformes et réseaux, il reste plus difficile d’aller vers les autres en remote qu’en live.

Concernant les conférences elles-mêmes, celles-ci étaient retransmises en décalé par rapport à la programmation live, du début d’après-midi jusqu’à assez tard dans la soirée, un point vraiment négatif pour les spectateurs qui ont des contraintes familiales par exemple. Il aurait probablement été plus judicieux de faire plusieurs streams en horaires décalés pour permettre à la majorité des timezones de suivre toutes les conférences. Heureusement, l’ensemble des conférences ainsi que les workshops gratuits devraient être rendus disponibles en vidéo.

Une timeline en temps réel très pratique était mise à disposition sur le site de React Advanced, avec les streams des deux tracks de conférence. C’était également appréciable de pouvoir mettre une conférence en pause ou revenir un peu en arrière pour mieux comprendre un point spécifique. En revanche nous avons toutes deux trouvé qu’il était assez difficile de se concentrer, à cause des distractions inévitables de l’ordinateur mais aussi du « bruit » présent dans les streams eux-mêmes. Les vidéos contenaient beaucoup d’informations sur les conférences à venir, les tweets en rapport avec l’évènement, etc. qui venaient un peu polluer l’expérience.

Dernier point regrettable, pas de vélotypie sur les streams, ce qui aurait pourtant été un gros plus en termes d’accessibilité, ainsi que pour ceux dont l’anglais n’est pas la langue maternelle.

Section intitulée conclusionConclusion

Une grosse partie des conférences était dédiée à React Native mais, étant toutes deux plutôt tournées développement Web, nous avons préféré assister aux conférences qui nous concernaient le plus.

Des ateliers gratuits en remote sur des demi-journées étaient proposés aux participants sur des thèmes comme TypeScript ou React-Query.

Dans l’ensemble ces deux jours de conférence ont été riches en enseignements, on espère pouvoir y assister à nouveau l’année prochaine et pourquoi pas vous y croiser !


Cet article porte sur la conférence React Advanced London 2022.

React Advanced London 2022

Commentaires et discussions

Nos formations sur ce sujet

Notre expertise est aussi disponible sous forme de formations professionnelles !

Voir toutes nos formations

Ces clients ont profité de notre expertise