Retour du front : dois je migrer vers GWT 2 ?

le 11/02/2010 par Bertrand Paquet
Tags: Software Engineering

Je travaille sur un projet GWT depuis un peu plus d'un an (26K lignes de Java, à peu près autant de code en test, GWT 1.7.1). GWT 2 est sorti récemment, avec son lot de nouveautés. Plusieurs questions se posent donc :

  • Dois je migrer vers GWT 2 ? (ou "Qu'est ce que GWT 2 va apporter à mon projet ?")
  • A-t-on vraiment le choix ?
  • Combien cela va t il me coûter ?
  • Comment vendre ce coût à ma MOA ?

Afin de répondre à ces questions ô combien importantes, j'ai donc fait quelques essais avec GWT 2. Voici le résultat.

Les nouveautés

Cette liste n'est pas exhaustive, elle contient juste celles qui me semblent importantes. La liste complète est ici.

Le nouveau Dev Mode

Cette nouveauté permet au développeur d'utiliser son navigateur habituel au lieu de celui qui était embarqué dans le Hosted Mode. Qu'est ce que cela change ? Sous windows, au lieu d'être obligé d'utiliser Internet Explorer 6, les développeurs vont pouvoir utiliser Firefox. Outre le moteur Javascript beaucoup plus performant, il est désormais possible d'utiliser Firebug !

Les développeurs sous Windows vont donc pouvoir avoir le même confort de développement que sous Mac (ou le Hosted Mode utilise Safari depuis toujours :-)). Pour la petite histoire, j'ai un jour calculé la différence de vitesse de l'application dans le Hosted Mode entre un Mac et un PC : cela va 6 fois plus vite avec Mac...

Cette nouveauté va donc améliorer grandement le confort de travail des développeurs. Toutefois, le navigateur cible du projet est Internet Explorer 6 : on est quand même obligé de l'utiliser pour mettre au point les CSS...

Le code splitting

Cette nouvelle fonctionnalité permet de séparer une application GWT en plusieurs fichiers Javascript, ce qui permet d'améliorer les performances au chargement. Pour plus d'informations, voir ici et .

J'ai essayé rapidement cette fonctionnalité sur mon projet, pour lequel le Javascript fait 970K (ce qui commence à être critique). Au bout de quelques essais, je n'ai pas réussi à splitté mieux qu'en deux blocs de 969K / 1K.
Soit je ne peux pas splitter mon projet facilement parce qu'il n'a pas été prévu pour, soit il faut que je passe plus de temps dessus. Mais la fonctionnalité est là.

La gestion des ressources

Cette nouvelle version du système de gestion des ressources va nous permettre d'améliorer un des plus gros problème de maintenance que nous avons avec notre application GWT : la maintenance des CSS. Avec GWT 1.7.1, nous avons

  • Des CSS externes à l'application Javascript
  • Ces CSS contiennent des liens vers des images, qui sont elles aussi externes à l'application Javascript
  • Les classes CSS sont en dur dans le code (c'est à dire sous forme de chaînes de caractères)

Avec GWT 2 :

  • Les CSS seront internes à l'application Javascript (packagées par GWT dans cette application, de manière optimisées)
  • Les images seront elles aussi internes à l'application Javascript, même quand elles sont seulement référencées par CSS (non utilisées sous forme d'objet Image dans le code). Voir ici pour plus d'informations. Ce que cela améliore :
    • GWT package l'image sous la forme la plus adaptée (image inlinée dans la CSS, image packagée avec d'autres dans une grande image, image indépendante)
    • GWT se charge de remplir pour nous certaines propriétés de l'image : background-image, width, height, clip. Le nom du fichier de l'image n'est plus dans la CSS, mais dans une interface Java. Cela s'applique également à quelques autres déclarations (repeat notamment)
    • GWT gère pour nous les problématiques de cache sur les ressources (plus de mise en production problématiques à cause des reverse proxy qui cachent des vieilles ressources)
  • Dans le code Java, les classes CSS ne seront plus écrites en dur, mais seront des appels Java sur une interface. Cela permet de faciliter la maintenance et le refactor. De plus, GWT vérifie que toutes les classes déclarées dans la CSS sont bien déclarées dans l'interface Java correspondante, ce qui permet de voir quel bout de code utilise une classe CSS donnée !

