Ook vandaag blijft het schrijven van Rich Internet Applications een vervelend en foutgevoelig proces. Ontwikkelaars worstelen het grootste deel van hun tijd met de eigenaardigheden van browsers. Bovendien is het bouwen, hergebruiken en onderhoud van grote JavaScript libraries en AJAX-componenten zeer moeilijk. Google Web Toolkit (GWT) wil dit makkelijker maken door heel complexe maar ook erg performante JavaScript front-end-toepassingen in Java te schrijven.

Met Google Web Toolkit schrijf je dus AJAX front-end code in Java, die vervolgens wordt gecompileerd in extreem geoptimaliseerde JavaScript code, die op zijn beurt automatisch geschikt is voor gebruik in alle grote browsers. De compiler zelf elimineert ‘dode code’, snoeit aggressief in ongebruikte classes, methodes, variabelen en zelfs methode parameters, en kan ook methodes ‘inlinen’ waar nodig. Het resultaat is compacte JavaScript code die sneller kan draaien dan handgeschreven code.

Als ontwikkelaar met GWT werk je overwegend in zogenaamde ‘hosted mode’, wat in wezen een gesimuleerde browseromgeving is waarin je niet met de gecompileerde JavaScript code maar recht-streeks met de Java code werkt. Dit betekent dat je volop kan genieten van alle beschikbare IDE debugfaciliteiten en dat voor zowel de GWT client code als de server side code.

Maar de Google Web Toolkit heeft legio voordelen en wil meer zijn dan ‘zomaar’ een web frame-work voor Java-ontwikkelaars. De bouwers van GWT durven stellen dat hun hoogste prioriteit een maximale eindgebruikerservaring is. Dit artikel belicht de kracht en de visie van GWT aan de hand van een aantal gebruikersvoorbeelden.

De eerste indruk telt

De hotelportier die met een glimlach de deur voor je opendoet. Het hondje in de kennel dat je aankijkt met zijn puppy-oogjes. Het moment dat je de iPhone-verpakking eraf haalt. Telkens en telkens weer gaat om één ding: de eerste indruk.

Rich Internet Applications vormen hierop geen uitzondering en de gebruikers ervan zullen die toepassingen dan ook op hun eerste indruk beoordelen. Met als logische vraag: hoe kan die zo positief mogelijk zijn? Wat zijn de cruciale factoren die hierbij spelen?

Jakob Nielsen, een autoriteit op het vlak van ‘usability design’, bestudeert ‘web usability’ al sinds 1995 en concludeert dat de gebruikers nog steeds met dezelfde klachten zitten als toen. Webpagina’s moeten veel sneller worden ingeladen en afgebeeld op het scherm! Het ‘manifesto’ van de Google Web Toolkit verklaart dan ook “de webervaringen van gebruikers radicaal te verbeteren door ontwikkelaars in staat te stellen bestaande Java-tools aan te wenden voor het bouwen van compromisloze Ajax-code voor eender welke moderne ‘browser’.”

Als oorzaken voor te trage pagina’s kan worden gekeken naar drie knelpunten: het downloaden van de resources, het uitvoeren van startup code (JavaScript) en het weergeven van de opmaak.

Internet resources brengen een aantal problemen met zich mee. Http roundtrips beïnvloeden de snelheid, kleine resources zijn ‘latency’ intensief,

Vervolgens moet de JavaScript code die nodig is voor de initialisatie van de pagina, worden uitgevoerd. Een stap waar zoveel mogelijk ‘lazy loading’ van applicatie-onderdelen geen overbodige luxe blijkt te zijn. Voorts werkt een specifiek JavaScript statement niet systematisch in alle browseromgevingen, en dat is goed voor heel wat bijkomende lijnen code om in de behoeften van alle browsers te voorzien. Lijnen code die helaas ook allemaal worden doorgestuurd, zodat je als Firefox-gebruiker dus ook de Internet Explorer-specifieke code op je brood krijgt!

De laatste stap, in casu het ‘renderen’, zeg maar het creëren van de pagina op basis van DOM manipulaties, biedt dezelfde problemen als de vorige stap. DOM manipulaties zijn immers browserspecifiek en mocht je trouwens overal dezelfde JavaScript code gebruiken, duiken geheid drastische performantieverschillen op. De creatie van een DOM element kan bijvoorbeeld al snel op zeven verschillende wijzen worden geïmplementeerd. De Rich Internet Application ontwikkelaar moet dan ook de code voor elke browser optimaliseren, een klus die je niemand toewenst. En heb ik dan al iets gezegd over het verschillende gedrag van de verschillende versies van een zelfde browser? Evenals in de vorige stap moet ook nu weer de gebruiker de code voor alle browsers downloaden.

