mardi 22 janvier 2013

De JSF à AngularJS


Ce matin j’ai partagé sur Twitter cet article en anglais qui fait une comparaison entre AngularJS et JSF. D’autres que moi l’ont partagé aussi, mais il y a eu quelques réactions étonnées, du genre : “c’est une blague ?”.

Pour moi la comparaison n’a rien d’absurde, et mérite de plus amples explications que ce qu’on peut écrire dans un tweet de 140 caractères.

Tout comme l’auteur de l’article, je viens du monde Java et j’ai travaillé avec JSF pendant 5 ans, certes surtout comme architecte et en support à mes collègues qui l’utilisaient au quotidien, mais j’ai aussi fait ma part de développements. Et moi aussi en découvrant AngularJS, j’ai forcément constaté des ressemblances entre les deux frameworks.


Des templates déclaratifs avec data-binding...

Tout d’abord, quand je parle de JSF, ce n’était pas le JSF des origines avec des templates en JSP et des tonnes de fichiers de configuration en XML, une horreur que je n’aurais jamais accepté d’utiliser. Il s’agissait d’une combinaison de JSF, de Facelets pour les templates (qui est la technologie de templates utilisée dans JSF 2.0), et du framework Seam (devenu Weld) pour l’injection de dépendances des services, et leur publication dans les différents contextes afin qu’ils soient directement utilisables pour le data-binding des composants JSF. N’allez pas raconter que j’ai dit qu’AngularJS ressemblait aux immondes pages JSP, je démentirai formellement !

Avec cette combinaison JSF + Facelets + Seam (ou Spring si vous voulez), on a des templates déclaratifs basés sur HTML avec du data-binding et un langage d'expression, qui ressemblent beaucoup à ceux d’AngularJS comme l'a très bien montré l'auteur de l'article cité. Je suis un grand partisan des templates déclaratifs. Je trouve l’approche déclarative beaucoup plus efficace que l’approche procédurale pour la création d’une interface utilisateur. Avant JSF, j’ai fait plusieurs années de Swing, et j’avais pu constater à quel point c’était lourd ; puissant certes, mais avec une lourdeur toujours présente pour une puissance rarement nécessaire. Quand on doit écrire un éditeur “rich text”, on apprécie la puissance de Swing, mais pour des usages plus classiques on passe son temps à maudire sa lourdeur. JavaFX était une très bonne idée, celle de rajouter des templates déclaratifs à la puissance de Swing, dommage qu’elle soit arrivée trop tard.

Mais revenons-en à nos templates JSF/Facelets. Aussi similaires soient-ils, il y a quand même des différences avec ceux d’AngularJS. Déjà, les composants JSF sont forcéments des éléments du pseudo XHTML, alors que les directives d’AngularJS peuvent être aussi des attributs. Du coup avec AngularJS, on peut avoir plusieurs directives sur un même élément : une directive est généralement un comportement applicable à un élément plutôt que l’élément lui-même. Avec Facelets, il faut imbriquer plusieurs composants JSF pour combiner leurs comportements.

... mais traités côté serveur

Une différence bien plus fondamentale, c’est que le template AngularJS est du HTML qui est analysé par le navigateur web avant qu’AngularJS n’intervienne dessus, tandis qu’avec JSF, c’est le moteur de Facelets qui convertit côté serveur le template en HTML pur. Avantage pour JSF, comme le traitement est fait côté serveur, on a un accès direct aux objets Java du serveur, notamment aux entités persistantes. Il n’y a pas besoin d’une couche intermédiaire de web services pour échanger les données avec le client, c’est nettement plus simple, surtout lorsqu’il y a une gestion assez pointue des droits sur les données de ces objets. Par contre AngularJS est plus proche du HTML, travaille en manipulant le DOM dans le navigateur web plutôt qu’en générant du HTML souvent trop verbeux comme le font les composants JSF. On aura d’une façon générale avec AngularJS des pages HTML plus propres et moins lourdes.