Hélas, la migration de nos CSS actuelles vers ce système ne va pas être gratuite. Avant GWT 2.0, nous avions déjà des douleurs avec les CSS, et avions prévu de les traiter. Nous allons donc pouvoir profiter des nouveautés pour ce chantier.

Les layouts

En GWT 1.7, nous avons fait tout le positionnement graphique avec des VerticalPanel, HorizontalPanel, et beaucoup de CSS. Cela pose 2 problèmes :

  • Le code HTML généré par des VerticalPanel et HorizontalPanel n'utilise que des tables HTML. Le code de la page est donc très lourd et très peu lisible
  • L'effet de style CSS sur des éléments contenus dans des tables est assez variable selon les navigateurs, le type de composant. Par exemple, dans un HorizontalPanel, on peut dimensionner un composant par sa taille en pixel, mais pas par sa taille relative.

Les développeurs de GWT ont donc ajouté dans GWT 2 un nouveau mécanisme, les layout panels, qui sont basés sur des div, plutôt que des tables. Cela est beaucoup mieux, car

  • Le code HTML est moins lourd (plus de <table><tbody><tr><td>, mais juste un <div>)
  • L'application des styles est beaucoup plus complète et surtout, est prédictive.

Dans les exemples fournis avec GWT, le positionnement est fait de deux manières :

  • Soit avec les nouveaux composants LayoutPanel pour les mises en pages compliquées (SplitBar, Layout North East West South, Stack Panel...)
  • Soit avec des HtmlPanel, dans les lesquels ont mets des <div>, et qu'on positionne via CSS.

J'avoue être convaincu par cette approche qui permet de positionner simplement et efficacement les composants. Dans notre projet, nous allons migrer vers ce nouveau système en même temps que le refactor des CSS.

Le UI binder

GWT 2 permet de décrire les interfaces en XML au lieu d'écrire plein de code Java. Concrètement, au lieu de faire plusieurs lignes new VerticalPanel, new HorizontalPanel, add, add, add... on écrit un fichier XML qui décrit cet agencement. Or notre application contient déjà beaucoup d'interfaces, décrite en Java... Donc ?

  • Pour moi, on ne gagne rien en terme de modularité / expressivité par rapport à du Java. C'est tout aussi verbeux (ou quasiment), plus difficile à maintenir (le Java est beaucoup plus outillé que le XML, notamment pour le refactoring)
  • Un des avantages de GWT est que tout est en Java & CSS : pas de HTML, pas de Javascript. Le UI Binder impose de ré -introduire du XML : cela fait un troisième language, cela n'est pas forcément une bonne idée pour la maintenance.
  • Dès que l'interface devient complexe et dynamique, on ne pourra plus utiliser ce système, il faudra écrire l'IHM en Java. Comme en Flex, on peut donc décrire l'interface soit en XML (déclaratif), soit en ActionScript (programmatif). Le language du UI Binder est cependant loin d'avoir l'expressivité du XML de Flex : il n'y a notamment pas de mécanisme de binding automatique de propriétés de composant graphique sur des variables du code.
  • L'apport du UI Binder est de séparer explicitement la description de l'interface du code associé. Cela est effectivement plus propre au niveau architecture applicative. Cependant, dans notre projet, nous avions déjà fait cette séparation au niveau du code Java. Cela n'est certes pas aussi joli, mais c'est déjà satisfaisant.

Migrer vers le UI Binder pour du code existant ne me paraît donc pas pertinent. Si l'on démarre un nouveau projet ou que l'on ait à développer de toutes nouvelles IHM, UI Binder permettra effectivement une meilleure productivité. Espérons que GWT 2.1 contiendra [enfin] un mécanisme de binding, comme en Flex.

Les tests