Tips om het beter te doen

Met dit alles in het achterhoofd kunnen we al snel concluderen dat onze werkwijze drastisch moet worden gewijzigd als we een optimale ervaring door de gebruiker beogen. Ik zet een aantal tips op een rijtje. Zo moet het aantal http requests worden gereduceerd door het aantal resources te verminderen. Cache de resources tot de zon ontploft! Werk cross browser, cross platform. Beoog een minimum aan usability compromissen die het gevolg zijn van code-implementaties en ga voor extreme JavaScript optimaliseringen.

Om aan die eisen tegemoet te komen, trekt de GWT compiler een lijn tussen de onderhoudbaarheid van de applicatie en efficiëntie van de executable.

Handgeschreven JavaScript code lijdt onder tegenstrijdige belangen. Lange en handige identifiers, mooi geformatteerde code en nuttig commentaar resulteren immers in grotere en tragere applicaties. Door de Java-code in te voeren in de JavaScript compiler kan worden gezorgd voor een ‘zero cost ab-stract’.

Voorts is de feedback van gebruikers en bruikbaarheidstesten van cruciaal belang voor het ontwerpen van gebruikersinterfaces. Je slaagt er nooit in meteen de optimale interface te bouwen, wel integendeel. Het is dan ook van groot belang vlot een aantal iteraties te kunnen doorlopen. Dat vereist dan weer tools waarmee op grote schaal aan ‘refactoring’ kan worden gedaan, met ook hier weer problemen voor JavaScript. JavaScript is uitermate moeilijk om te refactoren, zodat zorgen betreffende onderhoudbaarheid de kop opsteken, wat dan weer de druk opvoert om het meteen, vanaf de eerste keer goed te ontwerpen (frame-work-itis).

Een GWT compilatie resulteert in extreem geoptimaliseerde JavaScript executables, waarbij elke executable exact voorziet in een specifieke gebruikersbehoefte. Zo zal er een executable zijn voor de toepassing op Firefox (user agent) in het Nederlands (locale), een andere executable voor die toepassing op Firefox in het Engels, nog een andere op IE in het Nederlands enzovoort. Voor elke unieke combinatie in gebruikersbehoeftes bestaat er een JavaScript executable. Deze techniek staat binnen GWT bekend als deferred binding. Tenslotte worden alle browserspecifieke implementaties geabstraheerd en transparant ter beschikking gesteld aan de Java-ontwikkelaar.

Executables zijn geen standaard .js maar .cache.html bestanden voorzien van een UUID in de naamgeving. Deze tactiek laat toe de resource te cachen tot de zon ontploft en faalt nooit bij het ophalen van nieuwere versies. Er moet nooit worden gevraagd of het bestand is geüpdatet, en er is zelfs geen If-Modified-Since check nodig. Maar hoe weet de browser nu welke JavaScript executable hij moet downloaden? Naast de executables wordt ook een selectiescript gegenereerd (vergelijkbaar met een bootscript) waarin alle mogelijke gebruikerspecifieke combinaties (user agent, locale, …) staan vermeld. De browser haalt dit script binnen, waarna het script de correcte executable selecteert om te downloaden of uit de lokale cache te halen. Schijfruimte is immers goedkoop, bandbreedte en de tijd van de bezoeker zijn dat niet!

Tenslotte en allicht nog het meest magische aspect, wordt er in elke nieuwe versie van GWT gesleuteld aan de optimalisatie van de gecompileerde JavaScript code. Dat betekent steeds snellere applicaties zonder dat de ontwikkelaar ook maar iets hoeft te doen. Zo zijn er releases geweest waarbij tot 50 procent aan performantiewinst werd geboekt.

Hoffelijke dienst

De kelner die spontaan je wijnglas bijvult. De hotelportier die als je buitenkomt onmiddellijk een taxi voor je wenkt. Als gebruiker, als mens worden we graag in de watten gelegd en liefst zonder dat we er zelf moeten om vragen. Op kantoor brengen we vaak het merendeel van onze tijd voor onze computer door, en het is dan ook logisch om het de gebruiker zo comfortabel mogelijk te maken.