L’autre gros problème de JSF, c’est le stockage de l’état des composants, qui peut se faire côté serveur ou côté client. Encore qu’il est difficile d’envisager sérieusement le stockage de l’état côté serveur : comme JSF ne sait pas vraiment ce qu’il se passe dans le navigateur, il faut conserver l’état de plein de pages pour espérer qu’un utilisateur ayant ouvert plusieurs onglets ne soumette pas un formulaire d’une page dont l’état a été perdu ; inutile de préciser que dans ce mode la consommation de mémoire par utilisateur connecté est tout simplement colossale. Le mode qui fonctionne mieux, c’est celui consistant à stocker l’état des composants JSF sérialisé dans un champ caché de la page web. Plus de problème de consommation de mémoire côté serveur, ni de pages dont l’état a été perdu puisqu’il est conservé dans la page elle-même, mais ça implique de gros échanges pour passer dans un sens et dans l’autre cet état sérialisé, pour la moindre requête Ajax. Alors on en vient à faire un peu de jQuery pour éviter ces lourds échanges serveurs dès qu’on veut mettre un peu d’interaction dans une page web. Le résultat, c'est qu'on mélange du code client dans le template serveur, et ce qui était plutôt élégant devient horrible à maintenir.

Du web “terminal passif” au web “client-serveur”

C’est là qu’on touche aux limites du fait de gérer côté serveur une interface client. JSF, du moins une combinaison JSF + Facelets + Seam, est très efficace pour créer des applications web classiques, pour ne pas dire à l’ancienne, avec des pages web distinctes et peu d’Ajax. C’est le web façon terminal passif. Pour ce genre d’applications, gérer l’interface utilisateur côté client, même avec un framework aussi pratique qu’AngularJS, suppose de créer toute une API en web services REST échangeant du JSON, ce dont on est dispensé avec JSF.

Mais dès qu’on veut faire une application web plus réactive, éventuellement mono-page, c’est-à-dire quand on veut passer du web terminal passif au web client-serveur, alors JSF n’est plus du tout pertinent, et AngularJS s’avère un bien meilleur choix. JavaScript est de nos jours largement assez puissant pour gérer dans le navigateur web toute la couche de présentation d’une application, et c’est une approche beaucoup plus logique et plus cohérence, pour avoir de l’interaction sans échange avec le serveur, pour gérer correctement l’historique du navigateur dans une application mono-page.. En bref, on peut maintenant abandonner les solutions trop complexes et d’un autre âge, qui découlaient de la nécessité de gérer la présentation dans une technologie complètement déconnectée du langage natif du navigateur web, et même souvent exécutée côté serveur. Pour moi les JSF, GWT ou autre Vaadin apparaissent aujourd'hui comme des impasses de l’évolution du développement web, des espèces condamnées à l’extinction à plus ou moins court terme.

Et si un client JavaScript suppose une API en web services pour l’échange des données, c’est de toute façon une architecture qui se généralise car elle permet aussi de communiquer avec des applications mobiles, ou des services externes. Donc oui, on peut encore trouver des cas où une application web pourra être développée plus rapidement avec JSF qu’avec AngularJS, si ce n’est pas une application mono-page, qu’elle comporte peu d’interactions côté client, qu’il n’y aura pas de version mobile, etc. Ça n’empêche pas que malgré leurs similitudes, l’approche de JSF est du passé, et c’est celle d’AngularJS qui prévaudra pour ces prochaines années. Les ressemblances permettront une transition plus facile pour les anciens de JSF, et c'est une bonne chose.