Hélas, GWT 2 n'apporte pas grand chose au niveau des tests. La seule différence est que GWTTestCase n'est plus plateforme-dépendant. HtmlUnit est utilisé par GWTTestCase, au lieu du navigateur embarqué dans l'ancien Hosted Mode. D'après ce que j'ai pu essayer (je n'y ai pas consacré beaucoup de temps), les tests sont plus lents qu'avant (en local sur Mac du moins). La solution que nous avons mis en place (ce framework, décrit ici), est donc toujours, à mon avis, pertinente. Nous allons donc porter notre framework de test vers GWT 2, ce qui devrait ne pas être trop compliqué.

Les autres nouveautès

Il y a d'autres nouveautés : optimisation du compilateur (on gagne 30K sur 970K de Javascript), outil pour détecter les problèmes de performances, compilation "draft" pour accélérer l'intégration continue ...

A-t-on vraiment le choix ?

En fait, non :-( La branche 1.7 n'est plus maintenue. Le fait de choisir GWT comme framework de développement implique que l'on choisisse également de suivre les versions, puisque les anciennes branches ne sont pas maintenues. On ne peut donc pas bénéficier ni des corrections de bugs, ni du support des nouveaux navigateurs, ni évidemment des nouvelles fonctionnalités... La seule chose que l'on contrôle, c'est le moment où l'on fait la migration. Cela n'enlève cependant rien au fait que la migration doit être évaluée en terme d'apport et de coût. A terme, il faut la faire.

Combien cela va t'il me coûter

Après cette brève présentation des nouveautés, revenons à nos questions. Combien cela va t il me coûter ? Et bien cela dépend de quoi on parle :

  • Utiliser GWT 2.0 au lieu de 1.7.1 : le coût est quasiment nul. J'ai changé la version de GWT dans le pom, l'application se lance dans l'environnement de développement sans aucune modification, elle compile, est déployable et fonctionne normalement. Il y a quelques coûts indirects :
    • Quelques modifications mineures sont à apporter à l'environnement de développement (installation des nouveaux plugins, modifications de quelques classes utilisées pour le développement (nous n'utilisons pas le plugins Eclipse pour GWT))
    • Même si l'application fonctionne, quelques warnings apparaissent dans l'application dus à des API dépréciées. Il faudra donc les corriger.
    • Nous ne pouvons pas migrer vers GWT 2 le temps que le framework de test n'a pas été porté. Etant Open Source, je n'inclus pas le coût de ce portage dans le coût de migration
    • Attention, si votre application utilise GWT 1.5.x ou antérieur, des APIs ont été modifiées. Je vous conseille donc de passer sous GWT 1.7, de corriger tous les warnings, puis de migrer vers GWT 2.
  • Coût pour utiliser proprement le nouveau système de CSS : 2 semaines de travail pour un développeur. C'était un chantier déjà identifié, la venue de GWT 2 ne fait qu'apporter une solution plus propre pour le faire. Ayant déjà des douleurs avec les CSS et GWT 1.7, ce coût là ne fait donc pour moi pas partie du coût de migration. Par contre, la migration vers GWT 2 permet d'améliorer le ROI du refactor des CSS, en utilisant les nouvelles fonctionnalités.
  • Coût pour utiliser le code splitting, c'est pour moi un chantier indépendant de la migration GWT 2. Mais nous allons devoir le faire, notre Javascript devient trop gros. Cela ne devrait prendre que quelques jours.

Si l'on part du principe que le framework de test est compatible GWT 2, le coût de migration est donc marginal. On peut donc bénéficier facilement des améliorations au niveau du développement (nouveau DevMode), et ensuite progressivement refactorer le code pour utiliser les nouvelles fonctionnalitées (notamment CSS)

Comment vendre ce coût à ma MOA ?

Vu de la MOA (ou du client final), GWT 2 n'apporte ... rien. Cependant, comme le coût de migration est faible et étant donné que cela apporte pas mal de choses aux développeurs, cela ne devrait pas être trop difficile à négocier. Surtout vu le bénéficie prévisible en terme de maintenance CSS.

D'après l'équipe de GWT 2, cette version était effectivement consacrée au développeurs. Les versions suivantes devraient elles être consacrée aux utilisateurs. A suivre ...