Il y a 14 ans -
Temps de lecture 13 minutes
Tapestry 5 vs. Wicket
Mettre au grenier la configuration XML et l’API J2EE, voilà le pari que tentent de relever les frameworks orientés composants. Pour atteindre ce but louable : simplifier la vie stressée du développeur et par là même sauver quelques-uns de ses cheveux, le XML est remplacé par du code Java et l’API J2EE est cachée dans les entrailles du framework. Les pages deviennent des objets Java liés à des templates, auxquels sont ajoutés des composants réutilisables (si, si). Les composants sont ni plus ni moins que d’autres objets Java liés à des templates. Les requêtes, quant à elles, deviennent des événements traités par les pages et les composants.
Voilà pour le principe de cette approche qui semble avoir de beaux jours devant elle. Emergence naturelle ou stratégie voulue, la fondation Apache, jamais avare de solutions, nous propose deux frameworks composants : Tapestry 5 et Wicket. Alors comment choisir ? Le mieux est encore de se faire sa propre idée en les testant tous les deux. Nous sommes bien d’accord, rien ne remplacera jamais l’efficacité du prototypage. Cela n’empêche pourtant pas de faire une pré-sélection basée sur quelques points de comparaisons stratégiques. Voici donc un article pour vous aider à faire le meilleur choix ; à savoir le choix qui répondra le mieux aux besoins et à l’environnement de votre projet.
Bien qu’adoptant tous deux la programmation web orientée composant, les deux projets sont imprégnés d’une philosophie et d’un objectif différents. Les buts principaux de Wicket sont :
- Pages et composant statefull
- Programmation à la Swing
- Séparation stricte entre code et template
Pour Tapestry 5, les objectifs sont différents :
- Optimiser l’utilisation CPU et mémoire
- Simplifier la création de composants
Attention ! Ce sont là les objectifs sur lesquels les deux projets sont focalisés. Ce qui ne signifie pas qu’ils s’y intéressent exclusivement. Wicket supporte bien les composants sans état, ce n’est juste pas son but principal. De même que Tapestry supporte le développement web entièrement en objet Java.
Ils affichent, aussi, des buts communs, comme d’être orientés Pojo et d’éliminer la configuration XML avec le pattern Convention Over Configuration.
Configuration
Pas de XML ne veut pas dire pas de configuration. La différence consiste à configurer l’application avec du code Java. Dans le cas de Wicket, il s’agit de construire une classe héritant de WebApplication et, de la fournir en paramètre du contexte web. Dans la WebApplication, il faut fournir la classe correspondant à la page d’accueil en surchargeant la méthode getHomePage(). Pour définir les paramètres globaux de l’application, il faudra utiliser les getters et setters de la classe mère.
De la même façon, avec Tapestry, il faut d’abord ajouter le TapestryFilter, puis déclarer le package principal de l’application en context-param. Par défaut, Tapestry va considérer que le package myapp.services contient des services Tapestry IoC, que le package myapp.components contient des composants, et que le package myapp.pages contient des pages. L’application est configurée à partir d’une classe Pojo myapp.services.AppModule. Il s’agit en fait d’un module Tapestry-IoC qui, via des noms de méthodes conventionnels, va permettre d’affiner la configuration du framework et de monter nos propre services. En ce qui concerne la page d’accueil, par défaut, Tapestry chargera la page nommée Index.
Pages et composants
Dans Tapestry 5, les pages comme les composants sont des pojo décorés par des annotations et/ou utilisant des noms de méthodes conventionnels. Les annotations permettent d’injecter avec Tapestry IoC des services ou des composants. Elles sont aussi utilisées pour écouter des événements via des méthodes annotées. Certains noms de méthodes sont reconnus et utilisés par Tapestry pour recevoir les événements (onActionFromComponentId() par exemple). Souvenez vous, la configuration exige de fournir des nom de package pour les pages et les composants. Tapestry lie toutes les classes contenues dans les packages pages et composants à ses annotations et, cerise sur le gâteau, les recharge à chaud.
Avec Wicket, pages et composants sont des classes construites par héritage qui fournissent un constructeur chargé de les composer. Dans le constructeur, il faut créer les composants, les lier aux template et les ajouter à la page comme on le ferait avec un conteneur Swing. Les modèles permettent de lier les données des beans aux composants, et de les maintenir. Parfois, il sera utile de surcharger quelques méthodes comme onSubmit() pour un formulaire.
![]() |
![]() |
|
---|---|---|
Wicket |
|
|
Tapestry 5 |
|
|
En clair, avec Wicket on développe une application web comme on le ferait avec un toolkit graphique. La transition pour les habitués du MVC sera plus difficile. Tapestry est plus modéré de ce point de vue avec ses Pojo qui ne manquent pas de rappeler les actions ou contrôleurs d’usage en MVC. La possibilité de créer des composants réutilisables est bien au rendez-vous, par contre il faudra faire très attention au choix des identifiants qui doivent être uniques pour le couple page – composant. Impossible d’échapper au piège des identifiants uniques, quand il s’agit d’ajouter plusieurs fois le même composant dans une page par exemple.
Les templates
Dans les deux cas, les templates sont des fichiers XML composés de tags HTML et de quelques ajouts dans un espace de nom spécifique aux frameworks. Ils proposent tous deux de décorer le HTML avec des attributs spécifiques ou bien de directement ajouter des tags qui représentent les points d’ancrage des différents composants. Pour établir la liaison entre le code Java et le template, chaque composant est ajouté dans le template avec un identifiant unique qui est utilisé plus tard dans le code. Par défaut, les templates doivent porter le même nom que la classe auxquels ils se rapportent, ce qui inclut bien sûr le nom du package.
Wicket impose une séparation stricte entre code et template. Des attributs spécifiques Wicket (wicket:id= »monId ») sont ajoutés au template pour définir l’identifiant des composants. Dans le code, les composants sont liés au template en fournissant leur identifiant comme paramètre du constructeur. En opposition au JSP et autre Freemarker, il n’y a plus de code ou de pseudo-code dans le template, toute la partie dynamique est développée en Java pur. Pour gérer la mise en forme des pages (menu, en-tête et pied de page), Wicket propose l’héritage de template sur le même principe que sitemesh. Un tag est ajouté dans le template de la page mère, pour indiquer le lieu ou sera intégré le contenu surchargé par les template fils. Les templates fils, doivent, de leur côté , contenir une balise wicket:extend encadrant le HTML et les composants à injecter dans le template hérité.
La différence réside encore une fois dans le côté un peu plus laxiste de Tapestry qui favorise l’utilisation de pseudo-code dans le template. En définitive, les composants Tapestry fonctionnent un peu comme des Taglibs sans la configuration XML qui va autour. Ici, en plus de l’identifiant, les balises spécifiques supportent un nombre illimité de paramètres transmis sous la forme d’attributs XML ou de blocs de code HTML entourés du tag t:parameter. Les attributs peuvent être définis dans différents scope comme literal pour du texte, propertie pour des propriétés de la classe et bien d’autres. Tapestry fournit aussi un moyen d’injecter directement du texte ou du code HTML avec « des extensions ». Il suffit de placer entre ${…} le nom d’une propriété du composant pour que sa valeur soit injectée dans le rendu HTML. La mise en forme se fait par composition. Le template des pages est entouré par la balise d’un composant. Celui-ci doit alors définir un élément <t:body/> qui sera remplacé par le corps de la page.
![]() |
![]() |
|
---|---|---|
Wicket |
|
|
Tapestry 5 |
|
|
Force est de constater le côté plus laxiste de Tapestry 5, qui donne une plus grande liberté pour la rédaction des templates HTML, et qui surtout dépayse moins du J2EE traditionnel. Cette liberté a bien sûr un coût car elle permet au développeur de faire à peu près tout et surtout n’importe quoi. Il faudra garder un œil attentif à ce que font les développeurs, pour éviter de se retrouver avec un code illisible.
Principe de navigation
Dans les deux cas, la navigation est assurée par des composants de type Link ou Form qui lèvent des évènements en relation avec les requêtes de l’utilisateur. C’est la méthode captant l’évènement qui va définir la Page à retourner au client.
Pour Wicket, il faut appeler explicitement setResponsePage(…) dans la méthode du composant captant l’évènement. Ici, Il est possible de fournir une classe, ou une instance de Page. Par défaut, les URL sont générées pour la durée de vie de la session; mais il existe une alternative basée sur des BoorkmarkableLink permettant de créer des liens persistants. A chaque appel, les objets composants et pages sont instanciés puis stockés en session, seuls les templates sont stockés dans un cache qui permet d’accélérer le rendu et de recharger les templates à chaud pour le même prix.
Chez Tapestry, c’est le retour de la méthode captant l’évènement qui détermine la page ou le contenu de la réponse HTTP. Au développeur de choisir le type de retour, une chaîne pour le nom de la page, la classe de la page, la page instanciée, ou d’autres type de retour comme les objets JSON et les Stream. Les URL sont générées en REST de manière à assurer leurs persistance côté client. Notez que les pages sont instanciées une fois, puis conservée dans un pool pour être réutilisées par n’importe quelle session. Les pages passent donc par une phase de nettoyage après chaque utilisation. Il faut définir des méthodes onActivate et onPassivate pour récupérer le ou les paramètres stockés dans l’URL et charger les données en conséquence. Une annotation permet aussi de stocker des données en session pour les inconditionnels du genre.
![]() |
![]() |
|
---|---|---|
Wicket |
|
|
Tapestry 5 |
|
|
Il faut retenir tout de même, pour l’un comme pour l’autre, qu’aucune configuration XML n’est nécessaire.
Validation
Inutile de dire que la validation fait partie des conditions sine qua non à l’utilisation d’un framework web. Ici encore, le principe est le même. Il s’agit d’ajouter des validateurs prédéfinis aux composants du formulaire. Les deux projets fournissent sensiblement la même liste de validateurs natifs, avec une légère avance pour Wicket. Reste une différence importante. Tapestry est le seul à fournir une validation serveur et client. Mais il le fait au prix d’une grande restriction, sur l’initialisation des validateurs, qui ne peut traiter qu’un seul paramètre de type chaine (JavaScript ?). Pour ce qui est des validations un peu plus avancées, il faut se tourner vers l’évènement Tapestry onValidate qui permet d’ajouter des erreurs à la validation du formulaire. De l’autre côté, Wicket propose de créer et d’ajouter au formulaire des IFormValidator qui permettront de faire de la validation sur plusieurs champs. Au final, Wicket a l’avantage de configurer la validation entièrement en Java. Dans Tapestry il faut plutôt la définir directement dans le template via un attribut validate.
Ici, pas de miracle, les solutions proposées sont assez simplistes et ne répondront sans doute pas d’emblée aux logiques de validations compliquées. Elles fournissent tout de même un cadre propre pour la validation qui permettra, avec un peu de développement, de répondre à peu près à tous les besoins.
![]() |
![]() |
|
---|---|---|
Tapestry 5 |
|
|
Wicket |
|
|
Intégration d’autres Framework
Spring est évidement de la partie, chacun y allant de son annotation pour injecter des beans. Après un peu de plomberie, pour monter la WicketApplication en singleton Spring et lui ajouter la fabrique Spring en tant que ComponentInstanciationListener, il devient possible d’utiliser @SpringBean(name= »… ») pour injecter ses services dans les composants.
Dans Tapestry, il suffit de remplacer le TapestryFilter, précédemment utilisé, par le TapestrySpringFilter puis d’ajouter toujours dans le web.xml la configuration standard de Spring, à savoir un ContextLoaderListener responsable du chargement des différents applicationContext.xml. A partir de là, Tapestry-IoC inclut les beans Spring et les rend disponibles via l’annotation standard @Inject.
En plus de Spring, Tapestry fournit une extension pour Hibernate qui permet de le configurer rapidement et de gérer les transactions avec une annotation @CommitAfter. Cela manque un peu d’intérêt à mon goût, dès lors que Spring est utilisé dans le projet, mais cela peut permettre de s’en passer plus facilement.
Pour le JavaScript, Wicket a choisi de camper sur le serveur et de ne rien embarquer en terme de script client. Est-ce un bien ? Est-ce un mal ? En tout cas, Tapestry voit les choses différemment et embarque nativement la librairie PrototypeJS, ainsi que Scriptaculous. Grâce à cela, il fournit out-of-the-box des composants Ajax et la validation client. L’API JSON.org est utilisé pour les requêtes asynchrones et pour l’initialisation des composants JavaScript. Pas d’inquiétude à avoir, si Wicket n’intègre rien au départ, il est très simple d’embarquer JQuery par exemple.
Pour pouvoir bénéficier de composants Web 2.0 avancés et intégrer d’autres librairies comme GWT, Seam ou que sais-je encore, il faut se tourner vers les contributions. Les deux projets listent un certain nombre de sites de contributions, mais il faut un peu de chance pour tomber sur des composants maintenus. De ce point de vue, la communauté Wicket semble plus active.
Conclusion
A la fin, je suis bien forcé de constater que les deux frameworks se valent. La différence se joue un peu sur la performance et beaucoup sur le goût. En clair, si le cahier des charges prévoit une charge importante avec haute disponibilité et scalabilité, Tapestry sera un meilleur choix. Mais ce sera au prix d’un effort sur la gestion des données persistantes par rapport à Wicket. Pour le reste, il faudra choisir : le développement à la Swing et les composants par héritage de Wicket, ou les template par composition et les composants annotés de Tapestry. J’ai quant à moi une préférence pour Tapestry 5 qui propose une approche plus naturelle pour les habitués du développement web MVC. Ceci n’enlève rien à Wicket, qui est plus rigoureux et ne souffre d’aucune lenteur.
Commentaire
9 réponses pour " Tapestry 5 vs. Wicket "
Published by Gabriel , Il y a 14 ans
Bon article, merci! J’apprécie tout particulièrement la conclusion qui montre qu’il y a une différence d’utilisation entre wicket – plus orienté applis d’entreprise solidité du code et refactoring (à la Swing) – et Tapestry, plus orienté performance et convention over configuration (à la rails).
A noter tout de même que Wicket ne « campe » pas côté serveur. Il est facile de creér des composants Ajax très aisément, de la même manière qu’un composant classique.
Soit le lien html suivant:
click me
Voici une manière de créer un lien « classique » (qui rafraîchit la page).
add(new Link(« link ») {
public void onClick() {
// do nothing.
}
});
Voici un lien ajaxifié, qui utilise une librairie javascript pour rafraîchir 1 à n composants.
add(new AjaxFallbackLink(« link ») {
public void onClick(AjaxRequestTarget target) {
// add the components that need to be updated to
// the target
}
});
La différence n’est pas énorme…
Wicket n’embarque pas une librairie connue par défaut, contrairement à Tapestry qui utilsie avec bonheur Prototype. Mais les benchmarks qui ont comparé différentes librairies JS dont celle de wicket ont été très favorables pour cette dernière.
Il est possible en Wicket d’utiliser des composants qui eux permettent d’avoir des effets scriptaculous, ou permettent d’utiliser des plugins jquery. On a par exemple la librairie wiiquery qui promet d’être très intéressante.
Enfin un dernier mot, la structuration des communautés est assez différente. Tapestry est l’oeuvre (principalement) d’un Auteur, qui agit comme tel, fait évoluer l’api selon sa vision (profonde). C’est un framework (qui a été) (et qui reste) profondément novateur. Wicket est une oeuvre plus communautaire bien plus classique, mais qui a la chance d’avoir des membres à la fois motivés, assez nombreux pour faire pas mal de choses, et pas trop nombreux pour ne pas crouler sous le succès.
A noter aussi, pour ceux qui sont intéressés par « comment se font les choses », que Tapestry est arrivé quasiment le premier, et Wicket quasiment le dernier. Avec GWT et Jersey (JAX-RS). Avec ces quatre frameworks, on a vraiment à mon sens quatre excellentes solutions pour faire des développements webs.
Published by Emmanuel Koch , Il y a 14 ans
J’aimerai ajouter un autre aspect important : le « support » offert par Tapestry.
J’ai longuement utilisé Tapestry 4, pour apprendre un jour qu’ils sortent Tapestry 5, qu’ils ne supportent plus le 4, et qu’il n’existe pas de moyen facile de convertir une appli 4 en 5.
Désolé, mais pour moi la maintenance est un aspect trop important. Tapestry nous a déjà montré par le passé que ce n’est pas un objectif important pour eux. Etes vous prêts à devoir réécrire tout votre code quand ils passeront à Tapestry 6?
Pas moi.
Published by Séven Le Mesle , Il y a 14 ans
Effectivement, j’étais passé à côté du support Ajax fourni par Wicket. Merci aussi d’avoir souligné l’importance et la qualité de la communauté autour du projet Wicket. Tapestry est bien le fruit d’une équipe de 8 développeurs avec, il est vrai, une communauté moins fédérée.
Au final, je dirais que Wicket favorise une meilleure qualité de code source. Là où Tapestry joue plus le jeu de la productivité ce qui rejoint le rapprochement à Rails.
Pour ce qui est de l’incompatibilité entre Tapestry 4 et 5, j’ai suffisamment connu le problème avec Hibernate pour savoir a quel point cela peut-être rageant. Est-ce qu’un projet fait la migration Struts vers Struts 2 sans douleurs ?
Sur le site de tapestry, Howard Lewis Ship argue que certaines classes dataient de 2000. Tapestry 5 n’est pas compatible, mais son but est aussi d’assurer une bonne compatibilité ascendante. Avec ses Pojo et la convention de nom, Tapestry évite d’exposer aux développeurs ses API internes. Ce qui réduit énormément le couplage entre la version du framework et l’application. J’en veux pour preuve la passage récent de la version 5 à la version 5.1 sans douleurs.
Reste le problème du support à long terme et il me paraît impossible de parier sur le fait que les deux frameworks seront compatibles avec leurs API actuel.
Published by Carl Azoury , Il y a 14 ans
Bonjour,
Tout d’abord merci pour cet article instructif car je ne connais pas bien Tapestry. Concernant Wicket, j’aimerais apporter quelques précisions.
Le développement de composants et de pages peut certes êtres fait par héritage, mais aussi et surtout par composition. D’une part les Panels, composants ayant leur propre markup HTML, permettent de spécialiser le rendu d’une page. Ainsi, en fonction du contexte on pourra rajouter un Panel pour la recherche d’une personne morale ou un Panel de recherche d’une personne physique.
D’autre part, tout composant peut être enrichit et son comportement modifié par l’ajout d’un Behavior. Si je prend l’exemple d’un Label classique.
Label label = new Label(« date », monModel);
Pour que ce label soit maintenant rafraîchit toutes les 2 secondes côté client par un appel Ajax, il suffit de faire :
label.add(new AjaxSelfUpdatingTimerBehavior(Duration.seconds(2));
Le composant label n’a plus le même comportement grâce à la composition et non à la création d’une sous-classe, et ceci est juste un exemple. Je ne sais pas si Tapestry possède la même notion de Behavior.
On ne parle pas des modèles dans ce billet, mais cela serait intéressant pour la comparaison entre les deux frameworks. Concernant Wicket, c’est un grand point fort qui permet par exemple, en trois lignes de code, de drag & dropper depuis la page HTML un élément d’une liste dans un formulaire afin de le peupler avec les valeurs issues de l’objet (en gros on récupère l’objet du composant que l’on drag afin d’en faire le modèle du composant sur lequel on drop). Est ce que Tapestry possède aussi une telle notion de modèle ?
Concernant les wicket:id, ils doivent être unique sur une page certes, mais seulement sur le même niveau de profondeur de l’arbre de composants. En gros, sur la même page, je peux avoir un panel et un formulaire qui sont au même niveau d’arborescence sur la page et donc peuvent englober chacun un composant ayant le même wicket:id, par exemple « username ».
Concernant la validation, Wicket ne permet pas en effet la validation côté client nativement et offre par contre un mécanisme de validation par des appels Ajax. Ceci étant dit, il est possible d’intégrer à Wicket la validation côté client et c’est ce que nous avons commencé à faire en intégrant la librairie javascript nommé YAV.
C’est intéressant de l’évoquer, car même si notre implémentation est largement perfectible, cela illustre le mécanisme très puissant d’extension des composants et d’utilisation des Behavior.
A l’utilisation, pour avoir la validation côté client, il suffit d’écrire le code suivant :
monForm.add(new YavBehavior())
C’est tout…. le comportement du formulaire est maintenant différent. Ce Behavior liste l’ensemble des règles de validation côté Java et ajoute pour chaque règle de validation le Javascript correspondant côté client.
Le code et l’application de démonstration sont téléchargeables depuis le lien suivant :
https://wicket-stuff.svn.sourceforge.net/svnroot/wicket-stuff/trunk/wicketstuff-core/yav-parent/
Nous avons une autre application de démonstration utilisant ce Behavior illustrant différents points fort de Wicket et téléchargeable au lien suivant :
http://yeswicket.com/index.php?post/2009/05/20/Développer-une-application-web-en-Wicket
Published by Manu , Il y a 14 ans
Yeah Wicket Powaaaa !!!!
Ceci était un message du CAIBFW (Comité des Adorateurs Inconditionnels et un Brin Fanatique de Wicket).
Published by Gabriel , Il y a 14 ans
Bonjour Carl,
Tapestry n’a pas cette notion de Model. On fait directement appel à des beans, si je me souviens bien. Il n’y a pas la médiation d’un wrapper.
Le model est une indirection bien pratique, notamment pour toutes les implémentations de cette interface (LoadableDetachableModel, PropertyModel, etc) mais si son utilisation est intéressante, ce n’est tout de même pas elle qui permet de gérer le drag&drop, mais bien le fait d’avoir une appli stateful, ou j’ai râté un truc?
Comme quoi une belle architecture stateful a tout de même des avantages.
+1 pour le rappel sur les composants. C’est tout de même Le point fort des développement en Wicket. Créer des composants réutilisables se fait sans effort, assez naturellement. On peut créer un simple composant qui spécialise un comportement (champ texte obligatoire, par ex), ou un gros composant métier.
Encore faut-il savoir trouver de l’utilité à cette composition de la page. C’est tout de même une difficulté à ne pas négliger, lors d’un développement avec un framework à composants. La factorisation lors de l’écriture des services métiers est une habitude ; pas forcément lors de la création de composants graphiques.
Published by Joseph , Il y a 13 ans
Bonjour
J’arrive tardivement, à la faveur d’un click sur le tag wicket du tag cloud.
Toutefois, je ne peux m’empêcher de me demander comment Tapestry a été déclaré « meilleur en termes de performances et scalabilité ». En effet, il ne me semble pas que l’article ci dessus creuse ses aspects en détails, tout en se permettant, néanmoins, de conclure.
Or, à ma connaissance, la seule investigation poussée est celle de Peter Thomas, disponible là http://ptrthomas.wordpress.com/2009/09/14/perfbench-update-tapestry-5-and-grails/. Cette investigation me semble menée honnêtement.
La conclusion est la suivante : Wicket 1.4.1 est plus performant en général que Tapestry 5.1.0.5 et, pour peu que l’on passe à l’HTTPSessionStore, de façon encore plus marquée.
Qu’en dites vous ?
cordialement,
joseph
Published by Séven Le Mesle , Il y a 13 ans
@Joseph
Tout d’abord merci d’avoir pris le temps de lire cet article. Je me permet maintenant de rebondir sur la citation de l’article de Peter Thomas qui en lisant les commentaires montrent que l’auteur est assez orienté et que dans tous ses articles Wickets est mis en avant. Peter Thomas est plutôt un évangéliste Wicket qu’un analyste dans la voie de la neutralité. Il apparait de plus que l’implémentation réalisée par ce dernier de l’application sous Tapestry ne respecte pas les best practices du framework.
Dans mon article, je pense avoir fait largement transparaitre la proximité entre les deux frameworks et je me cite : « un peu sur la performance et beaucoup sur le goût ».
Pour en revenir donc à la performance et à la scalabilité. Je ne pense pas être malhonnête en disant que le chargement de la session HTTP est un facteur limitant en terme de performance et de scalabilité pour Wicket. Avec Tapestry, il est recommandé d’utiliser les URL à la REST pour retrouver les objets manipulés.
Cela permet de ne pas utiliser la session HTTP et donc évite pour des déploiements en cluster la réplication de sessions entre les serveurs. Ce qui est il me semble déterminant en terme de performance et de scalabilité.
C’est sur ces simples faits que j’ai basé ma conclusion accompagné bien évidement des différents retours que j’ai pu glaner sur le web. Mais je dois bien reconnaître que je n’ai pas réalisé de tests de performance par moi même. Je n’en reste pas moins convaincu que préférant Tapestry et le connaissant mieux que Wicket en faisant le même test que Peter Thomas avec des implémentations différente j’aurai obtenu de meilleures performance pour Tapestry.
C’est en partie pour éviter ce type d’écueil, que je ne me suis pas lancé dans cette comparaison.
J’espère vous avoir éclairé sur ma conclusion.
Bien cordialement,
Séven.
Published by joseph , Il y a 13 ans
Le but principal de mon commentaire initial n’était pas de dire « wicket est plus performant », mais plus de remettre en cause ce postulat comme quoi tapestry 5 est le plus performant sans en avoir quantifié la chose.
En effet, la performance et la « scalabilité » sont, en informatique et AMHA, une vraie gageure, résultante d’un bon design doublé de beaucoup d’optimisations à grands coups de « profileurs ». Dur de prévoir des performances à la seule lecture d’un code ou d’une architecture. Ainsi, je trouve cela très dangereux de penser qu’un framework est plus performant que d’autres sans réelle quantification de la chose, et à fortiori de s’en servir en tant qu’argument dans une conclusion.
Concernant la comparaison de Peter Thomas, je la mettais en avant justement en tant que contre exemple. Dans son cas précis, dont le code est accessible, wicket est plus performant, contrairement à ce que l’on pourrait croire sans avoir vérifié la chose.
L’important est de voir sur le fond. Si jamais des aspects importants de Tapestry 5 sont passés à la trappe pour la démo de Peter Thomas, je pense qu’il sera plus que ravi de les intégrer. Concernant la recommandation de faire du REST en tapestry 5, j’y reviens plus bas dans mon commentaire, mais en substance je ne vois tout simplement pas comment elle dépasse le cadre du vœux pieu (mais je ne demande qu’à en savoir plus).
Pour en revenir au fond, il me semble que l’article de Peter Thomas met à mal bien des idées préconcues, notamment sur le nombre de créations d’objets (voir le tableau avec head dump) et la heap size de Wicket, travers dont ce framework est souvent accusé (à tort donc à priori).
Au delà, sur l’aspect des performances pures, Wicket et Tapestry 5 semblent être dans le même ordre de grandeur (avec avantage wicket), tandis que seam et grails sont nettement plus consommateurs de ressources. Ma principale conclusion serait de plus me méfier de ces 2 derniers frameworks si d’aventure j’envisageais de les utiliser sur des sites avec de grosses charges. Pour wicket et tapestry 5, je serai moins inquiet, mais je passerai tout de même par une étape de tests de charges (le plus tot possible).
Toujours concernant Peter Thomas, je pense qu’il a été honnête dans son travail. Certes, il préfère Wicket, mais d’autres préfèrent Tapestry 5 sans que cela ne les empêche d’écrire des comparaisons ;) Et moi même, plutôt conquis par Wicket, de commenter le tout… Bref, regardons les messages et non les messagers.
Pour finir, j’aimerai également discuter certains des autres points présentés dans l’article, en deux parties : précisions sur le fonctionnement de wicket et quelques questions sur Tapestry 5.
A. Précisions sur le fonctionnement de Wicket
Dans la partie Pages et composants :
A propos de l’unicité des identifiants de composants, le problème est, je trouve, mal exposé.
Wicket élabore en effet une hiérarchie des composants utilisés. A ce titre, deux composants partageant le même « parent » doivent avoir des identifiants distincts. Par contre, deux composants peuvent partager le même identifiant pour peu que leur parent difère dans la hiérarchie. C’est d’ailleurs nécessaire pour permettre la réutilisation de composants.
De même, lorsqu’on désire répéter une partie d’html, on utilise des composants wicket qui prennent en charge très « joliment » la problématique de l’unicité des composants : il n’y a aucun problème à l’usage.
En fait, le seul problème est de maintenir la cohérence entre l’arbre de composants côté Java et côté html. A la moindre différence, en effet, Wicket stoppe tout au runtime .
Ceci dit, wicket fournit des messages d’erreurs très complets sur ce point. Il s’agit donc de quelque chose d’aisé à corriger, relevant de l’oubli momentané, et pas d’un problème de fond, même si pouvant arriver souvent (en fonction du développeur).
Dans la partie « Les templates »
Wicket propose également, et heureusement, la composition, via les Panel. Ceux ci sont en effet des blocs « code Java/template html » que l’on peut réutiliser n’importe où. L’héritage est en fait essentiellement utilisé pour définir le layout des pages (mon contenu à tel endroit, mon menu là et ainsi de suite). En pratique, l’héritage se contente généralement d’intervenir venir via une « PageDeBaseDeMonApplication » qu’on étend, puis dans laquelle on se soucie juste de fournir le contenu central. Ce contenu central est lui généralement composé via des Panel.
Dans la partie « Validation »
Parmi les moins, il y a « * Pas de notion de validation métier ». Je ne comprends pas bien ce moins. Wicket permet de créer des « validators » au niveau de chaque composant puis au niveau du formulaire, incluant donc plusieurs composants et permettant de vérifier des règles très complexes. Si là dedans on veut basculer vers une couche métier pour effectuer les dites validations, c’est possible. Par contre rien n’est imposé, et c’est tant mieux, car du coup on colle ensuite au plus près des besoins.
Dans la partie « Intégration d’autres Framework »
Wicket a décidé de ne pas embarquer de grandes librairies javascript, type Jquery, c’est tout à fait vrai. Par contre Wicket intègre des fonctionnalités javascript de base, notamment et surtout pour l’Ajax. Ainsi le reload partiel de page est tout à fait possible. On peut même décider que tout ou partie du cycle de vie (validation des composants suite à update, soumission du formulaire…) soit réalisée en ajax pour tel ou tel composant.
Après, le fait que wicket fasse l’essentiel côté serveur affranchit énormément le client de ces choses là. Du coup si on veut intégrer la librairie X ou Y pour avoir de jolis effets, c’est tout à fait possible et, au contraire, wicket ne vient pas trainer dans les pattes.
Seul hic, à contrario, intégrer l’Ajax sauce framework X Y avec l’Ajax wicket n’est pas simple/recommandé. Il est plutôt recommandé de n’utiliser que celui fournit par Wicket.
A noter que je rebondirai sur les commentaires parlant des modèles wicket : ces derniers sont la notion qui permet à wicket d’être stateful et « scalable » à la fois. Ils sont d’une puissance impressionnante et souvent on est ébahi par ce qu’ils permettent. La contrepartie à cela est que leur compréhension représente le gros point difficile, je trouve, de l’apprentissage de wicket. Mais une fois cela réalisé, que du bonheur ;)
B. Questions sur Tapestry 5
Dans la partie « Principe de navigation »
Je ne comprends pas comment Tapestry 5 peut faire abstraction de tout état. Quid de l’identité de l’utilisateur loggé, de sa navigation, de son profil, de son email s’il est loggé et ainsi de suite ? Comment est ce géré ? A ma connaissance, les applications purement REST ne constituent qu’une infime partie des applications web généralement développées…
Dans la partie « Validation »
Parmi les plus, il y a validation côté client : la validation est elle également réalisée coté serveur ? Sinon, comment s’assurer qu’un Javascript Ninja n’a pas contourné la validation côté client? Et quid des navigateurs sans javascript ?
Encore merci et bien cordialement,
joseph