Le titre est un peu racoleur je vous l’accorde mais l’objectif de ce billet est plutôt de se familiariser avec 3 façons de faire du RIA et de les comparer au travers d’un composant central d’une application : le grid.
Je me suis donc employé à recréer un écran simple contenant un label, un bouton et un grid.

En cliquant sur le bouton on charge dans le grid un nombre variable d’enregistrements et on affiche dans le label le temps nécessaire en secondes pour ce chargement. Le test à été réalisé avec 10, 50, 100, 500 et 1000 enregistrements.
Les temps sont mesurés à la fois dans Internet Explorer 7 et dans Firefox.
Dans un souci de transparence j’ai également effectué les mesures avec Rialto.
FLEX
J’ai tout d’abord essayé l’environnement d’Adobe. Après s’être créé un compte, il faut télécharger et installer Flex Builder 3
Ensuite tout est assez intuitif de la création de projet, à l’exécution de notre fichier mxml de test.
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.rpc.events.ResultEvent;
[Bindable]
private var gamesData:ArrayCollection;
private function initDataGridData():void
{
var gamesData:ArrayCollection = new ArrayCollection();
var date=new Date();
var start = date.getTime();
for (var i=0;i<10;i++){
gamesData.addItem({ID: i, Data1: start, Data2: "Data2"});
}
grid.dataProvider = gamesData;
date = new Date;
var end = date.getTime();
var sec = (end-start)/1000;
lab.text="Load in:"+sec;
}
]]>
</mx:Script>
<mx:Button y="10" x="400" click="initDataGridData()" label="load"/>
<mx:Label x="490" y="10" id="lab"
text="Wait:"
fontSize="16" fontWeight="bold"/>
<mx:DataGrid id="grid" x="10" y="5"
width="300" height="250" selectedIndex="0">
<mx:columns>
<mx:DataGridColumn dataField="ID" headerText="ID" width="100"/>
<mx:DataGridColumn dataField="Data1" headerText="Data1" width="100"/>
<mx:DataGridColumn dataField="Data2" headerText="Data2" width="100"/>
</mx:columns>
</mx:DataGrid>
</mx:Application>
La documentation est assez claire.
Avec Flex le rechargement du Grid se fait en modifiant la propriété dataProvider du composant.
grid.dataProvider = gamesData
Ext js
Pour réaliser les test dans un environnement javascript j’ai opté pour la librairie la plus en vue du moment (en bien et en mal
)
J’ai utilisé Ext 2.0.2. Je trouve la prise en main un peu plus « compliquée ». Il faut un fichier HMTL qui contient les inclusions des différents fichiers js et css nécessaires à Ext. Puis on crée un fichier javascript contenant le code de notre application.
Ext.onReady(function() {
var oData=new Array;
for (var i=0;i<1000;i++){
oData.push([i,"data1","data2"]);
}
Ext.get('myButton').on('click', function(){
var date = new Date;
start = date.getTime();
var d =new Ext.data.Store({data:oData,reader: myReader});
grid.reconfigure(d,grid.getColumnModel());
date = new Date;
end = date.getTime();
var sec = (end-start)/1000;
var myDiv = Ext.get('lab');
myDiv.dom.innerHTML="Load in: "+sec;
});
var myData = [['','','','']];
var myReader = new Ext.data.ArrayReader({}, [
{name: 'id'},
{name: 'd1'},
{name: 'd2'}
]);
var grid = new Ext.grid.GridPanel({
store: new Ext.data.Store({
data: myData,
reader: myReader
}),
columns: [
{header: 'ID', width: 100, sortable: true, dataIndex: 'id'},
{header: 'Data1', width: 100, sortable: true, dataIndex: 'd1'},
{header: 'Data2', width: 100, sortable: true, dataIndex: 'd2'}
],
viewConfig: {
forceFit: false
},
renderTo: 'content',
title: 'My First Grid',
width: 300,
height: 300,
frame: true
});
grid.getSelectionModel().selectFirstRow();
});
La documentation est très bien faite et on sent la richesse du composant. Par contre pour une utilisation simple le code devient lourd à manipuler.
Le rechargement du Grid se fait en modifiant l’objet Store et en appelant la méthode reconfigure
var d =new Ext.data.Store({data:oData,reader: myReader});
grid.reconfigure(d,grid.getColumnModel());
GWT-Ext
Au départ je voulais tester l’environnement GWT uniquement mais le composant Grid natif est trop simple et s’apparente plus à un simple tableau HTML. J’ai donc testé le composant Grid dans le wrapping GWT-Ext. Le code ressemble donc beaucoup à celui indiqué ci-dessus.
Panel panel = new Panel();
panel.setBorder(false);
panel.setPaddings(15);
lab=new Label("Load");
panel.add(lab);
Button but = new Button("Load", new ButtonListenerAdapter() {
public void onClick(Button button, EventObject e) {
Date now = new Date();
long start = now.getTime();
//treatment
Object[][] data = getData(1000);
MemoryProxy proxy = new MemoryProxy(data);
ArrayReader reader = new ArrayReader(recordDef);
Store store = new Store(proxy, reader);
store.load();
grid.reconfigure(store, columnModel);
now = new Date();
long end = now.getTime();
float sec = (new Float((end-start)).floatValue())/1000;
lab.setText("Load in: "+sec);
}
});
panel.add (but);
recordDef = new RecordDef(
new FieldDef[]{
new StringFieldDef("id"),
new StringFieldDef("data1"),
new StringFieldDef("data2")
}
);
grid = new GridPanel();
Object[][] data =new Object[][]{new Object[]{"", "", ""}};
//Object[][] data= getData(1);
MemoryProxy proxy = new MemoryProxy(data);
ArrayReader reader = new ArrayReader(recordDef);
Store store = new Store(proxy, reader);
store.load();
grid.setStore(store);
ColumnConfig[] columns = new ColumnConfig[]{
new ColumnConfig("ID", "id", 100),
new ColumnConfig("Data 1", "data1", 100),
new ColumnConfig("Data 2", "data2", 100)
};
columnModel = new ColumnModel(columns);
grid.setColumnModel(columnModel);
grid.setFrame(true);
grid.setStripeRows(true);
grid.setHeight(350);
grid.setWidth(600);
grid.setTitle("Array Grid");
panel.add(grid);
RootPanel.get().add(panel);
}
private Object[][] getData(int numberElmt) {
Object[][] data =new Object[numberElmt][2];
for (int i=0;i
Le site officiel regroupe des informations utiles, un très beau showroom , la documentation de l'API
Le principe de rechargement est bien sur le même qu’avec Ext js.
RESULTATS
Les temps sont indiqués en secondes.

Sans surprise Flex offre des résultats largement au dessus des autres mais n’oublions pas que nous comparons un langage compilé avec un langage interprété (même GWT au final s’exécute en javascript). Je suis plutôt surpris des résultats affichés par GWT que je voyais moins bon.
On note, comme souvent, de meilleurs résultats dans firefox que dans IE.
En tout cas un test très intéressant à faire pour appréhender les nouveaux acteurs du RIA de demain.

Zaccret
15 mai 2008 at 7:33
By the way, which version of Firefox did you use ?
Cyril Balit
15 mai 2008 at 8:17
The test was done with Firefox 2.0.0.14
Seb
23 mai 2008 at 16:06
tu n’as pas essayé en XUL???
Cyril Balit
23 mai 2008 at 16:31
non c’est vrai, je me suis limité à ces 3 environnements. question de temps libre aussi. J’aurais aussi pu le faire en silverlight.
yobo
14 septembre 2009 at 16:05
quid des résultats depuis le support javascript des navigateurs récents (chrome, firefox 3.5) ?
grisha
3 février 2010 at 22:23
l’écart devrait être réduit avec les nouveaux moteurs javascript des navigateurs.
de plus le test GWT est faussé car GWT-ext est « simplement » un « wrapper » de ext-js, ce n’est pas du javascript compilé et optimisé par GWT… Mais comme tu le dis, aurait fallu écrire un composant qui se rapproche des datatables de flex et ext-js.
PS : GWT-ext est devenu SmartGwt qui « wrappe » une autre librairie javascript (pbl de licence ext-js je crois). Ca à l’air complet, mais l’intéret de GWT est toujours aussi limité