Er zijn heel wat punten waarop Rich Internet Applicaties verschillen van klassieke webtoepassingen. ‘Live search’ in plaats van de traditionele paginazoekacties, formuliervalidatie terwijl je typt, het automatisch aanvullen van gegevens – er is duidelijk een trend om de gebruiker zo weinig mogelijk onnodige handelingen te laten verrichten.

Vanuit een technisch standpunt bekeken, betekent dit de nood om uiterst event driven en snel te werken. GWT biedt een zeer uitgebreid ‘listener interface model’, dat events uit zowel widgets als DOM elementen aankan. Om de gebruiker snel van de gewenste data te voorzien, voorziet GWT ‘out-of-the-box’ al in tal van communicatieprotocollen, zoals uiteraard HTTP (JSON en XML) maar ook GWT-RPC (een uiterst geoptimaliseerde vorm van traditionele RPC calls).Rich Internet Applicaties onderscheiden zich van traditionele html-gesteunde webtoepassingen omdat ze geen html-pagina’s moeten inladen maar alleen de data die de gebruiker nodig heeft. Het voordeel van een GWT-gesteunde architectuur is dan weer dat deze zorgt voor een volledige ontkoppeling tussen client en server, zodat servers volledig stateless kunnen werken en de ‘conversational state’ op de client wordt bijgehouden – een architectuur met bijzonder groot doorgroeipotentieel. Naast deze basisarchitectuur biedt GWT ook tal van gevanceerde mogelijkheden als het inbedden van gepreserialiseerde data. Met deze techniek kan het resultaat van een initiële RPC call meteen worden ingebed in de opstartpagina die door het clientsysteem wordt ingeladen – een soort turboboost van de opstart van de applicatie.

Personaliseren en ‘customisation’

De barman die zich je favoriete drankje herinnert. De spelfiguren van je WII. De koffie bij Starbucks, precies zoals je hem lust. We leven in een wereld waar het personaliseren van goederen en diensten vanzelfsprekend wordt. In de digitale wereld betekent dit dat de gebruiker zijn favoriete webapplicatie kan gebruiken op zijn desktop, laptop, pda, gsm, smartphone, en zelfs offline. De jongste generatie van online-gebruikers durft de lat nog hoger te leggen door een toepassing ook nog eens als een ‘widget’ in een OpenSocial container te draaien, een opgave waarvoor traditionele webtoepassingen helemaal moeten voor bedanken. Concreet biedt de Linker – een subsysteem van de GWT compiler – de mogelijkheid om een in Java geschreven toepassing naar verschillende platformen te compileren en voorziet in alle integratiebehoeften van RIA’s. Ook het off-line beschikbaar maken van een toepassing was nog nooit zo simpel en kan door het toevoegen van één lijntje in de GWT-configuratie.

Het zit hem in de details

Of je nu een auto koopt, een boek of een taart, het zijn de details die onze keuze beïnvloeden.

Rich Internet Applications mogen dan een nieuwe wijze van werken bieden door een toepassing volledig in de browser te draaien, toch kunnen een aantal oude gewoonten bij de gebruikers niet worden genegeerd. Gewoonten die niet altijd met doorsnee RIA’s kunnen worden ondersteund, zoals het ‘bookmarken’ van webpagina’s. Ajax-applicaties zijn event-driven en voorzien daardoor niet in de ‘bookmark’-behoefte. Een JavaScript actie die data van de server haalt en deze op het scherm afbeeldt, verandert de huidige URL niet – state en URL zijn niet langer een 1-op-1 gemapt. Dat probleem zorgt ervoor dat ook de terugknop niet kan worden gebruikt (als het niet zeker is dat na een actie ook de URL wijzigt, kan het gebruik van de terugknop de toepassing in een foute staat brengen). De GWT biedt echter in tegenstelling tot het Ajax-framework ondersteuning om toch in te haken op het ‘history system’. Concreet kunnen ontwikkelaars dan ook op transparante wijze ‘history tokens’ koppelen aan bepaalde acties. Kortom, GWT biedt alle voordelen van een AJAX-toepassing, zonder de nadelen ervan. GWT kun je niet vergelijken met traditionele webframeworks, noch met concurrerende AJAX libraries. Een nieuwe wereld die voor je opengaat!

Maarten Volders

Fout opgemerkt of meer nieuws? Meld het hier

Partner Content