18 commentaires:

  1. "On voit bien maintenant que les JSF, GWT ou autre Vaadin sont des impasses de l’évolution du développement web, des espèces condamnées à l’extinction à plus ou moins court terme."

    Avant de dire des anneries pareilles, on se renseigne! (je parle de GWT ici)

    Et si on me demande mon avis, JSF aurait dû mourrir (dans d'atroces souffrances) depuis longtemps, mais ça n'engage que moi.

    RépondreSupprimer
    Réponses
    1. Ah, je vois ici ou sur Twitter que ma prise de position plutôt tranchée a agacé des partisans de GWT.

      Peut-être que l'avenir me donnera tort, on pourra juger mes pronostics dans quelques années. Qui aurait parié il y a 5 ou 10 ans sur le succès croissant que connaît JavaScript aujourd'hui ?

      Pour moi, par rapport à JSF, GWT a apporté des solutions à une époque où l'on n'était pas outillé pour développer un client lourd directement en JS, mais aussi des difficultés, surtout celle de ne pas avoir accès aux objets du serveur (d'où les histoires de DTO, Gilead et compagnie).

      Pour moi aujourd'hui GWT est une solution qui n'a plus vraiment de justification, de même que JSF. Je le disais bien avant que Google commence à se désengager manifestement sinon officiellement de GWT.

      Supprimer
    2. La question n'est pas de savoir ici si GWT a un avenir, mais la façon dont GWT est présenté dans l'article: GWT ne gère pas "la présentation ailleurs qu'à l'endroit où elle s'exécute". En celà, GWT n'est pas différent de CoffeeScript, TypeScript ou Dart.

      Pour ce qui est de la valeur ajoutée et de l'avenir de GWT, et de l'engagement de Google dans le projet, on en reparlera un autre jour. Let's just agree we disagree.

      Supprimer
    3. Tu as raison, ma formulation est trompeuse. J'ai cité à côté de JSF, emporté par l'élan et par l'association d'idées, des technos lourdes consistant à écrire la présentation autrement qu'en natif (HTML + JavaScript).

      Mais par rapport à la phrase précédente où je parlais de "gérer la présentation ailleurs qu'à l'endroit où elle s'exécute", on est bien d'accord que ça ne colle pas avec GWT, puisque le résultat de la compilation GWT s'exécute entièrement dans le navigateur web. Je modifie la phrase.

      Supprimer
    4. Mon post arrive tard mais je comprends pas trop la comparaison entre angular et GWT. Je travaille sur les deux donc je n'ai pas de parti pris, mais je suis à chaque fois étonné lorsque je vois des posts pour savoir qui est le "fort". GWT est destiné au dev JAVA, et propose une solution pour un dev d'appli destiné surtout aux indus. Le seul regret qu'on puisse avoir c'est que ça bosse avec des sevlets... On s'extasie d'angular, mais il propose juste un pattern et des notions qui existent depuis des années, c'est juste le fait que dans le web on est pas habitué. Bref angular fait bien sur les proposions techniques, c'est un effet de mode qui passera comme tout le reste, jusqu'à la prochaine techno supportée surement par google...

      Supprimer
  2. Merci pour votre article dont je partage complètement le point de vue. Les solutions trop lourdes ne résistent pas avec le temps. Mon expérience de développement Struts / JSF m'a permis d'apprécier les qualités de Flex quand j'ai eu à l'utiliser sur certains projets. Mais au delà des qualités indéniables de Flex, j'ai aussi largement apprécié le confort d'utiliser une solution UI complètement découplée du langage Java (i.e. UI Flex <-> métier Java). Aujourd'hui, je ne suis plus convaincu en ce qui concerne l'avenir de Flex. J'attendais une réponse JavaScript. Angular semble être un très bon candidat.

    RépondreSupprimer
  3. Au fil du temps, j'ai pu constater que

    * JavaScript se rapproche petit à petit de Java (avec l'ajout prévu des classes par ex):
    "A false piece of news may become real as Java and JS move closer"
    http://www.jroller.com/dmdevito/entry/a_false_piece_of_news

    * Avec l'évolution de JavaScript, on assiste du même coup à l'émergence de frameworks basés sur JavaScript et qui se rapprochent de Flex:
    "AngularJS and Avatar sound like web standard-based Flex substitute candidates"
    http://www.jroller.com/dmdevito/entry/angularjs_and_avatar_web_standard

    Je crois que JavaScript va continuer sa trajectoire ascendante, et va s'accaparer une plus grande part de l'écosystème (pour faire simple: XML-based GUI orientée composants+templating). Du coup, les frameworks vont manger la laine sur le dos de JSF, en raison des limitations de JSF que vous mentionnez.

    Pour GWT, mon pronostic est un peu différent. A terme, GWT devrait finir par tomber, comme JSF, sous les coups de butoir des frameworks JavaScript. Mais GWT devrait tenir plus longtemps que JSF, en raison du fait qu'il ne présente pas les pbs (de JSF) mentionnés plus haut (GWT scale mieux que JSF), et qu'il est un des champions, sinon LE champion de la communauté Java, et qu'il est déjà en place.

    RépondreSupprimer
  4. Personnellement je ne suis pas fan de l'ajout des classes dans JavaScript, je crains que ça n'incite encore plus de développeurs à écrire du Java en JavaScript, sans en avoir compris les concepts.

    AngularJS est inspiré de Flex, au moins partiellement. Voir par exemple cet article de son concepteur Miško Hevery : What Flex taught me about data-binding.

    Entre GWT et JSF, j'ai une vision un peu différente. Autour de moi j'ai vu plus de JSF que de GWT, et j'ai quand même l'impression que c'est JSF qui est le plus populaire des deux, ce que semblent confirmer les jobs trends.

    Mais surtout, ce sont deux outils qui n'ont pas la même cible. GWT est clairement dans ce que j'ai appelé le web "client-serveur", c'est pour faire du client RIA, ce pour quoi JSF est peu adapté. Mais du coup, s'il y a encore des applications web qui peuvent être plus simples à faire avec JSF qu'avec AngularJS (les applications à l'ancienne, sans client riche ni web services), c'est beaucoup moins vrai pour GWT.

    Sur le type d'applications qu'on développe avec, AngularJS est davantage une alternative à GWT qu'à JSF, même si je pense que l'approche client JavaScript natif a de toute façon amorcé le déclin de ces deux frameworks.

    RépondreSupprimer
    Réponses
    1. L'ajout des classes dans JavaScript peut être une offre de tête de gondole, permettant à des développeurs de commencer à utiliser JavaScript, quitte à aller plus loin ensuite. Difficile à dire si cela apportera vraiment du mieux ou du moins à JavaScript. On verra bien.

      AngularJS est davantage une alternative à GWT qu'à JSF, oui, mais ce que je voulais dire, c'est que, en raison des difficultés liées au modèle JSF, et du positionnement "grand public" de JSF, je pense que JSF devrait néanmoins plus souffrir de AngularJS que GWT (GWT résistant plus longtemps en raison de son positionnement de niche).

      Supprimer
  5. Et puis je voulais signaler cet article très intéressant : A new development era (essay).

    Mis à part le pronostic sur Python qui me semble plus audacieux (même si j'aimerais bien qu'il se réalise), je suis totalement en phase avec la vision exposée. Je pense moi aussi qu'on entre dans une nouvelle ère du développement d'applis web.

    RépondreSupprimer
  6. "C’est là qu’on touche aux limites du fait de gérer côté serveur une interface client. JSF, du moins une combinaison JSF + Facelets + Seam, est très efficace pour créer des applications web classiques, pour ne pas dire à l’ancienne, avec des pages web distinctes et peu d’Ajax."

    C'est une vision très JSF 1.2. JSF 2 a un support ajax natif et développer une appli 100% ajax voir de type single page ne pose plus guère de problème.

    La conso mémoire de JSF dépend de l'utilisation qui en est faite. Et "colossale" est très exagéré. Il existe différentes stratégies quant à la sauvegarde d'état mais globalement la conso mémoire reste très raisonnable (cf. [1]). A noter que JSF 2 supporte maintenant un mode stateless.

    Le stockage de l'état est de toute façon indispensable que ce soit coté Angular que coté JS. L'utilisateur n'apprécierait pas après un rechargement malencontreux de tout perdre.

    Angular est une techno intéressante. Il lui faut maintenant une bibliothèque de composants riche s'il veut rivaliser avec les technos cités.


    http://lu4242.blogspot.fr/2012/05/understandingjsf-2-and-wicket.html

    RépondreSupprimer
  7. Oui bien sûr JSF 2 supporte nativement Ajax, mais pour écrire une appli mono-page réactive, ce n'est pas suffisant.

    Avec JSF la logique de présentation est exécutée par le serveur, ce qui oblige à des tas d'allers-retours dès qu'on veut un client un peu dynamique. Mais même avec plein d'Ajax dans une appli JSF, on est très loin de ce qu'on peut faire facilement côté client avec AngularJS. Et sur mobile n'en parlons même pas.

    JSF est un bon framework, que j'ai recommandé sur de nombreux projets, mais pas pour faire du client RIA.

    RépondreSupprimer
  8. Je pense pourtant que c'est suffisant. Le showcase primefaces montre bien le degré de réactivité qui est complétement transposable à une appli mono page car les mises à jours sont locales, les composants ont des systèmes de caches. Ce n'est bien entendu pas du local, mais la réactivité reste plus qu'acceptable. JSF évolue et reste clairement de mon point de vu une techno à suivre pour le développement de webapp.

    Le coté "facilement" d'Angular est à modérer grandement par l'aspect javascript, par le manque d'une bibliothèque de composants/directives (surtout quand on souhaite faire du RIA) et par le manque de retours d’expériences sur les RIA en Angular. Pour ces deux dernières raisons je ne le recommanderais qu'avec bcp de précautions pour du RIA.


    RépondreSupprimer
  9. Moi pour faire du client RIA, je recommande d'utiliser un framework client plutôt que d'essayer d'arriver à quelque chose d'acceptable en repoussant les limites d'un framework serveur qui n'est clairement pas conçu pour ça.

    Mais quand JSF convient, c'est une solution très productive en terme de développement. Quand un assemblage de composants PrimeFaces permet de faire une application suffisamment réactive, et qu'il ne faut pas qu'elle puisse tourner sur des terminaux mobiles, alors c'est très bien.

    L'écosystème des composants AngularJS est encore jeune, je suis bien d'accord, même si ça évolue vite. En même temps AngularJS a quand même moins besoin de composants que JSF. Ce n'est pas vraiment comparable, avec AngularJS on développe moins par assemblage de composants qu'avec JSF.

    RépondreSupprimer
  10. Ce que propose AngularJS n'est ni plus ni moins ce que proposait XUL, enrichir la syntaxe HTML avec des composant RIA. Lors de l'abandon de XUL en mode web. Les evangelistes mozilla nous promettaient que pour enrichir la syntaxe HTML, viendra la norme XBL2.0 pour nous sauver :-). Celle ci existait déjà dans XUL (XBL1), mais devait être normé par le W3C. hélas cela ne semble pas prévu dans les roadmaps des navigateurs. Pourtant cela était bien plus cohérent que AngularJS. Car AngularJS parse le document pour rajouter son comportement, alors que le navigateur a déjà parséce dernier. Pourquoi ne pas le laisser faire.
    Même si AngularJS semble séduisant par sa syntaxe, je lui promet pas grand avenir, dans la mesure ou à un moment ou un autre, les acteurs vont bien se rendre compte que HTML5 ne permet pas en l'état (sans DHTML) de faire du RIA.
    Viendra alors peut être le retour de XBL2 ou même d'un enrichissement de HTML5 par des composants comme XUL.
    Je vais essayé JSF2.0 et AngularJS, pour voir. JSF avec des frameworks style PrimeFaces me semble pas mal. Il faut l'éprouver maintenant.


    RépondreSupprimer
    Réponses
    1. Sauf erreur, XBL 2 a été remplacé par les Web Components: http://www.w3.org/TR/components-intro/

      Supprimer
  11. Ce débat a presque fait le tour des arguments techniques de l'une et l'autre technologie.Je pense qu'on en finira pas et l'avenir tranchera.

    Cependant, une remarque personnelle et plus générale consiste à dire que le succès d'une technologie n'est pas uniquement liée à ses caractéristiques intrinsèques ou au fait qu'il réponde à un besoin (même si cela reste un élément déterminant). Il faut regarder du côté adoption par la communauté.
    Et de ce point de vue, je compare la dynamique qu'il a autour du Web façon JAVA (conf de Adam Bien à Berlin sur JavaFX) par rapport à la dynamique qu'il y a autour des frameworks MV*/SPA/Client Templating/JS. Et là je me dis qu'il y a quand une différence.

    Ces dernières technos arrivent (principalement des US) comme un buldozer (un peu de philosophie), et elles attirent les développeurs les plus talentueux. Regardez le WEB anglophone pour s'en rendre compte.

    Cela me rappel JAVA en 97 : un language pour le moins verbeux et qui faisait de l'allergie à beaucoup de développeurs. Cependant, le language a eu un énorme succès grâce à son adoption et à tous les développements qui l'on accompagné (dont J2EE/JEE).

    Cela, alors qu'il y avait à l'époque des languages bien plus prometteur du point de vue purement techniques.

    Autre considération évoquée par Thierry : l'aspect service. Les DSI sont actuellement dans un mode intégration, et accepte de moins en moins des refontes de leur SI. Et dans ce cadre, les jolies composants JAVA bien structurés, dont profite JSF sont justes inutiles. On demande de plus en plus de refaire des IHM en utilisant le backend existant (vécu personnel). Et dans ce cadre la logique SPA/JS est plus adaptée.

    Dernière remarque : le plaisir de développer des IHM avec ces technos par rapport aux technos type server templating est incomparable. Le fait de faire son appli en partant d'une simple page HTML en décrivant ce que l'on doit présenter à l'utilisateur est complètement naturel, va de soi...etc.

    RépondreSupprimer
  12. A quand des composants JSF qui utilisent AngularJS ? :)

    RépondreSupprimer