Au cours des deux dernières années, j’ai entendu le terme Applications Web isomorphes mentionné de manière positive de plus en plus fréquemment. De plus, pendant ce temps, j’ai moi-même réfléchi à la technique. Ma conclusion est que les applications Web isomorphes sont quelque chose qui n’ajouterait pas de valeur pour moi ou les organisations typiques pour lesquelles je travaille. Plusieurs choses m’ont conduit à cette conclusion.
Mais, avant d’énumérer les raisons, permettez-moi d’abord de souligner que je pense que les bibliothèques javascript isomorphes (c’est-à-dire lodash.js) sont géniaux. En outre, je pense que des composants isomorphes isolés peuvent être précieux, par exemple un indicateur boursier mis à jour en direct.
Les raisons pour lesquelles je ne crois pas que les applications Web isomorphes soient précieuses pour moi ou pour les organisations pour lesquelles je travaille sont:
- Le serveur web ne peut désormais être écrit qu’en javascript
- Les applications Web isomorphes ne peuvent jamais être une amélioration progressive pour les applications non triviales
- Flux de données bloquant vs non bloquant
- Time-to-interaction and the Uncanny Valley
- Les appareils mobiles se figent pendant l’analyse de javascript
- Vos meilleurs développeurs sont maintenant occupés à ne pas produire de valeur
Je veux commencer par une définition des applications Web isomorphes. Une application Web isomorphe est une application Web dans laquelle le code de l’application ne sait pas où il est exécuté. Au lieu de cela, ces connaissances sont conservées dans le code d’infrastructure et permettent à l’application dans son ensemble de s’exécuter à la fois côté client et côté serveur.
- Le serveur web ne peut désormais être écrit qu’en javascript
- Les applications Web isomorphes ne peuvent jamais être une amélioration progressive pour les applications non triviales
- Flux de données bloquant vs non bloquant
- Time-to-interaction and the Uncanny Valley
- Les appareils mobiles se figent lors de l’analyse de javascript
- Vos meilleurs développeurs sont maintenant occupés à ne pas produire de valeur
- Résumé
- Remerciements
Le serveur web ne peut désormais être écrit qu’en javascript
Si le code client et le code serveur sont identiques (et que le client ne peut aujourd’hui interpréter que javascript), alors nous sommes limités à n’utiliser que javascript sur le serveur. J’aime node.js beaucoup, mais je pense qu’il vaut mieux être ouvert à des alternatives à l’avenir, de mon point de vue.
Les applications Web isomorphes ne peuvent jamais être une amélioration progressive pour les applications non triviales
Javascript côté client a accès à une machine d’état en mémoire qui permet un niveau d’interaction à grain fin, avec une latence très faible (sous-millisecondes). La même chose n’est pas vraie pour la machine d’état HTTP, qui est pilotée par les clics sur les liens et les soumissions de formulaires.
Pour moi, l’amélioration progressive consiste à commencer par une ligne de base accessible à tous les appareils / navigateurs possibles, de l’ancien au courant en passant par le futur. En pratique, cela signifie une base de rendu côté serveur. L’étape d’amélioration est une décision commerciale sur l’endroit où améliorer le site / l’application pour augmenter la valeur. En d’autres termes, l’amélioration se fait dans le code de l’application (spécifique) et *non* dans le code de l’infrastructure (général), à l’exception des techniques d’optimisation comme pjax ou turbolinks.
Le moyen pour les applications Web isomorphes d’obtenir une amélioration progressive consiste à prendre cette machine à états en mémoire à grain fin et à la « traduire » pour n’utiliser que des liens et des formulaires. Les seuls cas où je peux voir où cela est possible sont ceux où vous n’aviez pas besoin d’un rendu complet côté client en premier lieu, mais pouviez plutôt compter sur les techniques d’optimisation mentionnées ci-dessus et les composants côté client pour améliorer l’expérience (c’est-à-dire un composant de calendrier pour un champ de saisie pour une date).
Une variante de cette solution consiste à ne pas prendre en charge tous les états/ transitions côté client dans la machine d’états côté serveur. Dans ce cas, il devrait s’agir d’une décision commerciale qui doit être reflétée dans le code de l’application, ce qui rend l’environnement du code de l’application sensible, ce qui va à l’encontre de l’idée d’applications Web isomorphes.
Le moyen pour les applications Web isomorphes d’obtenir une amélioration progressive consiste à prendre cette machine d’état en mémoire à grain fin et à la « traduire » pour n’utiliser que des liens et des formulaires.
Flux de données bloquant vs non bloquant
La séquence de rendu pour le web côté serveur et le web côté client est différente : le côté serveur bloque et le côté client ne bloque pas.
Imaginez que nous devons faire deux requêtes à certains services afin de rendre une vue. Nous pouvons faire ces demandes en parallèle.
Côté serveur, si la deuxième requête retourne en premier, elle peut rendre cette partie de la réponse mais doit bloquer l’envoi de ces octets jusqu’à ce que la première ait rendu et renvoyé cette partie de la réponse au navigateur.
Côté client, cette contrainte n’existe pas : les deux réponses peuvent être traitées et rendues indépendamment.
De plus, je pense que ce qui précède représente le plus simple des exemples. Imaginez que vous ayez un arbre de composants, où le composant racine est intelligent (voir Composants de présentation et de conteneur pour une explication des composants intelligents / muets), suivi de quelques niveaux de composants muets, puis d’au moins un composant feuille intelligent.
L’infrastructure a alors besoin d’un moyen de s’assurer que le contexte de la feuille intelligente ne se perd pas, de sorte que nous perdons le contrôle de l’exécution bloquante / non bloquante, en fonction du mode serveur / client. Une façon de résoudre ce problème pourrait être de faire en sorte que l’ensemble du programme soit exécuté dans une monade libre, représentant l’exécution sous forme de données à interpréter ultérieurement. Une autre solution pourrait être d’utiliser une forme de modèle de visiteur et de laisser les composants déclarer les données dont ils ont besoin (similaire au tutoriel: Fabriquer à la main une application Redux Isomorphe (avec Amour)). Ce dernier est probablement le plus facile. Mon point est que le problème des différents modes de blocage est probablement beaucoup plus compliqué que l’on imagine au départ.
Une autre conception consiste à avoir une règle qui dit « seul le composant racine peut être un composant intelligent », similaire à la façon dont vous pourriez utiliser la monade IO dans Haskell, en gardant les feuilles pures et n’ayant que des effets secondaires au niveau supérieur. Je pense que cette conception est bonne côté serveur mais pas côté client: un composant côté client devrait pouvoir charger ses propres données dans au moins certains scénarios, par exemple en ce qui concerne les composants liés aux médias sociaux. Avoir une règle qui ne permet jamais ces scénarios semble très improductif.
Time-to-interaction and the Uncanny Valley
Avec l’approche des applications Web isomorphes, il y aura un laps de temps pendant lequel l’utilisateur verra des éléments graphiques à l’écran qui semblent être interactifs mais ne le sont pas. En d’autres termes, le temps entre le moment où le navigateur a rendu la réponse du serveur et le moment où le javascript est téléchargé, analysé et exécuté. C’est ce qu’on appelle la « Vallée étrange » ou le « Village Potemkine ».
Voir ce tweet et les réponses pour plus de détails.
Les appareils mobiles se figent lors de l’analyse de javascript
Sur un téléphone mobile « typique », vous obtenez un décrochage de thread d’interface utilisateur de 1 ms par javascript de 1 Ko, selon ce tweet. Malte Ubl est le responsable technique du projet AMP, donc je soupçonne qu’il sait de quoi il parle.
Vos meilleurs développeurs sont maintenant occupés à ne pas produire de valeur
Les applications Web isomorphiques sont une approche qui exige un haut niveau de compétences en développement. Dans de nombreux domaines (du moins dans le monde occidental), il est difficile de trouver et de recruter des développeurs hautement qualifiés. Choisir de développer des applications Web isomorphes permet à ces développeurs de faire quelque chose que je remets en question produit une valeur commerciale quelconque. Il existe de meilleures façons d’utiliser leur temps.
Résumé
Les applications Web isomorphes limitent votre choix de langage / plate-forme de serveur Web pour qu’il ne s’agisse que de javascript. Il a l’ambition de permettre une amélioration progressive, mais il ne peut pas y parvenir. Il introduit un haut niveau de complexité technique en raison des différences de flux de données bloquant / non bloquant. Il introduit une fenêtre temporelle où les choses semblent être interactives, mais ne le sont pas (the Uncanny Valley). Une grande quantité de javascript gèle également les navigateurs mobiles, avec la règle empirique selon laquelle 1 Ko de javascript signifie 1 ms de thread d’interface utilisateur bloqué. Et, comme cela nécessite une conception logicielle compliquée, cela demande un temps et des efforts précieux à vos meilleurs développeurs – il existe de meilleures façons d’utiliser leur temps.
Enfin, je tiens à souligner que vos expériences pourraient être différentes des miennes. Il existe peut-être des scénarios où les applications Web isomorphes sont bonnes. Mais ils ne sont pas une solution miracle pour combler tous les écarts entre les avantages Web côté serveur et les avantages Web côté client, tout en n’obtenant aucun des inconvénients des deux approches.
Qu’en pensez-vous ? Avez-vous envisagé de « devenir isomorphe »? Avez-vous des réflexions sur les défis et les coûts? Comment les traitez-vous?
Remerciements
Merci à Oskar Wickström et Per Ökvist pour de précieuses discussions autour de ce sujet. Oskar a également passé en revue cet article – merci Oskar.