Ar t e v e l de hog e s c hool Ca mpusMa r i a k e r k e I ndus t r i e we g232 9030Ge nt Ma r i a k e r k e
J a va S c r i pt f r a me wor ks E e nv e r g e l i j k e ndes t udi ev a ndebe k e nds t eJ a v a S c r i pt f r a me wor k s , a l s ookdei nv l oe d v a nhe tg e br ui ke r v a nopdeJ a v a S c r i pt c odedi ewe bont wi k k e l a a r ss c hr i j v e n I nt e r nepr omot or :AnnAude na e r t E x t e r nepr omot or : Kr i j nHoe t me r Ac a de mi e j a a r2008– 2009
E i ndwe r kv oor g e dr a g e ndoorMa t hi a sBy ne nst othe tbe ha l e nv a nhe tdi pl oma Ba c he l ori ndeGr a fis c hee nDi g i t a l eMe di a , a f s t ude e r r i c h ngMulme di a pr oduce .
Woord vooraf JavaScript en alles wat ermee te maken heeft, is duidelijk aan een soort revival bezig. In de wereld der weblogs, alsook op professionele congressen omtrent webontwikkeling is het meer en meer stof tot discussie. Ik meen dat het ontstaan van JavaScript-frameworks (samen met de Ajax-hype) hiervan de grootste oorzaak is. Dit wordt ook duidelijk bij het bekijken van de lijst met eindwerkonderwerpen van dit academiejaar: maar liefst drie studenten hebben een JavaScript-gerelateerd onderwerp. Jos De Berdt bespreekt het gebruik van geavanceerde JavaScript, terwijl Robin Venneman één enkel JavaScriptframework, namelijk jQuery, onder de loep neemt. Ikzelf voer een onderzoek naar het nut van JavaScript-frameworks, gecombineerd met een vergelijkende studie van de verschillende opties. Toen ik dit eindwerk schreef, werd al gauw duidelijk dat het eindresultaat vrij technisch zou worden. Ik begrijp dan ook dat dit document niet voor iedereen even vlot leesbaar is. Teneinde deze drempel ietwat te verkleinen, heb ik getracht moeilijke jargontermen steeds kort maar bondig te verklaren. Graag bedank ik mijn promotoren Ann Audenaert en Krijn Hoetmer. Zonder hun begeleiding en expertise was dit eindwerk nooit geworden tot wat het nu is. Verder richt ik mijn dank aan iedereen die ik in het kader van dit project met vragen heb bestookt, alsook aan enkele medestudenten voor de sporadische tips die ik van hen kreeg.
— Mathias Bynens
Eindwerk: JavaScript-frameworks
2
Mathias Bynens
Inhoudsopgave Woord vooraf ............................................................................................................................. 2 Inhoudsopgave ........................................................................................................................... 3 Lijst van gebruikte (niet-geijkte) afkortingen ............................................................................. 5 Inleiding ...................................................................................................................................... 7 1.
2.
3.
4.
5.
Wat is JavaScript? ............................................................................................................... 8 1.1.
Definitie .................................................................................................................... 8
1.2.
Geschiedenis ............................................................................................................ 9
1.3.
Verdere info ........................................................................................................... 10
Wat is een JavaScript-framework?................................................................................... 11 2.1.
Definitie van ‘framework’ ...................................................................................... 11
2.2.
Definitie van ‘JavaScript-framework’ ..................................................................... 11
Voordelen van JavaScript-frameworks ............................................................................ 12 3.1.
Cross-browser-compatibiliteit ............................................................................... 12
3.2.
Eenvoudige selectie van DOM-elementen ............................................................ 13
3.3.
Hergebruik van code .............................................................................................. 16
3.4.
Onderhoudbaarheid van code ............................................................................... 16
3.5.
Klasse-gebaseerde overerving ............................................................................... 17
Nadelen van JavaScript-frameworks ................................................................................ 18 4.1.
Bestandsgrootte ..................................................................................................... 18
4.2.
Performantie .......................................................................................................... 19
4.3.
Kennis van JavaScript ............................................................................................. 20
Vergelijkende studie van JavaScript-frameworks ............................................................ 21 5.1.
Selectie van frameworks ........................................................................................ 21
5.2.
Vergelijkingscriteria ............................................................................................... 23
5.2.1.
Gebruikte techniek ......................................................................................... 23
Eindwerk: JavaScript-frameworks
3
Mathias Bynens
5.2.2.
Functionaliteit & gelaagd bouwen ................................................................. 26
5.2.3.
Community ..................................................................................................... 29
5.2.4.
CSS selector engine......................................................................................... 29
5.2.5.
Licentie............................................................................................................ 31
5.2.6.
Bestandsgrootte ............................................................................................. 32
5.3.
5.3.1.
Prototype & script.aculo.us ............................................................................ 33
5.3.2.
MooTools & moo.fx ........................................................................................ 35
5.3.3.
jQuery & jQuery UI ......................................................................................... 38
5.3.4.
The Dojo Toolkit.............................................................................................. 42
5.3.5.
YUI (Yahoo! UI Library) ................................................................................... 44
5.4.
6.
Individuele analyse ................................................................................................ 33
Onderlinge vergelijking .......................................................................................... 48
5.4.1.
Vergelijking op basis van bestandsgrootte ..................................................... 48
5.4.2.
Performantie van CSS selector engines .......................................................... 49
Conclusie .......................................................................................................................... 52
Bronnenlijst .............................................................................................................................. 53 Bijlagen ..................................................................................................................................... 60
Eindwerk: JavaScript-frameworks
4
Mathias Bynens
Lijst van gebruikte (niet-geijkte) afkortingen Ajax
Asynchronous JavaScript And XML, een term voor de ontwikkeling van interactieve webpagina’s waarin op asynchrone wijze met de webserver gecommuniceerd wordt. Hierdoor hoeven pagina’s niet in hun geheel ververst te worden. (Vaak foutief geschreven als ‘AJAX’. Het is weliswaar een afkorting, maar Ajax wordt enkel met beginhoofdletter geschreven!)
API
Application Programming Interface. Dit is een verzameling definities op basis waarvan een computerprogramma kan communiceren met een ander programma of onderdeel (meestal in de vorm van bibliotheken).
ARIA
Accessible Rich Internet Applications. Dit is het principe om webapplicaties, die intensief gebruikmaken van scripting, alsnog accessible of toegankelijk te maken.
CSS
Cascading Style Sheets. Dit is een computertaal die het mogelijk maakt om de vormgeving van een webpagina vast te leggen op basis van de opbouw van de HTML-code.
CPU
Central Processing Unit, de Engelse term voor ‘centrale verwerkingseenheid’ of ‘processor’.
DOM
Document Object Model. Dit model is een objectgeoriënteerde benadering van gestructureerde documenten, zoals (X)HTMLbestanden.
GUI
Graphical User Interface, de Engelse term voor ‘grafische gebruikersomgeving’.
JS
JavaScript. Zie het hoofdstuk “Wat is JavaScript?” (vanaf pagina 8) voor meer uitleg.
JSON
JavaScript Object Notation. Dit is een dataformaat binnen de programmeertaal JavaScript. Het wordt gebruikt voor het uitwisselen van datastructuren in webapplicaties die asynchroon gegevens ophalen van de webserver (zoals met Ajax).
Eindwerk: JavaScript-frameworks
5
Mathias Bynens
OOP
Object-Oriented Programming, oftewel objectgeoriënteerd programmeren. Bij deze benadering wordt een systeem opgebouwd uit objecten, waarbij ieder object gemaakt is vanuit de definitie van een klasse of een prototype.
PHP
PHP: Hypertext Preprocessor (recursief acroniem). Dit is een serverside scriptingtaal waarmee dynamische webpagina’s gemaakt kunnen worden.
RIA
Rich Internet Application, een interactieve internetapplicatie die overkomt als een desktopprogramma, doordat ze zonder andere webpagina’s te openen, respons geeft op de ingevoerde gegevens.
(X)HTML
(Extensible) HyperText Markup Language. Dit zijn de twee meestgebruikte opmaaktalen waarin webpagina’s geschreven worden.
KB, kB, K
Een kilobyte is een maat om bestandsgrootte uit te drukken, en omvat 1000 bytes.
KiB
Een kibibyte is 1.024 bytes.
MB
Een megabyte is 1.000.000 bytes of 106 bytes. Dit komt overeen met 1.000 KB.
MiB
Een mebibyte is 1.0242 bytes oftewel 220 bytes. Dit komt overeen met 1.048.576 bytes, ofwel 1.024 KiB.
GB
Een gigabyte is 1.000.000.000 bytes of 109 bytes. Dit komt overeen met 1.000 MB.
GiB
Een gibibyte is 1.0243 bytes oftewel 230 bytes. Dit komt overeen met 1.073.741.824 bytes, ofwel 1.024 MiB.
TB
Een terabyte is 1.000.000.000.000 bytes of 1012 bytes. Dit komt overeen met 1.000 GiB.
TiB
Een tebibyte is 1.0244 bytes oftewel 240 bytes. Dit komt overeen met 1.099.511.627.776 bytes, ofwel 1.024 GiB.
Eindwerk: JavaScript-frameworks
6
Mathias Bynens
Inleiding Fronteers is een Nederlandse vakverening voor webontwikkelaars, met als hoofddoelstelling de professionalisering van het beroep front end web developer. Daarbij wordt gestreefd naar erkenning, verbetering en ondersteuning van de (positie van) Nederlandse webontwikkelaars. Hiertoe organiseren zij onder meer een jaarlijks congres. In 2008 vond dit plaats op 11 en 12 september. Gezien mijn interesse voor webontwikkeling alsook de waslijst aan beroemde sprekers van o.a. Yahoo!, Microsoft en het W3C, was ook ik van de partij. Het beloofde een interessante tweedaagse te worden. Maar liefst zes van de zestien sessies bleken over JavaScript te gaan! Alle andere aspecten van front-endontwikkeling (HTML, CSS), alsook algemene onderwerpen zoals professionalisme, onderhoudbaarheid van code en de verschillen tussen internetbrowsers, werden dus verspreid over tien sessies in totaal. Na die twee dagen besefte ik dat JavaScript, nu meer dan ooit, een hot topic is. Het lijkt misschien vreemd dat een scriptingtaal die al sinds 1995 bestaat nu pas zo’n grote populariteit kent. Dit is echter eenvoudig te verklaren door de opkomst van de zogenaamde JavaScript-frameworks. Tijdens zijn presentatie deed Tom Occhino (bekend van MooTools) de uitspraak dat er per JavaScript-ontwikkelaar gemiddeld zo’n 1.2 frameworks beschikbaar zijn. Aangezien ik persoonlijk zeer geïnteresseerd ben in front-end-ontwikkeling (en JavaScript in het bijzonder), leek het mij boeiend om dieper in te gaan op dit relatief nieuwe fenomeen, eens uit te zoeken wat nu precies de voor- en nadelen van deze frameworks zijn, en waarom er zo’n overaanbod is. Verschillen deze JavaScript-libraries dan werkelijk zo veel? Zijn er enkel voordelen verbonden aan het gebruik van frameworks, of kan dit ook nadelen met zich mee brengen? Hoe beïnvloedt het gebruik van frameworks de taak van JavaScriptontwikkelaars? Welk framework zou ik gebruiken voor een doordeweekse website? Verandert deze keuze indien ik een RIA wil bouwen? In dit eindwerk tracht ik door theoretische studie en praktisch onderzoek deze en andere vragen te beantwoorden. Voor dit laatste ga ik op zoek naar meetbare vergelijkingspunten tussen verschillende JavaScript-frameworks. Dit omvat een analyse van bestandsgrootte alsook performantietests van de gebruikte CSS selector engines door middel van benchmarks.
Eindwerk: JavaScript-frameworks
7
Mathias Bynens
1.
Wat is JavaScript?
1.1. Definitie Wikipedia omschrijft JavaScript als een dynamische, weakly typed, op prototypes gebaseerde objectgeoriënteerde scriptingtaal met ondersteuning voor first-class functions die gebruikt wordt voor client-side webontwikkeling. Dat zijn heel wat moeilijke termen in één zin. Laten we ze even stuk voor stuk overlopen. Een dynamische programmeertaal is een programmeertaal die bij het uitvoeren van een script gedragingen uitvoert die andere, niet-dynamische programmeertalen tijdens het compilen zouden verrichten. JavaScript is met andere woorden dynamisch omdat de code niet gecompileerd moet worden, maar gewoon rechtstreeks geïnterpreteerd wordt telkens het script draait. JavaScript ondersteunt weak typing, hetgeen wil zeggen dat nieuwe variabelen gedeclareerd kunnen worden zonder er een type aan te koppelen. Bovendien kan het type van een bestaande variabele veranderen door er een operatie op uit te voeren. Bij programmeertalen die met strong typing werken, is dit niet het geval. Om dit te verduidelijken, deel ik graag volgend voorbeeld met u: var foo; // de variabele foo wordt aangemaakt, het type is nog onbekend foo = 'bar'; // de variabele foo bevat nu een string document.writeln(typeof(foo)); // 'string' foo = foo * 1.0; // na vermenigvuldiging wordt het variabeletype number document.writeln(typeof(foo)); // 'number' var bar = false; // de variabele bar wordt aangemaakt document.writeln(typeof(bar)); // 'boolean'
Prototype-based programmeren is een stijl van objectgeoriënteerd programmeren waarbij klasses niet gebruikt worden. Het hergebruik van gedragingen (gekend als ‘overerving’ in class-based programmeertalen) gebeurt hierbij door bestaande objecten, die als prototypes fungeren, te klonen. Doordat JavaScript met prototypes werkt, kan je zeer eenvoudig extra functionaliteit toevoegen door de reeds bestaande prototypes uit te breiden. In het volgende voorbeeld breiden we het String-prototype uit met de functie corrigeerSpelling(). String.prototype.corrigeerSpelling = function() { return this.replace('fautje', 'foutje'); };
Eindwerk: JavaScript-frameworks
8
Mathias Bynens
Nadien kan deze functie zonder meer op alle strings worden toegepast; ook op strings die aangemaakt zijn voor de corrigeerSpelling()-functie bekend was. document.writeln('In deze zin staat een fautje.'.corrigeerSpelling()); // 'In deze zin staat een foutje.'
JavaScript kent drie soorten objecten: native objects (ingebouwde objecten), host objects (objecten die door de omgeving van de cliënt gedefinieerd worden), en user-defined objects (objecten die de JavaScript-programmeur zelf omschrijft). Aangezien alle objecten in JavaScript prototype-gebaseerd zijn, kunnen deze allemaal aangepast / uitgebreid worden. Deze mogelijkheid (het aanpassen van prototypes van native en zelfs van host objects) maakt JavaScript een erg flexibele, uitbreidbare taal. Veel frameworks maken hier dan ook gebruik van. Andere libraries blijven hier dan weer zo ver mogelijk vandaan, omdat dit een vrij controversiële techniek is. Hierover later meer (zie “Gebruikte techniek” op pagina 23). JavaScript is een objectgeoriënteerde taal omdat ze is opgebouwd uit objecten, waarbij ieder object gemaakt is vanuit de definitie van een prototype. (Vele andere objectgeoriënteerde talen werken met klassen in plaats van prototypes.) Een programmeertaal die first-class functions ondersteunt, zoals JavaScript, laat toe om nieuwe functies of methodes te creëren terwijl de code wordt geïnterpreteerd, om die functies in datastructuren op te slaan, om ze als argumenten door te geven aan andere functies, en om ze terug te geven als resulterende waarden van andere functies. Client-side webontwikkeling is de ontwikkeling van code die op de machine van de cliënt of eindgebruiker gelezen en geïnterpreteerd zal worden. Dit omvat (X)HTML, CSS en JavaScript. Hiernaast zijn er ook server-side programmeertalen, zoals PHP of ASP.NET. Deze code wordt op serverniveau geïnterpreteerd; de eindgebruiker merkt hier niets van. Ik denk dat na deze uitleg mijn definitie van JavaScript wel duidelijk is. 1.2. Geschiedenis De eerste versie van JavaScript werd in 1995 ontwikkeld door Brendan Eich (foto) van Netscape Communications Corporation voor gebruik in de Netscape Navigator-browser. Aanvankelijk was de naam Mocha en vervolgens LiveScript. De taal werd hernoemd tot JavaScript in de tijd dat in de Netscape-browser ook ondersteuning voor Java-applets werd ingebouwd. Hierdoor wordt JavaScript helaas nog steeds vaak verward met Java. De namen zijn misschien gelijkaardig, en ook de syntaxis van
Eindwerk: JavaScript-frameworks
9
Mathias Bynens
beide programmeertalen vertoont weliswaar enige overeenkomsten, maar daar houdt de gelijkenis op. Netscape heeft, in een poging om JavaScript als een officiële norm erkend te krijgen en er toch zelf voldoende zeggingskracht over te behouden, de taal laten goedkeuren door de European Computer Manufacturers Association (ECMA), waarbij de naam om officiële redenen is gewijzigd in ECMAScript. De ECMA heeft met andere woorden JavaScript gestandaardiseerd. Ondertussen zijn er meerdere implementaties van deze standaard beschikbaar, zoals JavaScript van Mozilla, JScript van Microsoft, en ActionScript van Adobe. 1.3. Verdere info Uiteraard valt er nog veel meer te vertellen over JavaScript. Voor meer uitleg verwijs ik dan ook graag naar het eindwerk van medestudent Jos De Berdt over geavanceerde JavaScript.
Eindwerk: JavaScript-frameworks
10
Mathias Bynens
2.
Wat is een JavaScript-framework?
Om te begrijpen wat een JavaScript-framework is, moeten we ons eerst afvragen hoe een framework gedefinieerd kan worden. 2.1. Definitie van ‘framework’ Wikipedia zegt dat een framework een geheel van softwarecomponenten is, dat gebruikt kan worden bij het programmeren van applicaties. Een framework kan echter ook afspraken in verband met het gebruik van die componenten binnen een groep ontwikkelaars omvatten, alsook conventies met betrekking tot gebruikte code-standaarden en libraries. Dit is alweer een vrij vage definitie vol technische termen. Wat doet een framework nu precies?
Het werken met complexe technologieën vereenvoudigen; Losstaande softwarecomponenten verbinden tot een praktischer geheel; Ontwikkelaars in zekere zin verplichten om hun code volgens bepaalde afspraken te schrijven, hetgeen resulteert in consistentie van de code, minder bugs en flexibele applicaties.
Het gebruik van frameworks brengt met andere woorden vele voordelen met zich mee. Zo kan elke ontwikkelaar op eenvoudige wijze code testen en debuggen, zelfs indien hij die code niet zelf heeft geschreven. Door de opgelegde code-standaarden zal de code immers voor iedereen die met het framework vertrouwd is, leesbaar zijn. Een framework vormt als het ware een laag bovenop een bestaande programmeertaal, waardoor het mogelijk wordt om eenvoudiger, consistenter code te schrijven. 2.2. Definitie van ‘JavaScript-framework’ Een JavaScript-framework is een framework zoals het hierboven beschreven wordt, maar dan specifiek toegepast op de JavaScript-scriptingtaal. Dit houdt niet alleen in dat het framework zelf in JavaScript is geprogrammeerd, maar bovendien dat ook de code die via het framework geschreven wordt gewoon JavaScript is. JavaScript-frameworks worden ook wel eens JavaScript-libraries genoemd. Alvorens op zoek te gaan naar de onderlinge verschillen tussen de verscheidene JavaScriptframeworks, zal ik onderzoeken wat de voor- en nadelen zijn van het gebruik ervan.
Eindwerk: JavaScript-frameworks
11
Mathias Bynens
3.
Voordelen van JavaScript-frameworks
Tegenwoordig is er werkelijk een overvloed aan JavaScript-frameworks. Of, zoals Tom Occhino het gekscherend zegt, zijn er “1.2 frameworks per JavaScript developer”. Dit wijst er op dat het gebruik van een framework toch wel voordelen moet bieden. Wat mogen deze voordelen dan wel zijn? 3.1. Cross-browser-compatibiliteit Hoewel de specificatie van JavaScript zelf vrijwel browser-onafhankelijk is, wordt het vaak gebruikt om het Document Object Model (DOM) te manipuleren. Het DOM is echter niet browser-onafhankelijk, en er bestaan soms grote verschillen tussen de DOM-implementaties in verschillende browsers.
Een voorbeeld hiervan is het binden van events of gebeurtenissen. De W3C-standaard hiervoor is de addEventListener()-functie. Internet Explorer ondersteunt deze methode echter niet, maar heeft wel een eigen implementatie: attachEvent(). JavaScript-frameworks bevatten meestal extra code voor verschillende browsers, zodat de ontwikkelaar zich niet (of minder) bezig hoeft te houden met het cross-browser-compatibel maken van zijn code.
Eindwerk: JavaScript-frameworks
12
Mathias Bynens
3.2. Eenvoudige selectie van DOM-elementen JavaScript heeft enkele ingebouwde methodes waarmee het mogelijk is het DOM te doorlopen en op zoek te gaan naar het gewenste element of de gewenste reeks elementen. Heel flexibel zijn deze echter niet. Beschouw volgend voorbeeld van een HTML5-pagina:
Het doorlopen van het DOM (DOM traversing)
Deze pagina bevat een ongeordende lijst met drie items, die elk een verschillende link bevatten. Nu kunnen we het DOM doorlopen via JavaScript om de gewenste elementen te selecteren: // Selecteer ul#menu var menu = document.getElementById('menu'); document.writeln(menu); // '[object HTMLUListElement]'
De variabele menu bevat nu het hele ul-element uit het DOM. In plaats van één element, is het ook mogelijk een lijst van elementen te selecteren: // Selecteer alle li’s binnen ul#menu var menuLIs = menu.getElementsByTagName('li'); document.writeln(menuLIs); // '[object HTMLCollection]'
Hierna bevat de variabele menuLIs een nul-geïndexeerde NodeList met daarin alle lielementen die onderdeel zijn van de ongeordende lijst ul#menu. Om hieruit enkel de derde li te selecteren, kunnen we volgende code gebruiken: // Selecteer enkel de derde li in ul#menu var menuThirdLI = menuLIs[2]; // eerste element heeft als index 0 document.writeln(menuThirdLI); // '[object HTMLLIElement]'
Eindwerk: JavaScript-frameworks
13
Mathias Bynens
Deze code kan als volgt gelezen worden: neem het derde element van de menuLIs-variabele, die enkel de li-elementen binnen ul#menu bevat, en bewaar dit in de variabele menuThirdLI. De menuThirdLI-variabele bevat nu dus de derde li binnen ul#menu. We kunnen dit element echter ook selecteren door in JavaScript gebruik te maken van het childNodes-attribuut. Hiermee kunnen we – de naam zegt het zelf – alle child-nodes van een element opvragen. // Selecteer enkel de derde li in ul#menu var menuThirdLI = menu.childNodes[2]; document.writeln(menuThirdLI); // '[object HTMLLIElement]'
Net als het resultaat van de getElementsByTagName()-methode, bevat het childNodesattribuut een nul-geïndexeerde NodeList. Het gevaar hierbij is dat childNodes alle children van het gekozen element in het DOM teruggeeft. Aangezien het DOM per browser verschilt, kan dit wel eens tot onverwachte resultaten leiden. Bovenstaande code werkt bijvoorbeeld niet in Mozilla Firefox, omdat deze browser de whitespace (de spaties en regeleindes tussen de verschillende li-elementen) eveneens als child-nodes aanziet. Dit kunnen we onderzoeken aan de hand van volgende code: var menuChildren = menu.childNodes; for (var key in menuChildren) { if ('object' == typeof menuChildren[key]) { document.writeln( key + ': ' + menuChildren[key] + '; ' + menuChildren[key].innerHTML ); }; };
Hiermee worden alle child-nodes van ul#menu bewaard in de variabele menuChildren. Vervolgens doorlopen we deze array, en tonen we per element de huidige index, het objecttype en de inhoud binnen de li-tags. In Internet Explorer geeft dit volgend resultaat: 0: [object HTMLLIElement];
Link 1 1: [object HTMLLIElement];
Link 2 2: [object HTMLLIElement];
Link 3
In Firefox zien we echter het volgende: 0: [object Text]; undefined 1: [object HTMLLIElement];
Link 1
Eindwerk: JavaScript-frameworks
14
Mathias Bynens
2: 3: 4: 5: 6:
[object [object [object [object [object
Text]; undefined HTMLLIElement];
Link 2 Text]; undefined HTMLLIElement];
Link 3 Text]; undefined
Het derde li-element heeft hier dus niet 2, maar 5 als index. Om voorgaande code crossbrowser-compatibel te maken, zijn met andere woorden verdere controles binnen het script nodig. Over het algemeen kunnen we stellen dat de ingebouwde DOM traversing methods volgende problemen met zich mee brengen: weinig flexibiliteit; langdradige, weinig leesbare code; cross-browser-incompatibiliteit wegens verschillen in het DOM. Vele JavaScript-frameworks bieden hiervoor een oplossing door de mogelijkheid toe te voegen om het DOM te doorlopen via de krachtige syntax van CSS selectors. Dit laat toe om veel eenvoudiger code te schrijven om de gewenste elementen te selecteren: // Dit voorbeeld maakt gebruik van de jQuery-syntax. // Voor andere frameworks is deze syntax echter zeer gelijkend. // Selecteer ul#menu var menu = $('ul#menu'); // Selecteer alle li’s binnen ul#menu var menuLIs = $('ul#menu li'); // Selecteer enkel de derde li in ul#menu var menuThirdLI = $('ul#menu li:eq(2)');
Bovendien rekenen de meeste frameworks zoals reeds vermeld intern af met cross-browserverschillen in de DOM, waardoor een betrouwbaar resultaat gegarandeerd is. De mogelijkheid tot selectie van DOM-nodes via CSS selectors binnen JavaScript is zo’n populair voordeel van frameworks, dat verschillende browser vendors een specificatie hebben gemaakt om dit standaard in hun browser te implementeren. Deze W3C-specificatie staat gekend onder de naam “Selectors API”, en breidt JavaScript uit met de methodes querySelector() en querySelectorAll(). Hiermee kunnen respectievelijk één enkel element en een array van elementen geselecteerd worden door middel van CSS selectors. Ondertussen is deze functionaliteit ingebouwd in zowat alle moderne browsers: Firefox 3.5+, Safari 3.1+, Chrome 1+, Opera 10+, en zelfs Internet Explorer 8+.
Eindwerk: JavaScript-frameworks
15
Mathias Bynens
Het spreekt voor zich dat deze native implementaties beduidend sneller en performanter zijn dan dezelfde functionaliteit, omschreven in een framework. Moderne frameworks maken dan ook gebruik van deze browser-implementatie, indien deze beschikbaar is. Zo niet, dan biedt het framework alsnog de eigen CSS selector engine. Als gebruiker van een framework hoef je dus helemaal geen rekening te houden met deze specificaties en ontwikkelingen. 3.3. Hergebruik van code Naarmate websites interactiever worden is er steeds meer JavaScript-code nodig. Net als bij andere programmeerprojecten ontstaat in zo’n geval ook bij webontwikkelaars de behoefte aan een verzameling van in de praktijk geteste, herbruikbare functionaliteit. In deze behoefte wordt door een framework voorzien. Ajax is hiervan een praktisch voorbeeld. De meeste frameworks hebben ingebouwde methodes die toelaten om op zeer eenvoudige wijze asynchrone verbindingen te maken via het XMLHttpRequest-object. Zonder framework of enige voorafgaande scripting, komt dit neer op het schrijven van vele regels code. Bovendien werken veel JavaScript-frameworks met een plugin-systeem, waardoor het zeer eenvoudig wordt om zelf een bepaalde functionaliteit in een apart bestand te beschrijven, en het over verschillende projecten te hergebruiken. Frameworks met een grote / actieve community hebben als bijkomend voordeel dat er een zeer groot aanbod aan beschikbare plugins is. 3.4. Onderhoudbaarheid van code JavaScript-frameworks bestaan doorgaans uit één gecomprimeerd bestandje, dat simpelweg vanuit de HTML-pagina kan worden aangesproken. Eens het framework geladen is, kan je dan andere JavaScript-code toevoegen, die gebruikmaakt van de aangepaste functionaliteit van het framework. De code die je zelf schrijft, kan je dus perfect gescheiden houden van de framework-code. Dit maakt het zeer eenvoudig om, indien er een update van het framework verschijnt, te upgraden; het is immers slechts een kwestie van het juiste bestand te overschrijven. Hetzelfde geldt voor de plugin-architectuur die vele frameworks hanteren: een plugin is simpelweg een JavaScript-bestandje dat verder bouwt op het geladen framework om nieuwe functionaliteit toe te voegen. Ook deze plugin-code blijft met andere woorden gescheiden
Eindwerk: JavaScript-frameworks
16
Mathias Bynens
van de code die je als webontwikkelaar zelf schrijft. Het installeren van een plugin-update is dus even eenvoudig als het upgraden van je framework naar de laatste versie. 3.5. Klasse-gebaseerde overerving Zoals reeds uitgelegd in het hoofdstuk “Wat is JavaScript?” (vanaf pagina 8), maakt JavaScript gebruik van overerving op basis van prototypes (prototype-based inheritance) in plaats van de traditionele overerving op basis van klassen (class-based inheritance). Veel JavaScript-frameworks bieden de gebruiker de mogelijkheid om met traditionele overerving, gebaseerd op klassen, te werken. Het framework zorgt er dan voor dat deze op de achtergrond geïmplementeerd wordt met behulp van JavaScript’s prototypegebaseerde overerving. Op die manier kunnen programmeurs die het gebruik van klassen gewoon zijn, deze methodiek alsnog in JavaScript toepassen. Andere frameworks kiezen er dan weer bewust voor om dit niet te doen, teneinde de natuurlijke opbouw van JavaScript te behouden.
Eindwerk: JavaScript-frameworks
17
Mathias Bynens
4.
Nadelen van JavaScript-frameworks
Er zijn echter ook enkele nadelen verbonden aan het gebruik van JavaScript-frameworks. Logischerwijs worden deze veel minder gedocumenteerd dan de vele voordelen. Uit eigen ervaring kwam ik echter tot de volgende opsomming. 4.1. Bestandsgrootte Een JavaScript-framework neemt al gauw enkele tientallen kilobytes in beslag. Daarbij komt dan nog eens de code die je, gebruikmakend van het framework, zelf schrijft. Afhankelijk van het framework, de hoeveelheid code, de snelheid van de server waarop de bestanden gehost staan, en de internetsnelheid van de eindgebruiker, kan het dus even duren alvorens de scripts volledig geladen zijn. Een langere laadtijd voor de eindgebruiker is echter niet het enige probleem dat een hogere bestandsgrootte met zich mee brengt. Het frequent versturen van grote bestanden betekent immers ook een zekere belasting van de server. Het totale datavolume dat een server per tijdseenheid verstuurt en ontvangt, wordt bandbreedte of verbruik genoemd. Hoe hoger het verbruik binnen een bepaald tijdsinterval ligt, hoe hoger de serverkost voor die periode zal zijn. Om aan te tonen dat dit geen muggenzifterij is, illustreer ik deze problematiek graag aan de hand van een voorbeeld. Stel dat Google twee onafhankelijke JavaScript-ontwikkelaars de opdracht geeft om hun homepagina van een nieuwe functionaliteit te voorzien. Ontwikkelaar A gebruikt een JavaScript-framework van 49 kB (een realistisch gemiddelde), en schrijft daarbovenop nog 1 kB eigen code om het geheel te laten werken. Ontwikkelaar B programmeert zonder framework, en heeft dus (naast ongetwijfeld meer werk) iets meer eigen code: 10 kB. Google krijgt dagelijks zo’n 90 miljoen unieke bezoekers1. Stel dat deze allemaal over een browser beschikken die JavaScript-bestanden, eenmaal ze geladen zijn, in de cache bewaart, zodat per bezoeker de bestanden slechts eenmaal geladen worden. Nu kunnen we het verschil in bandbreedte per dag berekenen voor beide JavaScript-oplossingen.
1
How many hits per day does Google get? Opgehaald van Yahoo! Answers. http://answers.yahoo.com/question/index?qid=20080130154125AAvRxei
Eindwerk: JavaScript-frameworks
18
Mathias Bynens
De code van ontwikkelaar A is in totaal goed voor 50 kB. Indien deze 90 miljoen keer geladen wordt, betekent dit een dagelijks verbruik van 4.500.000.000 kB. Dit is maar liefst 4.500 GB, oftewel 4,5 TB aan gegevens! De code van ontwikkelaar B neemt 10 kB in beslag. Indien deze 90 miljoen keer geladen wordt, brengt dit een dagelijks verbruik van 900.000.000 kB met zich mee. Dit komt overeen met 900 GB.
Het verschil tussen beide oplossingen bedraagt dus maar liefst 3,6 terabytes! Stel nu nog dat Google met goedkope servers werkt (hetgeen hoogst twijfelachtig is), en dat bandbreedte hen slechts 1 cent per gigabyte kost; dan nog komt dit neer op een verschil van 36 euro per dag. (Let wel, bovenstaand voorbeeld houdt hoegenaamd geen rekening met de eventuele voordelen die het gebruik van een framework in dit geval zou kunnen bieden, zoals onderhoudbaarheid en herbruikbaarheid van code. Uiteraard kunnen ook werkuren een financieel verschil maken.) Voor projecten waarbij slechts minimale JavaScripting nodig is, kan het soms dus interessanter zijn om zonder framework te werken, zowel voor de eindgebruikers als voor diegene die de server bekostigt. Sommige frameworks laten je toe om zelf een downloadbaar bestand samen te stellen door enkel de gewenste onderdelen te selecteren. Op die manier wordt enkel de nodige code telkens geladen, hetgeen afhankelijk van de situatie gemakkelijk enkele kilobytes kan schelen. 4.2. Performantie De term “laadtijd” kan op verschillende manieren opgevat worden. Enerzijds is er de tijd die de server nodig heeft om een bestand naar de eindgebruiker of cliënt te versturen. Deze tijdspanne hangt af van de snelheid waarmee de server data kan versturen, en van de snelheid waartegen de cliënt die data kan downloaden (afhankelijk van de internetverbinding). (Zie “Bestandsgrootte” op pagina 18 voor meer info.) Daarnaast is er echter ook de tijd die het verstuurde bestand nodig heeft om door de computer van de eindgebruiker ‘gelezen’ of geladen te worden. De snelheid waarmee dit
Eindwerk: JavaScript-frameworks
19
Mathias Bynens
gebeurt, hangt af van de hardwareconfiguratie en de browser van de cliënt2, alsook de CPUintensiteit van het script in kwestie. Eens een framework helemaal door de browser van de eindgebruiker gedownload is (de eerste vorm van laadtijd), moet de computer van de cliënt deze code nog interpreteren alvorens de uitvoering ervan zichtbaar wordt. Op moderne computerconfiguraties komt dit doorgaans neer op een kwestie van slechts milliseconden, maar dat neemt niet weg dat performantie belangrijk is in de wereld van de webontwikkeling. Ook hier geldt de regel dat het voor projecten die slechts minimale JavaScripting vereisen, soms interessanter is om zonder framework te werken. 4.3. Kennis van JavaScript Doordat het via frameworks zoveel eenvoudiger is om werkende JavaScript-toepassingen te ontwikkelen, programmeren JS-ontwikkelaars nog amper in ‘pure’ JavaScript. Dankzij de goede documentatie en code-voorbeelden die vele frameworks aanbieden, wordt het bovendien zeer verleidelijk om kant-en-klare scripts te kopiëren en aan te passen aan de eigen wensen. Voor ervaren codeurs is dit niet zozeer een probleem. Nieuwe JavaScript-ontwikkelaars die op deze manier te werk gaan, lopen echter het risico niet te weten waar ze mee bezig zijn, omdat ze de originele JavaScript-syntax niet herkennen in de voor het framework geschreven code. We zien met andere woorden een grote gebruikersgroep die het schrijven van ingewikkelde code overlaat aan de ontwikkelaars van frameworks en plugins, waarna zijzelf dan door het combineren en aanpassen van enkele lijnen voorbeeldcode een volledige applicatie in elkaar flansen. Het succes van frameworks komt de algemene kennis van JavaScript dus niet ten goede! Het grote gevaar hiervan is dat de technische vooruitgang, zowel van de frameworks als van de taal JavaScript, meer en meer van een steeds kleiner wordende groep professionele ontwikkelaars afhangt, terwijl de groep eindgebruikers sneller dan ooit stijgt. Door hun grote gebruiksgemak verlagen frameworks voor nieuwe gebruikers de drempel tot JavaScript aanzienlijk. Hiermee verkleint echter ook de grens tussen de (iets minder professionele) JavaScripters en absolute nieuwelingen.
2
Higgins, P. (sd). TaskSpeed: Library Task Test Suite. Opgehaald van http://dante.dojotoolkit.org/taskspeed/
Eindwerk: JavaScript-frameworks
20
Mathias Bynens
5.
Vergelijkende studie van JavaScript-frameworks
Zoals reeds aangehaald, is het aanbod van JavaScript-libraries tegenwoordig enorm groot. Dit maakt de keuze des te moeilijker! Daarom is het interessant om op zoek te gaan naar de mogelijke onderlinge verschillen. 5.1. Selectie van frameworks Gezien het enorme aanbod is het simpelweg onmogelijk om alle beschikbare JavaScriptframeworks te bespreken. Ik moet dus een selectie maken. Om deze zo objectief en onwillekeurig mogelijk te laten verlopen, stelde ik enkele voorwaarden op waaraan een framework moet voldoen om deel uit te maken van dit onderzoek. Ik besloot de focus te leggen op browser-gerichte, server-agnostische, niet-commerciële, open-source JavaScript-frameworks met een open ontwikkeling; pakketjes die met andere woorden voor elke JavaScript-ontwikkelaar potentieel nut hebben. Met deze maatstaf vielen meteen heel wat frameworks af. ASP.NET AJAX (vroeger gekend als ‘Atlas’) bespreek ik bijvoorbeeld niet, omdat deze library zich specifiek tot .NET-ontwikkelaars richt, en dus niet server-agnostisch is. Dit gegeven sluit immers een eerlijke vergelijking met andere frameworks uit. Om dezelfde reden vallen ook Google Web Toolkit en het Direct Web Remoting-framework af; deze oplossingen zijn immers enkel interessant voor Java-ontwikkelaars. De ExtJS-library heeft een dubbele licentie, waarvan er één commercieel is. Bovendien heeft dit project, hoewel het eindresultaat open-source is, een gesloten ontwikkeling. Er is geen bug tracker, en aanpassingen aan de code van het framework zijn niet publiekelijk zichtbaar tot een nieuwe versie wordt uitgebracht. Het Ajax-framework van Adobe, Spry genaamd, richt zich voornamelijk op webdesigners, en is dus minder interessant voor webontwikkelaars. base2, de JavaScript-library van Dean Edwards, beperkt zich, naast het toevoegen van enkele minieme functionaliteiten, tot het cross-browser-compatibel maken van enkele standaardmethodes. Hierdoor is dit framework lang niet zo uitgebreid als vele andere. Het zou dan ook oneerlijk zijn om base2 in de vergelijking op te nemen. Na deze schifting blijft volgende lijst van JavaScript-frameworks over:
Eindwerk: JavaScript-frameworks
21
Mathias Bynens
Prototype & script.aculo.us
MooTools & moo.fx
jQuery & jQuery UI
The Dojo Toolkit
YUI (Yahoo! UI Library)
Om de vergelijking zo duidelijk mogelijk te maken, zal ik elk framework uitgebreid bespreken, en telkens dezelfde praktische voorbeeldjes nabouwen volgens de codestandaarden van de library in kwestie.
Eindwerk: JavaScript-frameworks
22
Mathias Bynens
5.2. Vergelijkingscriteria “Een goede vergelijking verfrist het verstand”, zei Ludwig Wittgenstein ooit. Hoewel hij het naar alle waarschijnlijkheid niet over JavaScript-frameworks had, geeft hij met deze zin wel het belang aan van de vergelijkingscriteria, waarmee een studie als deze immers staat of valt. 5.2.1. Gebruikte techniek
Een eigenschap van alle JavaScript-frameworks is dat ze functionaliteit toevoegen aan JavaScript. De manier waarop dit gebeurt, verschilt echter per framework. Er kan geopteerd worden om de nieuwe functies te categoriseren volgens objecttype (String, Number, Array…), en vervolgens de prototypes van deze objecten uit te breiden om deze functionaliteiten toe te voegen. De functie corrigeerSpelling() ter uitbreiding van het String-prototype in het hoofdstuk “Wat is JavaScript?” (vanaf pagina 8) is hier een eenvoudig voorbeeld van. Een ietwat geavanceerder maar praktischer voorbeeld is de trim()-functie, die witruimte aan het begin en einde van een string verwijdert. Indien deze functie door prototype-aanpassing wordt toegevoegd aan JavaScript, ziet de code er als volgt uit: String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g, ''); };
Deze implementatie laat volgende code toe: document.writeln(' test '.trim()); // 'test'
De trim()-methode kan nu dus zonder meer op alle String-objecten worden toegepast. Het lijkt met andere woorden alsof de trim()-functie onderdeel is geworden van JavaScript. Dit laat toe om zeer georganiseerde code te schrijven; elke functie is immers toegekend aan het prototype van het type object waarop ze kan gebruikt worden. Bovendien kunnen meerdere functies op dezelfde string worden toegepast door middel van chaining (het aaneenschakelen van functies): document.writeln(' fautje '.trim().corrigeerSpelling()); // 'foutje'
Om te achterhalen wat deze code doet, lezen we simpelweg van links naar rechts: neem de string ' fautje ', verwijder hiervan onnodige witruimte via de trim()-functie, en
Eindwerk: JavaScript-frameworks
23
Mathias Bynens
corrigeer vervolgens de spelling via de corrigeerSpelling()-functie. Toon tenslotte het resultaat op het scherm via document.writeln(). Kortom, na uitbreiding van prototypes kan je op eenvoudige wijze code schrijven die heel natuurlijk overkomt. Het alternatief bestaat erin om de nieuwe trim()-functie simpelweg als losstaande functie te schrijven. Dit gebeurt als volgt: function trim(str) { return str.replace(/^\s+|\s+$/g, ''); };
Om deze functie dan te gebruiken, doen we het volgende: document.writeln(trim(' test ')); // 'test'
Het nadeel van deze werkwijze is dat de code minder leesbaar is, doordat het aaneenschakelen van functies via chaining onmogelijk wordt. Dit wordt duidelijker als we meerdere functies op een string gaan toepassen. Stel dat we de corrigeerSpelling()functie uit het allereerste voorbeeld als losstaande functie hebben toegevoegd: document.writeln(corrigeerSpelling(trim(' fautje '))); // 'foutje'
Om nu te achterhalen wat deze code precies doet, moeten we van rechts naar links lezen. (Neem de string ' fautje ', verwijder hiervan onnodige witruimte via de trim()-functie, en corrigeer vervolgens de spelling via de corrigeerSpelling()-functie. Toon tenslotte het resultaat op het scherm via document.writeln().) Hoewel deze manier van interpreteren misschien minder natuurlijk overkomt, is deze syntax – in tegenstelling tot die van chaining – gebruikelijk in de meeste programmeertalen. Naast het zichtbare verschil in syntax, kan de manier waarop functionaliteit aan JavaScript wordt toegevoegd ook minder voor de hand liggende gevolgen met zich mee brengen. Indien er voor prototype-uitbreiding gekozen wordt, kan dit immers voor onverwachte resultaten zorgen. Deze interferentie is vooral waarneembaar wanneer het Objectprototype gewijzigd wordt. Beschouw volgend voorbeeld: var ego = { voornaam: 'Mathias', achternaam: 'Bynens', leeftijd: 20 }; document.writeln(typeof ego); // 'object'
Eindwerk: JavaScript-frameworks
24
Mathias Bynens
document.writeln(ego); // '[object Object]' for (var property in ego) { document.writeln(property + ': ' + ego[property]); };
Deze code kan als volgt gelezen worden: maak een variabele ego die een lijst van paren van eigenschappen (properties) en daarmee geassocieerde waarden van een object (values) bevat. (Deze constructie heet een object literal, en is herkenbaar aan de accolades.) Geef vervolgens het type van de zonet aangemaakte variabele weer. Toon ook hoe deze variabele globaal wordt weergeven. Hierna volgt een for…in-lus, waarbij alle elementen van de variabele doorlopen worden. Zoals gezegd, is elk element hierbij een paar van een eigenschap en een waarde. Per element worden deze property en value, door een dubbelepunt en een spatie gescheiden, weergegeven op het scherm. Deze code geeft dus normaal gezien volgend resultaat: object [object Object] voornaam: Mathias achternaam: Bynens leeftijd: 20
In het volgende voorbeeld breiden we het Object-prototype uit met de trim()-functie, die enkel voor String-objecten nuttig is: Object.prototype.trim = function() { if ('string' == typeof this) { return this.replace(/^\s+|\s+$/g, ''); } else { return false; }; };
Wanneer we nu opnieuw de for…in-lus van daarnet gebruiken, wordt de problematiek van prototype-aanpassingen duidelijk. var ego = { voornaam: 'Mathias', achternaam: 'Bynens', leeftijd: 20 }; document.writeln(typeof ego); // 'object' document.writeln(ego); // '[object Object]' for (var property in ego) { document.writeln(property + ': ' + ego[property]); };
Eindwerk: JavaScript-frameworks
25
Mathias Bynens
Aangezien het Object-prototype is uitgebreid met de nieuwe functie trim(), en de variabele ego van het type object is, krijgen we nu volgend resultaat: object [object Object] voornaam: Mathias achternaam: Bynens leeftijd: 20 trim: function () { if ('string' == typeof this) { return this.replace(/^\s+|\s+$/g, ''); } else { return false; }; }
Het lijkt dus alsof de trim()-functie, verbonden aan het Object-prototype, onderdeel is geworden van de aangemaakte object literal ego. Dit is echter niet het geval! Om na uitbreiding van het Object-prototype alsnog bovenstaande code te gebruiken, dienen er heel wat controles toegevoegd te worden. Zo zouden we binnen de for…in-lus per element moeten nagaan of het element in kwestie ook deel uitmaakt van Object.prototype. Dit maakt de code echter nodeloos complex. Samengevat kunnen we stellen dat het aanpassen van de ingebouwde JavaScript-prototypes kan resulteren in nette, georganiseerde code en een grote eenvoud in gebruik. Langs de andere kant kan deze techniek echter ook interferentie teweegbrengen, en aldus leiden tot onverwachte resultaten. Bij de keuze van een framework is het dus zeker interessant om na te gaan welke methodiek er gehanteerd wordt om functionaliteit aan JavaScript toe te voegen. 5.2.2. Functionaliteit & gelaagd bouwen
JavaScript-frameworks hebben over het algemeen de bedoeling om JavaScript development te vereenvoudigen. Het eindresultaat van deze ‘JavaScript-ontwikkeling’ kan echter vele uiteenlopende vormen aannemen. Zo kan JavaScript-code extra functionaliteit toevoegen aan een statische webpagina om de gebruiksvriendelijkheid te verhogen. Het is bijvoorbeeld mogelijk om via JavaScript een lijst van alle hyperlinks uit het huidige document te verzamelen. Deze lijst kan dan gebruikt worden om onderaan een overzicht van gebruikte links weer te geven. In dit geval kan de JavaScript-laag gezien worden als een leuk extraatje, dat echter niet noodzakelijk is voor de
Eindwerk: JavaScript-frameworks
26
Mathias Bynens
werking van de website. Dit principe staat bekend als unobtrusive JavaScript of discrete JavaScript. De JavaScript-functionaliteit is immers gescheiden van de structuur, inhoud en presentatie van de webpagina in kwestie, waardoor deze laatste ook zonder JS kan werken. Dit kan als volgt voorgesteld worden:
HTML
CSS
JS
De HTML-laag omvat de structuur en inhoud van de webpagina. Dit omsluit ook eventuele interactieve elementen zoals formulieren. Via CSS wordt de ongestijlde HTML-inhoud van ontwerp en lay-out voorzien. We kunnen spreken van een grafische laag. De JavaScript-laag, oftewel behavior layer, voegt door verwerking en manipulatie van de HTML- en/of CSS-laag extra functionaliteit toe. Bij het laden van een webpagina voegt de browser deze drie lagen samen tot een geheel. Binnen dit model, zal de HTML-laag ook zonder CSS en JS de inhoud van de pagina correct weergeven. Deze zal echter niet gestijld zijn en geen extra JavaScript-functionaliteit bieden. Indien het principe van discrete JavaScript is toegepast, bevat zowel de inhouds- als de grafische laag geen elementen die vertrouwen op JavaScript. Wanneer enkel de JavaScriptlaag ontbreekt, wordt de inhoud alsnog gestijld weergegeven. Waarom is het eigenlijk zo belangrijk om websites ook zonder JavaScript te laten werken? Het antwoord is simpel: niet alle internetgebruikers surfen met JavaScript ingeschakeld. Er zijn bedrijven die, om veiligheidsredenen, hun browsers instellen om JavaScript te blokkeren. Bepaalde browsers (denk aan pda’s en mobiele telefoons) hebben geen ingebouwde JavaScript-engine. Dit geldt ook voor de belangrijkste surfer van het hele internet: Google! Inhoud die enkel beschikbaar is met JavaScript ingeschakeld, kan door Google onmogelijk geïndexeerd worden. En dan zijn er nog de surfers die wel over JavaScript kunnen beschikken, maar niet alle toegevoegde functionaliteit kunnen gebruiken. Blinden en
Eindwerk: JavaScript-frameworks
27
Mathias Bynens
slechtzienden, of mensen die geen muis kunnen gebruiken, zullen het bijvoorbeeld moeilijk hebben met ‘drag and drop’-toepassingen. Sommige frameworks richten zich voornamelijk op ontwikkelaars die op dynamische wijze grafische effecten willen toevoegen aan hun webpagina’s. Denk maar aan openschuivende navigatiemenu’s, of slideshows waarbij elke foto zachtjes overgaat naar de volgende. Dit houdt eerder wijzigingen aan de grafische laag in, dan manipulatie van de HTML. Ook hierbij is het perfect mogelijk om het principe van discrete JavaScript toe te passen. Op die manier zullen visuele effecten, indien de JavaScript-laag wegvalt, louter op basis van de grafische laag worden weergegeven (en dus weinig dynamisch zijn). Het gebruik van discrete JavaScript leidt tot graceful degradation – de site werkt immers nog steeds indien JavaScript wordt uitgeschakeld – en geeft JavaScript de functie van progressive enhancement. Dit laatste houdt in dat browsers die JavaScript ondersteunen een verbeterde, meer functionele versie van de webpagina te zien krijgen, zonder dat JavaScript effectief vereist is. JavaScript kan echter ook gebruikt worden om een volledige Rich Internet Application te bouwen. RIA’s zijn webapplicaties die de indruk geven een desktop-applicatie te zijn. Zo reageren ze op invoer zonder hiervoor zichtbaar pagina’s te herladen. JavaScript-RIA’s maken hiervoor gebruik van de Ajax-technologie. Via een asynchrone verbinding met de webserver wordt nieuwe informatie ingeladen. In plaats van de hele pagina te herladen, wordt enkel het gedeelte waarin mogelijk wijzigingen zijn, opgevraagd. Vervolgens wordt de HTML in het DOM als het ware dynamisch vervangen door de nieuwe inhoud. Dit kunnen we als volgt voorstellen:
HTML + Ajax
CSS
JS (+ Ajax)
Uit deze schematische voorstelling wordt meteen het grote gevaar van Ajax duidelijk. Aangezien een deel van de inhoudslaag via Ajax wordt aangeleverd vanuit de JavaScript-laag, is er een probleem indien deze laatste wegvalt. Deze inhoud kan dan immers niet meer
Eindwerk: JavaScript-frameworks
28
Mathias Bynens
bekeken worden. JavaScript betekent dus niet langer enkel een meerwaarde voor de website. Indien Ajax gebruikt wordt, is het dus des te belangrijker om rekening te houden met de principes van discrete JavaScript. In dit geval betekent dit: ervoor zorgen dat alle inhoud ook zonder JavaScript beschikbaar is. Het komt er dus op neer om eerst een statische, JavaScriptloze website uit te bouwen, die via hyperlinks en HTML-formulieren communiceert met de server. De server geeft per request een volledige pagina terug. Nadien kan je de website dan uitbreiden met een JavaScript-laag, die de nodige links en formulierverzendingen onderschept, en deze via Ajax verstuurt. Hierbij kan je dan genieten van de voordelen van Ajax, en selecteren welk gedeelte van de pagina herladen moet worden. Deze toepassing van het concept van discrete JavaScript op de populaire Ajax-technologie, werd door Jeremy Keith ‘Hijax’ gedoopt3. Bij de keuze van een JavaScript-framework is het belangrijk om voor jezelf uit te maken welke functionaliteit je vooral nodig hebt. Wil je de gebruiksvriendelijkheid van je website verhogen door het toevoegen van enkele scriptjes? Ben je op zoek naar een eenvoudige manier om grafische effecten toe te voegen? Of bouw je een RIA, en wil je vooral een handige Ajax-library? Ook kan het interessant zijn om na te gaan in hoeverre het framework de principes van discrete JavaScript en gelaagd bouwen toelaat. Dit hangt meestal samen met de basisfunctionaliteit van het framework. 5.2.3. Community
Elk framework heeft z’n eigen gebruikersbasis. Hoe populairder een framework, hoe groter deze wordt. Dit lijkt misschien irrelevant bij de keuze van een framework, maar dat is het zeker niet! De grootte van de community rond een framework houdt immers verband met de beschikbare ondersteuning, en het aanbod aan plugins. Bovendien zullen er bij een framework met een hogere populariteit sneller bugs ontdekt (en verholpen) worden, aangezien er dan meer gebruikers zijn die voortbouwen op de code van het framework. 5.2.4. CSS selector engine
De meeste frameworks laten toe om door middel van CSS selectors het DOM te doorlopen. Moderne browsers hebben deze functionaliteit zelfs ingebouwd, via de zogenaamde Selectors API. Zoals reeds besproken, levert dit vele voordelen ten opzichte van klassieke DOM traversing-methodes.
3
Keith, J. (2006). Hijax. Opgehaald van DOM Scripting. http://domscripting.com/blog/display/41
Eindwerk: JavaScript-frameworks
29
Mathias Bynens
JavaScript CSS selector engines hebben in de loop der jaren een rijke evolutie doorgemaakt. Het begon allemaal in maart 2003, toen Simon Willison een blogbericht schreef over zijn zelfgemaakte document.getElementsBySelector()-functie. Vele ontwikkelaars zagen meteen het potentieel van deze functionaliteit, en gaven de nodige feedback om de functie te verbeteren en uit te breiden. Iets meer dan een jaar later, in april 2004, stelde JavaScript-goeroe Dean Edwards zijn eigen implementatie voor: cssQuery(). De belangstelling bleef groeien, en in augustus van datzelfde jaar werd versie 2.0 van cssQuery() beschikbaar. Naast ondersteuning voor nieuwe en complexere selectors, was deze engine uitgebreid met een cache-functie. Bijna tegelijkertijd hiermee bracht John Resig jSelect uit. Voortbouwend op deze selector engine, ontwikkelde John een JavaScript-framework, dat in januari 2006 beschikbaar werd: jQuery. In mei 2006 werd een eerste kladversie van de W3C Selectors API gepubliceerd. Deze API implementeert CSS selectors op browserniveau in JavaScript. Sindsdien volgden nog vele JavaScript CSS selector engines, zoals moo.dom (dat later uitgroeide tot MooTools), MochiKit.Selector (onderdeel van MochiKit), DomQuery (onderdeel van ExtJS), dojo.query (onderdeel van Dojo Toolkit), en base2.DOM (onderdeel van base2). In augustus 2008 publiceerde John Resig een eerste versie van Sizzle, zijn nieuwe framework-onafhankelijke CSS selector engine, dat later de ingebouwde engines in jQuery, Prototype, Dojo, MochiKit en YUI zal vervangen. Elk framework heeft een eigen CSS selector engine. Onvermijdelijk vertonen deze engines onderlinge verschillen. Zo laten niet alle engines even geavanceerde selectors toe, en zijn er mogelijk verschillen in performantie. Hoewel JavaScript-frameworks in moderne browsers grotendeels gebruikmaken van de native Selectors API, blijft het interessant om de selector engine van het framework zelf te onderzoeken. In oudere browsers, die de Selectors API niet ondersteunen, wordt immers de framework-versie van de CSS selector engine geladen. Dit garandeert met andere woorden achterwaartse compatibiliteit. Bovendien kan de engine van een framework meer functionaliteit bieden dan de API van het W3C. Zo laten bepaalde frameworks toe om zelf nieuwe selectors te definiëren4. Ook in de modernste browsers wordt de ingebouwde CSS selector engine van het framework dus nog gebruikt, zij het louter ter uitbreiding van de Selectors API.
4
Padolsey, J. (2008). Extending jQuery’s selector capabilities. Opgehaald van http://james.padolsey.com/javascript/extending-jquerys-selector-capabilities/
Eindwerk: JavaScript-frameworks
30
Mathias Bynens
5.2.5. Licentie
Elk framework wordt vrijgegeven onder de voorwaarden van een bepaalde licentie. Hier zijn vele mogelijkheden. Aangezien JavaScript een dynamische programmeertaal is (zie hoofdstuk “Wat is JavaScript?”, vanaf pagina 8), zijn alle JavaScript-frameworks technisch gezien open-source. Iedereen kan immers het bronbestand van het framework overnemen en over exact dezelfde functionaliteit beschikken. Ik overloop dus even de meest voorkomende licenties voor opensourcesoftware. Frameworks met een MIT-licentie hebben als enige voorwaarde dat het copyright statement in alle kopieën blijft staan. Verder is zowat alles toegestaan: het framework mag doorgegeven of herverdeeld worden, omgebouwd worden tot een nieuw framework, gebruikt worden voor commerciële doeleinden, en zelfs deel uitmaken van gepatenteerde software. Een BSD-licentie houdt ongeveer hetzelfde in als de MIT-licentie. Vrijwel alles is toegestaan, zolang de copyright-disclaimer in elke kopie bewaard blijft. De BSD-licentie voegt hier echter nog een kleine clausule aan toe, waarin staat dat de code op eigen risico gebruikt dient te worden. Hiermee dekken de auteur(s) van het framework zich dus in tegen iedere vorm van schade (zoals dataverlies) die hun code eventueel zou kunnen aanrichten. De Academic Free License (AFL) omvat enkele aanvullingen ten opzichte van de MIT- en BSDlicenties. Zo benadrukt de AFL de rol van de eigenaar van de licentie ten opzichte van diegene die de software gebruikt. Tevens omvat deze licentie een clausule die bepaalt dat de eindgebruiker de eigenaar van de licentie niet mag aanklagen wegens octrooischending. De GPL, oftewel GNU General Public License, geeft gebruikers het recht om het framework te gebruiken voor al dan niet commerciële doeleinden en te herverdelen. Zowel veranderingen aan de originele code als hergebruik van het framework binnen een groter softwarepakket zijn toegestaan, op voorwaarde dat ze eveneens onder de GPL worden uitgegeven. Een gelijkaardige licentie is de LGPL, oftewel GNU Lesser General Public License. Deze is iets soepeler dan de GPL, aangezien ze toelaat om het framework als onderdeel van een grotere applicatie te gebruiken en dit totaalpakket onder een licentie naar keuze uit te geven.
Eindwerk: JavaScript-frameworks
31
Mathias Bynens
5.2.6. Bestandsgrootte
De omvang van een framework is een meetbaar gegeven, dat tevens een indicatie geeft van de memory footprint die de library met zich meebrengt. Het is dus zeker interessant om ook qua bestandsgrootte een vergelijking te maken. Om dit op een zo eerlijk mogelijke wijze te doen, zal ik manueel alle bronbestanden comprimeren. Hiertoe maak ik gebruik van de laatste bètarelease van Dean Edwards’ Packer (versie 3.1)5. Voor een minimale resulterende bestandsgrootte, vink ik de ‘shrink variables’-optie aan. De ‘base62 encode’-optie laat ik uitgeschakeld.
5
Edwards, D. (sd). Packer: Test Page. Opgehaald van http://base2.googlecode.com/svn/trunk/src/apps/packer/packer.html
Eindwerk: JavaScript-frameworks
32
Mathias Bynens
5.3. Individuele analyse Hier overloop ik de geselecteerde frameworks en bespreek ik één voor één hun specifieke eigenschappen. 5.3.1. Prototype & script.aculo.us
In maart 2005 bracht Sam Stephenson de eerste versie van Prototype uit. Vanaf dan won dit framework razendsnel aan populariteit, mede doordat het een standaardonderdeel werd van grotere projecten zoals Ruby on Rails. Prototype heeft als hoofddoel het gebruiksgemak van de JavaScript-taal te verhogen. Om dit te verwezenlijken, voegt het voornamelijk ‘ontbrekende’ functionaliteit toe. Dit gebeurt via het uitbreiden van de native JavaScript-prototypes, waardoor conflicten met andere frameworks of andere bestaande JavaScript-code kunnen optreden. Zoals vele frameworks, biedt Prototype een zogenaamde dollar-functie aan. Deze kan gebruikt worden om eenvoudige wijze DOM-nodes te selecteren. Bovendien beschikken alle elementen die de dollar-functie teruggeeft over toegevoegde functionaliteit ten opzichte van klassieke DOM traversing-methodes. De setStyle()-methode is hier een voorbeeld van: // Klassieke methode, zonder framework: document.getElementById('foo').style.color = 'yellow'; document.getElementById('foo').style.background = 'black'; // Hetzelfde, maar dan met de dollar-functie van Prototype: $('foo').setStyle({ color: 'yellow', background: 'black' });
Beide bovenstaande scriptjes geven het element met id="foo" een gele tekstkleur en een zwarte achtergrond. De Prototype-code is echter veel korter en leesbaarder, en dus ook handiger in onderhoud. De dollar-functie van Prototype geeft telkens zichzelf terug als resultaat, waardoor chaining mogelijk wordt: $('foo').setStyle({ color: 'red' }).addClassName('bar').update('!');
Voorgaande code geeft het element met id="foo" een rode tekstkleur en past er de CSSklasse bar op toe. Vervolgens wordt de inhoud van het element vervangen door een uitroepteken. Dit zijn maar liefst drie mutaties van het #foo-element, die via chaining in één regel code zijn geschreven.
Eindwerk: JavaScript-frameworks
33
Mathias Bynens
DOM-manipulatie gebeurt binnen Prototype via de volgende syntax: // Voeg een li-element toe aan het eind van #menu $('menu').insert({ bottom: '
Een extra item' });
Het binden van gebeurtenissen (events) kan als volgt: // Toon een bericht wanneer er op een li-element wordt geklikt $$('li').invoke('observe', 'click', function() { alert('Proficiat, u klikte zonet op een li-element!'); });
Prototype maakt het mogelijk om met klassen en klasse-gebaseerde objecten te werken in JavaScript. Codeurs die het gewoon zijn om in andere programmeertalen te werken met klasse-gebaseerde overerving, kunnen dit principe ook in JavaScript gebruiken, en hoeven prototype-gebaseerde overerving dus niet aan te leren. // Voorbeeld van het aanmaken van een klasse in JS via Prototype var Person = Class.create({ initialize: function(name) { this.name = name; }, say: function(message) { return this.name + ': ' + message; } }); var ego = new Person('Mathias'); document.writeln(ego.say('Hallo wereld!')); // 'Mathias: Hallo wereld!'
Het is zelfs mogelijk om andere Prototype-klassen uit te breiden via Class.extend(). Het Prototype-framework implementeert ook een Ajax-object, hetgeen toelaat om op zeer eenvoudige wijze cross-browser-compatibele XMLHttpRequest-toepassingen te schrijven. Dit object bevat twee methodes: Ajax.Request() geeft de ruwe XML-uitvoer van een Ajaxrequest terug, en Ajax.Updater() injecteert het resultaat van de request in een DOM-node naar keuze. De Prototype-API is volledig gedocumenteerd op de website. Bovendien zijn er zes inleidende tutorials beschikbaar, die enkele code-voorbeelden bevatten. Verder is er een publieke bug tracker, waarmee iedereen bugs kan rapporteren en de status ervan opvolgen.
Eindwerk: JavaScript-frameworks
34
Mathias Bynens
Naast het Prototype-framework is er ook script.aculo.us, dat zich focust op visuele effecten en GUI-elementen. Thomas Fuchs publiceerde hiervan de eerste versie in juni 2005. Hoewel men spreekt van “het script.aculo.us-framework”, is dit in wezen een uitbreiding van Prototype. Prototype wordt onder andere gebruikt op de websites van Apple, ESPN, CNN en Fox News, en maakt deel uit van het populaire server-side web development-framework Ruby on Rails. Om een idee te krijgen van de communitygrootte en –activiteit, analyseerde ik de archieven van de Prototype-mailinglijst. Op dit moment verschijnen er zo’n 20 berichten per dag op de discussiegroep voor Prototype / script.aculo.us. Een half jaar geleden lag dit gemiddelde met 32 dagelijkse berichten merkbaar hoger. Volgens Google Trends lag het zoekvolume voor de termen “Prototype framework” in oktober 2008 zo’n 60% hoger dan in april 2009. Dit wijst op een algemene afname in interesse voor het framework. We kunnen dus stellen dat de populariteit van Prototype betere tijden heeft gekend. De meest recente Prototype-release is versie 1.6.1 RC2. Na compressie neemt deze 78,3 kB in beslag. Wat de optionele script.aculo.us-library betreft: de laatste versie hiervan, 1.8.2, neemt na compressie 80,2 kB in beslag. Deze omvat dan wel alle beschikbare componenten (acht in totaal). Prototype wordt uitgegeven onder een MIT-licentie. Zolang de copyright notice bewaard blijft, mag je dit framework dus vrijelijk gebruiken. 5.3.2. MooTools & moo.fx
In september 2006 bracht Valerio Proietti MooTools uit ter vervanging van moo.dom, de CSS selector engine die hij enkele maanden voordien had geschreven. MooTools (My Object Oriented Tools), was oorspronkelijk een fork of afsplitsing van de Prototype-library, met een deel van script.aculo.us-functionaliteit, zoals visuele animaties en drag and dropmogelijkheden. Enkele Prototype-concepten, zoals de implementatie van klasse-gebaseerde overerving en de uitbreiding van native JavaScript-prototypes, werden hierbij overgenomen. Dit laatste houdt in dat MooTools kan conflicteren met andere frameworks of eigen JavaScript-code. MooTools heeft als hoofddoelstelling de gebruiker voordelen te bieden ten opzichte van native JavaScript, door toe te laten om op een elegante, flexibele en efficiënte manier crossbrowser-compatibele scripts te schrijven. Hiertoe werken ze, net als Prototype, volgens een net, gestructureerd systeem volgens objectgeoriënteerde klassen. De MooTools-
Eindwerk: JavaScript-frameworks
35
Mathias Bynens
ontwikkelaars hebben een ietwat holistische benadering van JavaScript-ontwikkeling; ze willen vooral een geheel creëren dat groter is dan de som van de aparte delen. De toegevoegde functionaliteit is dan ook onderverdeeld in losstaande componenten, hetgeen van MooTools een modulair alsook zeer flexibel framework maakt. Per project dienen immers enkel de nodige componenten geladen te worden, hetgeen bestandsgrootte en performantie ten goede komt. Hieronder overloop ik enkele componentcategorieën van MooTools.
Core omvat de kern van het hele framework; dit is met andere woorden alle basisfunctionaliteit waar de andere componenten op voortbouwen. Class is de basis-library waarin de instantiatie van ‘klassen’ beschreven wordt. Deze laat toe om klasse-gebaseerde overerving te gebruiken in JavaScript. Native breidt de native JavaScript-prototypes uit met nieuwe functionaliteit. Hierbij kunnen weliswaar conflicten met andere frameworks of eigen JavaScript-code optreden. Element bevat uitbreidingen voor het HTMLElement-object. Deze worden bij het doorlopen van het DOM via de dollar-functie toegepast op de teruggegeven resultaten. Fx is de effectencomponent van MooTools. Deze bevat een geavanceerde API om op eenvoudige wijze elementen te animeren en visuele effecten toe te voegen. Request omvat cross-browser-compatibele XMLHttpRequest-functionaliteit (voor vereenvoudigd gebruik van Ajax), cookie-functies en methodes om met JSON-data te werken.
Onderstaand voorbeeld toont hoe we met MooTools het DOM kunnen doorlopen en CSS toepassen op een HTML-element naar keuze. $$('#foo').setStyles({ color: 'yellow', background: 'black' });
Bovenstaande code geeft het element met id="foo" een gele tekstkleur en een zwarte achtergrond. De dollar-functie van MooTools laat chaining toe: $$('#foo').setStyle('color', 'red').addClass('bar').set('html', '!');
Voorgaande code geeft het element met id="foo" een rode tekstkleur en past er de CSSklasse bar op toe. Vervolgens wordt de inhoud van het element vervangen door een uitroepteken. Dit zijn maar liefst drie mutaties van het #foo-element, die via chaining in één regel code zijn geschreven.
Eindwerk: JavaScript-frameworks
36
Mathias Bynens
DOM-manipulatie gebeurt binnen MooTools via de volgende syntax: // Voeg een li-element toe aan het eind van #menu new Element('li', { html: 'Een extra item' }).inject($('menu'), 'bottom');
Het binden van gebeurtenissen (events) kan als volgt: $$('li').each(function(li) { li.addEvent('click', function() { alert('Proficiat, u klikte zonet op een li-element!'); }); });
MooTools maakt het mogelijk om in JavaScript met klassen en klasse-gebaseerde objecten te werken. De manier waarop dit gebeurt, vertoont grote gelijkenissen met Prototype. // Voorbeeld van het aanmaken van een klasse in JS via MooTools var Person = new Class({ initialize: function(name) { this.name = name; }, say: function(message) { return this.name + ': ' + message; } }); var ego = new Person('Mathias'); document.writeln(ego.say('Hallo wereld!')); // 'Mathias: Hallo wereld!'
Via de Request-component vereenvoudigt MooTools het gebruik van Ajax aanzienlijk. Deze klasse is een cross-browser-compatibele wrapper voor het XMLHttpRequest-object van JavaScript, waarmee asynchrone serververbindingen mogelijk zijn. // Voer een GET-verzoek uit voor de pagina zoeken.php?q=zoekterm new Request({ method: 'get', url: 'zoeken.php' }).send('q=zoekterm');
De MooTools-website omvat een uitgebreide documentatie-sectie, waarin alle toegevoegde functionaliteit wordt beschreven. Bij de meeste methodes staan ook concrete codevoorbeeldjes. Helaas zijn deze niet vergezeld van uitvoerbare demo’s, om het resultaat van deze code ook meteen te bekijken. De site beschikt echter wel over een aparte demo-sectie met uiteenlopende voorbeelden. Verder is er een publieke bug tracker, waarmee iedereen bugs kan rapporteren en de status ervan opvolgen.
Eindwerk: JavaScript-frameworks
37
Mathias Bynens
Voor MooTools kunnen ook plugins gebruikt worden. Deze uitbreidingen van de functionaliteit zijn in klasse-vorm geschreven. Via de officiële website is hier echter weinig informatie over te vinden. Wie op zoek is naar MooTools-plugins, moet dus gebruikmaken van zoekmachines. De Fx-component van MooTools, die ook bekend staat als moo.fx, kan ook in combinatie met het Prototype-framework gebruikt worden. MooTools wordt onder andere gebruikt op de websites van CNet, Vimeo, het W3C, Jeep, Joomla!, Nintendo en phpMyAdmin. Op dit moment verschijnen er zo’n 34 berichten per dag op de discussiegroep voor MooTools. Een half jaar geleden lag dit gemiddelde met 97 dagelijkse berichten merkbaar hoger. Dit kan echter verklaard worden door de oprichting van het onofficiële mooforum, hetgeen de rol van de mailinglijst grotendeels heeft overgenomen. Dagelijks worden hierop gemiddeld 46 berichten geplaatst. Volgens Google Trends lag het zoekvolume voor de term “MooTools” in april 2009 zo’n 5% lager dan in oktober 2008. We kunnen dus stellen dat de populariteit van MooTools de laatste zes maanden niet wezenlijk is veranderd. Jammer genoeg doet het ontwikkelingsteam via de officiële website weinig moeite tot het creëren van een communitygevoel. Het gebrek aan centralisatie van plugins is hier een voorbeeld van. Er is wel een community, maar deze bevindt zich op andere websites, zoals het zelf-opgerichte forum. De meest recente MooTools-release is versie 1.2.2. Na compressie neemt de core 64,3 kB in beslag. Deze kan met de verschillende besproken componenten worden uitgebreid. Om de selectie hiervan te vereenvoudigen, beschikt de MooTools-website over een download builder. Deze genereert op basis van de gewenste componenten een op maat gemaakte versie van het framework, met enkel de gekozen functionaliteit. Zo blijft de bestandsgrootte van het geheel minimaal. Toevoeging van de complete moo.fx-component brengt 19,7 kB aan extra bestandsgrootte met zich mee. MooTools wordt uitgegeven onder een MIT-licentie. Zolang de copyright notice bewaard blijft, mag je dit framework dus vrijelijk gebruiken. 5.3.3. jQuery & jQuery UI
In januari 2006, tijdens de BarCamp-conferentie in New York City, stelde John Resig de eerste versie van jQuery voor. Dit framework heeft als hoofddoel de interactie tussen
Eindwerk: JavaScript-frameworks
38
Mathias Bynens
JavaScript en HTML te verbeteren, door toe te laten het principe van discrete JavaScript op eenvoudige wijze toe te passen. jQuery is opgebouwd uit één enkele namespace, namelijk jQuery. Hiervoor bestaat ook een kortere alias: $. Bovendien breidt jQuery geen native JavaScript-prototypes uit, teneinde conflicten met andere frameworks of bestaande code te vermijden. In plaats hiervan wordt alle extra functionaliteit toegekend aan de jQuery-namespace. Dit houdt in dat alle interactiviteit met het framework via de zogenaamde dollar-functie verloopt. Een groot voordeel is dat jQuery modulair is opgebouwd. Alle toegevoegde functionaliteit (zowel interne functies van het framework als plugins geschreven door externen) wordt simpelweg aan de jQuery-namespace toegekend. In principe kan je dus de frameworkfuncties die je niet gebruikt gewoon uit het bronbestand verwijderen om bestandsgrootte te sparen, zonder dat hierdoor de andere functionaliteit wordt aangetast. Onderstaand voorbeeld toont hoe we met jQuery het DOM kunnen doorlopen en CSS toepassen op een HTML-element naar keuze. $('#foo').css({ color: 'yellow', background: 'black' });
Bovenstaande code geeft het element met id="foo" een gele tekstkleur en een zwarte achtergrond. De dollar-functie van jQuery geeft telkens een jQuery-object terug als resultaat, waardoor chaining mogelijk wordt: $('#foo').css('color', 'red').addClass('bar').html('!');
Voorgaande code geeft het element met id="foo" een rode tekstkleur en past er de CSSklasse bar op toe. Vervolgens wordt de HTML-inhoud van het element vervangen door een uitroepteken. Dit zijn maar liefst drie mutaties van het #foo-element, die via chaining in één regel code zijn geschreven. DOM-manipulatie gebeurt binnen jQuery via de volgende syntax: // Voeg een li-element toe aan het eind van #menu $('#menu').append('
Een extra item');
Het binden van gebeurtenissen (events) kan als volgt: // Toon een bericht wanneer er op een li-element wordt geklikt $('li').click(function() { alert('Proficiat, u klikte zonet op een li-element!'); });
Eindwerk: JavaScript-frameworks
39
Mathias Bynens
jQuery hanteert dus duidelijk een intuïtieve, korte en effectieve syntax. Het jQuery-framework biedt ook uitgebreide Ajax-mogelijkheden via onder andere $.get() en $.post(). Voor geavanceerde gebruikers die meer functionaliteit (zoals uitgebreide foutafhandeling) nodig hebben, is er bovendien ook $.ajax(). Via de officiële website is er een enorm uitgebreide documentatie beschikbaar. Deze omschrijft niet alleen alle beschikbare jQuery-functionaliteit, maar omvat bovendien demonstratieve code-voorbeelden. Verder zijn er ook een paar honderd uiteenlopende tutorials beschikbaar, en dit in verschillende talen. Bovendien kunnen via de website screencasts en presentaties over jQuery bekeken worden. Voor verdere ondersteuning kunnen gebruikers van het framework terecht op de jQuery-discussiegroep. Bovendien is het mogelijk om tegen betaling professionele opleiding en ondersteuning te krijgen via Liferay. Naast de documentatie omvat de site ook een plugin repository, alwaar jQuery-gebruikers hun eigen creaties kunnen verspreiden en documenteren. Verder is er ook een publieke bug tracker, waarmee iedereen bugs kan rapporteren en de status ervan opvolgen. Deze centralisatie van documentatie, demo’s, plugins en ontwikkeling geeft de jQuerywebsite een groot communitygevoel. Naast jQuery zelf is er ook jQuery UI, dat zich focust op visuele effecten, GUI-elementen en grafisch aanpasbare widgets. Dit laatste zijn voorgedefinieerde componenten bestaande uit HTML-, CSS- en JavaScript-code, die samen een interactieve feature vormen. jQuery UI is het enige grafische JavaScript-framework dat conventies handhaaft voor benamingen van CSS-klassen. Alle widgets, inclusief apart gedownloade plugins, gebruiken voor dezelfde grafische elementen identieke klassen. Dit heeft als voordeel dat je niet elke widget apart hoeft te stijlen om tot een grafisch coherent geheel te komen. Stijl gewoon éénmaal de verschillende elementen, en alle widgets die hiervan gebruikmaken, zullen dezelfde stijling overnemen. Om deze taak te vereenvoudigen bieden de ontwikkelaars van jQuery UI zelfs een RIA aan: de zogenaamde ThemeRoller. Kies de gewenste lettertypes, kleuren en graphics voor de verschillende interface-elementen, klik op de download-knop en je eigen jQuery UI theme in CSS is een feit.
Eindwerk: JavaScript-frameworks
40
Mathias Bynens
De website van jQuery UI bevat ook een custom download builder, waarbij je de benodigde effecten kan selecteren. Op basis hiervan wordt er dan een op maat gemaakte versie van jQuery UI gegenereerd, met enkel de gekozen functionaliteit. Zo blijft de bestandsgrootte van het framework minimaal. jQuery wordt onder andere gebruikt op de websites van Google, Dell, Mozilla, WordPress, Digg en Drupal. Op dit moment verschijnen er zo’n 130 berichten per dag op de discussiegroep voor jQuery. Een half jaar geleden lag dit gemiddelde met net geen 99 dagelijkse berichten merkbaar lager. jQuery UI heeft zijn eigen mailinglijst, waarop er dagelijks zo’n 35 berichten geplaatst worden. Zes maand geleden waren dit slechts 21 berichten per dag. Volgens Google Trends lag het zoekvolume voor de term “jQuery” in april 2009 maar liefst 210% hoger dan in oktober 2008. Deze spectaculaire toename in interesse voor het framework is niet eens zo verbazingwekkend, als je weet dat Microsoft en Nokia eind september 2008 hun ondersteuning voor jQuery aankondigden. Microsoft integreerde jQuery in Visual Studio, en Nokia implementeerde het framework in hun widgetontwikkelplatform voor mobiele telefoons. Kortom, het is duidelijk dat de populariteit van het jQuery-framework de afgelopen maanden opvallend is gestegen.
Eindwerk: JavaScript-frameworks
41
Mathias Bynens
De meest recente jQuery-release is versie 1.3.2. Na compressie neemt deze 55,3 kB in beslag. Wat de optionele jQuery UI-library betreft: de laatste versie hiervan, 1.7.1, neemt na compressie 171 kB in beslag. Deze omvat dan wel alle beschikbare componenten (25 in totaal). jQuery wordt uitgegeven onder een MIT-licentie. Zolang de copyright notice bewaard blijft, mag je dit framework dus vrijelijk gebruiken. 5.3.4. The Dojo Toolkit
De eerste versie van Dojo (voluit: The Dojo Toolkit) verscheen eind 2004. Dit project werd gestart door een groep van ontwikkelaars, waaronder Alex Russell, Dylan Schiemann en David Schontzler. The Dojo Foundation is een non-profitorganisatie met als doel dit framework te promoten. Dojo focust op het vereenvoudigen van de ontwikkeling van toegankelijke cross-browsercompatibele webapplicaties. Dit gebeurt onder andere door het gebruik van widgets. Hierbij houdt Dojo rekening met de ARIA-specificatie, alsook met de principes van discrete JavaScript en progressive enhancement. Dojo is modulair opgebouwd, maar gaat hierbij nog net een stapje verder dan de meeste andere frameworks. Het maakt immers gebruik van een package-hiërarchie, hetgeen doet denken aan andere programmeertalen zoals ActionScript. Alle toegevoegde functionaliteit wordt netjes gegroepeerd in modules, die elk hun eigen .js-bestand vormen. Eens de coremodule van Dojo geladen is, kan je vanuit JavaScript extra modules laden via dojo.require(). Dojo zoekt dan op basis van de gekozen module naar het juiste bestand, en laadt dit indien dit nog niet gebeurd was. Deze programmeertechniek heet lazy loading. Op deze manier kan je er voor zorgen dat per webpagina enkel de noodzakelijke bestanden worden geladen, zonder vooraf een selectie te maken tussen benodigde modules. Dit betekent dat de laadtijd van Dojo in rechtstreeks verband staat met de hoeveelheid gebruikte modules op een pagina. Bovendien laat Dojo de native JavaScript-prototypes intact, waardoor conflicten met andere frameworks of bestaande code vermeden worden. Alle functionaliteit van het framework, wordt vanuit de verschillende componenten toegekend aan de dojo-namespace. Onderstaand voorbeeld toont hoe we met Dojo het DOM kunnen doorlopen en CSS toepassen op een HTML-element naar keuze. dojo.query('#foo').style({ color: 'yellow', background: 'black' });
Eindwerk: JavaScript-frameworks
42
Mathias Bynens
Bovenstaande code geeft het element met id="foo" een gele tekstkleur en een zwarte achtergrond. Ook het volgende is mogelijk: dojo.query('#menu') .style('color', 'red').addClass('bar')[0].innerHTML = '!';
Voorgaande code geeft het element met id="foo" een rode tekstkleur en past er de CSSklasse bar op toe. Vervolgens wordt de HTML-inhoud van het element vervangen door een uitroepteken. Dit zijn maar liefst drie mutaties van het #foo-element, die via chaining in één regel code kunnen geschreven worden. Merk op dat de innerHTML-eigenschap eigen is aan JavaScript, en dus geen toegevoegde functie van Dojo is. DOM-manipulatie gebeurt binnen Dojo via de volgende syntax: // Voeg een li-element toe aan het eind van #menu dojo.query('#menu').addContent('
Een extra item', 'end');
Het binden van gebeurtenissen (events) kan als volgt: // Toon een bericht wanneer er op een li-element wordt geklikt dojo.query('li').connect('click', function() { alert('Proficiat, u klikte zonet op een li-element!'); });
The Dojo Toolkit biedt ingebouwde cross-browser-compatibele Ajax-mogelijkheden. Via dojo.xhrGet() kan asynchroon een GET-verzoek worden uitgevoerd; dojo.xhrPost() kan gebruikt worden om data te versturen. De officiële website geeft toegang tot een zeer uitgebreide documentatie van de Dojo-API. Verder zijn er ook enkele tutorials beschikbaar. Bovendien omvat de website enkele screencasts en presentaties over ontwikkeling met het framework. Voor demo’s werd er een aparte sectie aan de site toegevoegd. Hiernaast zijn er ook Dojo-mailinglijsten voor discussies omtrent de ontwikkeling van Dojo. Bovendien is er een actief forum aanwezig, waarop gebruikers van het framework ondersteuning van vrijwilligers kunnen krijgen, en suggesties voor toekomstige releases kunnen plaatsen. Het is echter ook mogelijk om tegen betaling support te krijgen via SitePen. In dit geval word je dan bijgestaan door een team van professionele Dojo-ontwikkelaars, waaronder de makers van The Dojo Toolkit. Deze centralisatie van documentatie, demo’s, ondersteuning en ontwikkeling geeft de Dojowebsite een groot communitygevoel.
Eindwerk: JavaScript-frameworks
43
Mathias Bynens
Dojo wordt onder andere gebruikt op de websites van AOL, Apple (Store), IBM, MapQuest en Bloglines. Volgens Google Trends lag het zoekvolume voor de term “Dojo” in april 2009 zo’n 3% lager dan in oktober 2008. (Voor de term “Dojo Toolkit” waren niet voldoende gegevens beschikbaar.) De interesse voor het framework is dus niet wezenlijk veranderd. Dit kan verklaard worden doordat Zend Technologies in mei 2008 bekendmaakte dat Dojo geïntegreerd zou worden in het populaire Zend Framework voor PHP. Hierdoor bereikt The Dojo Toolkit sowieso een groot publiek van webontwikkelaars. Bovendien hebben zowel IBM als Sun Microsystems aangekondigd The Dojo Foundation financieel te steunen. Deze bedrijven dragen ook actief bij aan de ontwikkeling van de toolkit. Naast de zogenaamde ‘Dojo Core’ zelf, bevat The Dojo Toolkit ook Dijit, dat zich focust op visuele effecten, GUI-elementen en eenvoudig configureerbare widgets. Voor meer geavanceerde gebruikers is er bovendien DojoX, dat meer uitgebreide mogelijkheden biedt. De meest recente Dojo-release is versie 1.3.0, die na compressie 79,5 kB in beslag neemt. Alle extra Dijit-componenten omvatten samen 309,6 kB. Dit lijkt misschien veel, maar dankzij lazy loading worden hiervan uitsluitend de noodzakelijke bestanden geladen. The Dojo Toolkit is dubbel gelicentieerd: het wordt uitgegeven onder de BSD-licentie en de AFL. Concreet houdt dit in dat gebruikers mogen kiezen onder welke licentievoorwaarden ze het framework gebruiken. 5.3.5. YUI (Yahoo! UI Library)
De ontwikkeling van de Yahoo! UI Library (YUI) ging in 2005 van start, onder impuls van Thomas Sha. Aanvankelijk was het de bedoeling om met dit framework de JavaScript-code die over de verschillende sites van Yahoo! gebruikt werd, te standaardiseren, teneinde de onderhoudbaarheid van de code te verhogen. Begin juli 2005 werd de library al gebruikt op My Yahoo! en de Yahoo!-homepagina. In februari 2006 werd YUI ook publiekelijk beschikbaar. De praktische uitwerking evenals het onderhoud van YUI gebeuren volledig intern. Yahoo! financiert dan ook de ontwikkeling. Het hoofddoel van YUI is de ontwikkeling van HTML-gebaseerde web-applicaties te vereenvoudigen, door cross-browser-compatibele functionaliteiten beschikbaar te stellen. YUI is een modulair framework; deze toegevoegde mogelijkheden zijn dus in losstaande componenten onderverdeeld. Per project dienen enkel de nodige componenten geladen te worden. Hieronder overloop ik de zes componentcategorieën van YUI.
Eindwerk: JavaScript-frameworks
44
Mathias Bynens
Core omvat de kern van het hele framework; dit is met andere woorden alle basisfunctionaliteit waar de andere componenten op voortbouwen. Een voorbeeld hiervan is de Event Utility, waarmee cross-browser-compatibele event binding mogelijk is. Utilities is een verzameling van gereedschappen die het schrijven van JavaScript over het algemeen vereenvoudigen. Deze omvat zaken als Selector (de CSS selector engine), Element (waarmee manipulatie van HTML-elementen in JavaScript makkelijker wordt gemaakt) en Connection Manager (voor gebruik bij Ajaxverbindingen en het versturen van formulieren), maar ook grafische gereedschappen zoals Resize en Drag and Drop. Controls is de YUI-benaming voor widgets. Voorbeelden hiervan zijn Calendar, Image Cropper, Rich Text Editor en Color Picker. CSS Resources omvat – de naam zegt het al – CSS-specifieke functionaliteit. Een voorbeeld hiervan is CSS Base, waarmee de standaard-CSS van verschillende browsers wordt overschreven en zo cross-browser-compatibel wordt gemaakt. Developer Tools is een pakket van gereedschappen voor ontwikkelaars. Dit omvat onder andere de Profiler, waarmee de performantie van scripts gemeten kan worden. Om de resultaten van deze metingen weer te geven, kan de ProfilerViewer gebruikt worden. De laatste categorie, Build Tools, bestaat momenteel enkel uit de YUI Compressor. Deze laat toe om JavaScript- en CSS-bestanden te comprimeren.
YUI is modulair opgebouwd rond één enkele namespace, namelijk YAHOO. Er worden dus geen wijzigingen aangebracht aan native JavaScript-prototypes, waardoor de kans op conflicten met andere frameworks of bestaande code minimaal is. Alle toegevoegde functionaliteit zit vervat in de YAHOO-namespace. Net als Dojo maakt YUI gebruik van een soort package-hiërarchie. Via de YUI Loader Utility implementeert YUI lazy loading vanuit JavaScript. Onderstaand voorbeeld toont hoe we met YUI het DOM kunnen doorlopen en CSS toepassen op een HTML-element naar keuze. YAHOO.util.Dom.setStyle('foo', 'color', 'yellow'); YAHOO.util.Dom.setStyle('foo', 'background', 'black');
Bovenstaande code geeft het element met id="foo" een gele tekstkleur en een zwarte achtergrond. Ook het volgende is mogelijk:
Eindwerk: JavaScript-frameworks
45
Mathias Bynens
var foo = YAHOO.util.Dom.get('foo'); YAHOO.util.Dom.setStyle(foo, 'color', 'red'); YAHOO.util.Dom.addClass(foo, 'bar'); foo.innerHTML = '!';
Voorgaande code geeft het element met id="foo" een rode tekstkleur en past er de CSSklasse bar op toe. Vervolgens wordt de HTML-inhoud van het element vervangen door een uitroepteken. Dit zijn drie mutaties van het #foo-element. Helaas biedt YUI 2.x (nog) geen chaining-functionaliteit; anders hadden we deze code in één regel kunnen schrijven. Yahoo! garandeert echter dat YUI vanaf versie 3.x chaining zal toelaten. Merk trouwens op dat de innerHTML-eigenschap eigen is aan JavaScript, en dus geen toegevoegde functie van YUI is. DOM-manipulatie gebeurt binnen YUI via de volgende syntax: // Voeg een li-element toe aan het eind van #menu YAHOO.util.Dom.get('menu').innerHTML += '
Een extra item';
Het binden van gebeurtenissen (events) kan als volgt: // Toon een bericht wanneer er op een li-element wordt geklikt var lis = document.getElementsByTagName('li'); YAHOO.util.Event.addListener(lis, 'click', function() { alert('Proficiat, u klikte zonet op een li-element!'); });
De YUI-website is enorm uitgebreid. De API van de library is volledig gedocumenteerd, met meerdere codevoorbeelden en demo’s per onderdeel. Bovendien is er per YUI-component minstens één tutorial beschikbaar, en wordt er duidelijk uitgelegd hoe je zelf widgets kan schrijven, of hoe de functionaliteit van bestaande YUI-componenten kan uitgebreid worden. Wat opvalt, is dat deze HTML-documentatie volledig inbegrepen zit in de download. Yahoo! ziet YUI dus werkelijk als een gereedschap voor ontwikkelaars dat, net als een uitgebreid softwarepakket, voorzien moet zijn van online en offline documentatie. De ontwikkelaars van YUI beheren het Yahoo! User Interface Blog. Hierop verschijnen regelmatig nieuwtjes, tutorials, artikels, alsook videocasts van presentaties omtrent de library. Voor dit laatste is er trouwens een aparte website: The YUI Theater. Deze website omvat ook presentaties over JavaScript en webontwikkeling in het algemeen. Bovendien is er ook een YUI-discussiegroep op Yahoo! Groups. Verder is er een publieke bug tracker, waarmee iedereen bugs kan rapporteren en de status ervan opvolgen. Dit grote aanbod van documentatie, demo’s, ondersteuning en ontwikkeling zorgt voor een groot communitygevoel rond het YUI-framework.
Eindwerk: JavaScript-frameworks
46
Mathias Bynens
YUI wordt onder andere gebruikt op de websites van LinkedIn, Slashdot, en natuurlijk Yahoo! zelf. Opmerkelijk is dat zelfs ‘concurrent’ Google gedeeltelijk gebruikmaakt van YUI: iGoogle, de gepersonaliseerde homepagina-service, maakt gebruik van YUI Grids CSS. Op de YUI-discussiegroep verschijnen dagelijks zo’n nieuwe 43 berichten. Een half jaar geleden lag dit gemiddelde met 55 dagelijkse berichten iets hoger. Dit kan echter verklaard worden doordat de YUI-website binnenkort zijn eigen domeinnaam krijgt, yuilibrary.com. Op deze website is nu reeds een forum actief, en ook de bug tracker is er beschikbaar. In de toekomst zal ook de API-documentatie overgeheveld worden van de Yahoo!-website. Tot die tijd zit de YUI-community dus een beetje verspreid. Volgens Google Trends lag het zoekvolume voor de term “YUI” in april 2009 zo’n 20% hoger dan in oktober 2008. De interesse voor het framework is gedurende de laatste zes maanden dus merkbaar toegenomen. De meest recente YUI-release is versie 2.7.0. Na compressie neemt de basisfunctionaliteit van de Core zo’n 35,9 kB in beslag. Naarmate meer componenten worden gebruikt, zal de bestandsgrootte uiteraard toenemen. YUI wordt uitgegeven onder de BSD-licentie. Zolang de copyright-disclaimer in elke kopie bewaard blijft, mag het framework dus op eigen risico gebruikt worden.
Eindwerk: JavaScript-frameworks
47
Mathias Bynens
5.4. Onderlinge vergelijking Nu elk van de geselecteerde frameworks besproken is, ga ik over tot praktisch onderzoek. Er zijn immers ook meetbare vergelijkingspunten aan JavaScript-frameworks! 5.4.1. Vergelijking op basis van bestandsgrootte
De omvang van de verschillende frameworks kan als volgt voorgesteld worden: Prototype 1.6.1 RC2
78,3
Prototype + script.aculo.us
158,5
MooTools 1.2.2
64,3
MooTools + moo.fx
84
jQuery 1.3.2
55,3
jQuery + jQuery UI 1.7.1
171
Dojo Base 1.3.0
79,5
Dojo + Dijit
309,6
YUI 2.7.0
35,9 0
50
100
150
200
250
300
350
Hierbij geeft de horizontale as de bestandsgrootte in kB van elk framework weer. We merken dat de kern van YUI opvallend compact is. Uiteraard zal de bestandsgrootte van dit framework toenemen wanneer meer dan enkel de basis-componenten worden gebruikt. Aangezien het laden van extra onderdelen dankzij de YUI Loader Utility door middel van lazy loading kan gebeuren, zal steeds het minimum aan benodigde bestanden geladen worden. Ook jQuery heeft een beperkte omvang. Dit is verwonderlijk, aangezien we het hier over de volledige versie van de library hebben, met alle beschikbare functionaliteit. Samen met alle componenten van jQuery UI neemt dit framework 171 kB in beslag. Dit laatste lijkt veel, maar aangezien deze grafische library uit losstaande componenten is opgebouwd, zal het zelfden voorvallen dat deze allemaal benodigd zijn. MooTools en Prototype schommelen rond de 70 kB, hetgeen nog steeds acceptabele waarden zijn. Uitgebreid met hun losstaande grafische library nemen deze frameworks respectievelijk 84 en 158,5 kB in beslag. De Base oftewel de basisfunctionaliteit van Dojo omvat net geen 80 kB. Met alle Dijitwidgets erbij, neemt dit framework in totaal 309,6 kB in beslag. Dit lijkt enorm veel, maar aangezien Dojo het principe van lazy loading ondersteunt, is het mogelijk om per webpagina
Eindwerk: JavaScript-frameworks
48
Mathias Bynens
enkel de nodige componenten te laden. Een situatie waarbij de volledige 309,6 kB geladen wordt, is welhaast ondenkbaar. Wanneer we de geselecteerde frameworks nu oplopend sorteren volgens de gecomprimeerde bestandsgrootte, bekomen we volgende lijst: 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
YUI 2.7.0 jQuery 1.3.2 MooTools 1.2.2 Prototype 1.6.1 RC2 The Dojo Toolkit (Dojo Base 1.3.0) jQuery + jQuery UI 1.7.1 Prototype + script.aculo.us MooTools + moo.fx Prototype 1.6.1 RC2 Dojo + Dijit
Zoals reeds uitgebreid besproken werd in het hoofdstuk “Bestandsgrootte” (vanaf pagina 18), kan de omvang van een framework gevolgen hebben voor het verbruik van de server. Vooral voor drukbezochte sites kan dit een wezenlijk verschil maken. Een hoger verbruik kan immers resulteren in hogere serverkosten. Een mogelijke oplossing hiervoor is het gebruik van een gratis content distribution network, zoals Google Code. Hierbij neemt het CDN de hosting van het framework over, waardoor dataverkeer ten gevolge van de JavaScript-library op de eigen server beperkt blijft. Bovendien kan het resultaat van het framework pas zichtbaar worden wanneer de code volledig is geladen. Een hogere bestandsgrootte betekent dus dat gebruikers langer moeten wachten tot de site geladen is. 5.4.2. Performantie van CSS selector engines
Een veelgebruikte vergelijkingsmethode voor JavaScript-frameworks is de zogenaamde SlickSpeed-test. Dit is de naam van een PHP-scriptje waarmee het mogelijk is om testcases voor verschillende CSS selector engines op te zetten. Deze engines, waarop de kernfunctionaliteit van de meeste frameworks berust, worden dan getest op hun performantie. Bij deze test moet elk framework door middel van 40 verschillende selectors de juiste DOMnodes uit een groot HTML-document halen. Per selector wordt gemeten hoe lang het framework erover doet; tenslotte wordt de totale benodigde tijd berekend. Uiteraard hangen de precieze resultaten van deze test niet enkel af van het framework zelf, maar ook van de gebruikte browser, van de processorkracht van de computer waarop de
Eindwerk: JavaScript-frameworks
49
Mathias Bynens
test wordt uitgevoerd, et cetera. Indien dezelfde test echter onder dezelfde omstandigheden op dezelfde computer wordt uitgevoerd voor verschillende frameworks, geven de resultaten wel een idee van de performantie van de CSS selector engine. Ik stelde zelf een SlickSpeed-test samen met de meest recente versies van de besproken JavaScript-frameworks. Ter vergelijking voegde ik ook de native querySelectorAll()methode van de officiële Selectors API toe aan de testcase. Deze methode werkt echter niet in Internet Explorer 7, Opera 9.62 en Firefox 3.0. Dit wordt in de volgende tabel weergegeven door een asterisk (*). Internet Explorer 8 ondersteunt de Selectors API slechts gedeeltelijk (**).6 Hier zijn de testresultaten: IE7
IE8
Firefox 3.0
Chrome 1.0
Safari 4.0
Opera 9.62
Opera 10
1502
912
240
79
49
607
590
MooTools 1.2.2
372
460
347
115
74
186
344
jQuery 1.3.2
340
125
174
62
28
346
206
Dojo Base 1.3.0
236
130
531
68
24
82
1814
1406
1362
195
473
267
583
248
*
**
*
41
6
*
156
Prototype 1.6.1 RC2
YUI 2.7.0 Selectors API
De cijfergegevens staan voor het aantal milliseconden dat een framework erover doet om de Slickspeed-test uit te voeren. Hoe lager deze getallen, hoe beter het resultaat. Per browser is het beste resultaat in groen aangeduid; het slechtste resultaat heeft een rode achtergrond. Resultaten van de Selectors API zijn oranje gemarkeerd. Uit bovenstaande tabel kunnen we afleiden dat de Sizzle-engine achter jQuery het beste resultaat geeft in Internet Explorer 8, Firefox 3.0, Chrome 1.0 en Opera 10. Dojo’s selector engine is de snelste in Internet Explorer 7, Safari 4.0 en Opera 9.62, maar behaalt dan weer de laagste score in Firefox 3 en Opera 10. De andere frameworks vallen niet echt op in deze test. YUI behaalt de laagste scores in Internet Explorer 8, Chrome 1.0 en Safari 4.0. Prototype neemt deze twijfelachtige eer op zich in Internet Explorer 7 en Opera 9.62. MooTools blijkt een goede middelmaat; dit framework haalde geen enkele keer de hoogste of de laagste score. Wanneer we de geselecteerde frameworks nu aflopend sorteren volgens de gemeten performantie van hun CSS selector engine, bekomen we volgende lijst:
6
Zie http://eindwerk.mathiasbynens.be/
Eindwerk: JavaScript-frameworks
50
Mathias Bynens
1. 2. 3. 4. 5.
jQuery 1.3.2 The Dojo Toolkit (Dojo Base 1.3.0) MooTools 1.2.2 Prototype 1.6.1 RC2 YUI 2.7.0
Het feit dat jQuery als winnaar uit deze test komt, is een bevestiging van de filosofie van het framework: discrete JavaScript (waarbij een selector engine een zeer handig gereedschap blijkt) wordt op eenvoudige (en snelle!) wijze mogelijk gemaakt. De resultaten van deze test dienen weliswaar met een korreltje zout genomen te worden. Zoals gezegd, hangen de gemeten waarden niet enkel af van de frameworks in kwestie. Het is mogelijk dat er onder andere omstandigheden resultaten uit de bus komen die afwijken van de bovenstaande. Tevens meet deze test de snelheid van elk CSS selector engine door middel van enkele zeer complexe en ongebruikelijke selectors. De kans dat deze allemaal evenveel in de praktijk gebruikt zullen worden, is miniem. Benchmarks als deze houden enkel rekening met specificatie, en niet met de werkelijkheid. Bovendien geeft deze test uitsluitend een indicatie van de performantie van de verschillende CSS selector engines. Deze is niet noodzakelijk evenredig met de prestaties van de rest van het framework. De performantie van de andere framework-mogelijkheden is moeilijker te meten, aangezien deze afhangt van welke functionaliteit je precies gebruikt, en de manier waarop ze gebruikt wordt. Dit hangt met andere woorden voor een deel af van de JavaScript-ontwikkelaar die gebruikmaakt van het framework.
Eindwerk: JavaScript-frameworks
51
Mathias Bynens
6.
Conclusie
Dit eindwerk biedt door theoretische studie en praktisch onderzoek een antwoord op de vragen uit de inleiding. De voor- en nadelen van JavaScript-frameworks werden uitgebreid onderzocht, besproken en afgewogen ten opzichte van traditionele JavaScript. De resultaten hiervan leest u vanaf pagina 12. Bovendien bleek dat het gebruik van een library in sommige gevallen slechts een beperkte meerwaarde biedt, en dus niet altijd even nuttig is. De invloed van het gebruik van frameworks op JavaScript-ontwikkelaars wordt aangehaald in het puntje “Kennis van JavaScript” (pagina 20). Na mijn vergelijkende studie, kan ik enkel het volgende concluderen: “Welk JavaScriptframework zou ik best gebruiken?” is een subjectieve vraag! Enerzijds kan deze keuze afhangen van het gewenste eindresultaat. Iemand die snel en eenvoudig een RIA wil ontwikkelen, zal vooral interesse tonen voor Dojo, YUI en jQuery UI. Wie daarentegen simpelweg op zoek is naar een handige manier om de principes van discrete JavaScript op cross-browser-compatibele wijze toe te passen, zal eerder naar Prototype, MooTools en jQuery neigen. Anderzijds is het duidelijk dat alle besproken frameworks soortgelijke functionaliteit bieden. Bij het maken van een keuze, moet je dus niet alleen kijken naar wat de mogelijkheden precies zijn, maar ook naar de manier waarop het framework jouw manier van coderen kan beïnvloeden. Zo hanteert jQuery een zeer korte, leesbare en intuïtieve syntax, terwijl frameworks als Dojo of YUI nogal ‘breedsprakerig’ zijn. Deze laatste twee gebruiken dan weer een packagesysteem, hetgeen eventueel een voordeel kan zijn voor ontwikkelaars met ervaring in andere programmeertalen waarin dit principe gebruikt wordt. Hetzelfde kan gezegd worden over klasse-gebaseerde overerving; scripters met ervaring in klasse-gebaseerde objectgeoriënteerde programmeertalen, willen deze methodologie misschien doortrekken naar JavaScript. Dit kan via frameworks als Prototype of MooTools. De belangrijkste vraag blijft: helpt dit JavaScript-framework mij bij het schrijven van deze code? Het antwoord hierop hangt grotendeels af van de stijl van de library en zijn API, hetgeen dan weer afhankelijk van persoonlijke voorkeur als positief of negatief ervaren wordt. Alvorens een beslissing te nemen, is het dus van vitaal belang om het framework effectief te testen in zijn gebruik.
Eindwerk: JavaScript-frameworks
52
Mathias Bynens
Bronnenlijst Academic Free License. (sd). Opgehaald van Wikipedia: http://en.wikipedia.org/wiki/Academic_Free_License Ajax Framework Analysis Results. (2009). Opgehaald van Raible Designs: http://raibledesigns.com/rd/entry/ajax_framework_analysis_results Almaer, D. (2008). A great example of sharing; Sizzle Engine in Dojo Foundation. Opgehaald van Ajaxian: http://ajaxian.com/archives/a-great-example-of-sharing-sizzle-engine-in-dojofoundation Anne van Kesteren. (2008). “1.2 frameworks per JavaScript developer”. Opgehaald van Twitter: http://twitter.com/annevk/status/917538372 Arvidsson, E. (2005). Object.prototype is verboten. Opgehaald van http://erik.eae.net/archives/2005/06/06/22.13.54/ ASP.NET AJAX. (sd). Opgehaald van Wikipedia: http://en.wikipedia.org/wiki/ASP.NET_AJAX Bakaus, P. (2008). jQuery UI and beyond: The jQuery-Liferay partnership. Opgehaald van jQuery Blog: http://blog.jquery.com/2008/01/23/jquery-ui-and-beyond-the-jquery-liferaypartnership/ BSD licenses. (sd). Opgehaald van Wikipedia: http://en.wikipedia.org/wiki/BSD_licenses Caron, S. (2009). Demystifying the jQuery selectors optimization. Opgehaald van No Margin for Errors: http://www.no-margin-for-errors.com/2009/04/28/demystifying-the-jqueryselectors-optimization/ Citaten met een V. (sd). Opgehaald van Citaten, aforismen, woordspelingen, definities, oneliners, wijsheden, gezegden, spreuken: http://users.belgacom.net/citaten/v.htm Clifton, M. (2003). What is a framework? Opgehaald van CodeProject: http://www.codeproject.com/KB/architecture/WhatIsAFramework.aspx Creative Commons Licenses. (sd). Opgehaald van http://creativecommons.org/licenses/ Crockford, D. (2008). JavaScript: The Good Parts. O’Reilly Media, Inc. Crockford, D. (2008). JavaScript: The World’s Most Misunderstood Programming Language Has Become the World’s Most Popular Programming Language. Opgehaald van http://javascript.crockford.com/popular.html
Eindwerk: JavaScript-frameworks
53
Mathias Bynens
Crockford, D. (sd). JSLint, The JavaScript Verifier. Opgehaald van http://www.jslint.com/ Defining classes and inheritance. (sd). Opgehaald van Prototype JavaScript framework: http://prototypejs.org/learn/class-inheritance Diepenmaat, J. (2008). Constructors considered mildly confusing. Opgehaald van Zeekat Softwareontwikkeling: http://joost.zeekat.nl/constructors-considered-mildly-confusing.html Discussiegroep voor jQuery (English). (sd). Opgehaald van Google Groups: http://groups.google.com/group/jquery-en/about Discussiegroep voor MooTools Users. (sd). Opgehaald van Google Groups: http://groups.google.com/group/mootools-users/about Discussiegroep voor Prototype & script.aculo.us. (sd). Opgehaald van Google Groups: http://groups.google.com/group/prototype-scriptaculous/about Dojo Quick Start Guide. (2008). Opgehaald van SitePen Labs: http://sitepen.com/labs/guides/?guide=DojoQuickStart Dual-licensing. (sd). Opgehaald van Wikipedia: http://en.wikipedia.org/wiki/Dual-licensing DWR: Easy Ajax for Java. (sd). Opgehaald van http://directwebremoting.org/ Edwards, D. (2006). Opgehaald van http://dean.edwards.name/weblog/2006/07/enum/ Edwards, D. (sd). Packer: Test Page. Opgehaald van http://base2.googlecode.com/svn/trunk/src/apps/packer/packer.html Edwards, D. (2007). Rules for JavaScript library authors. Opgehaald van http://deanedwards.me.uk/weblog/2007/03/rules/ Edwards, J. (2008). A collection is not an array. Opgehaald van SitePoint: http://www.sitepoint.com/blogs/2008/03/19/a-collection-is-not-an-array/ Framework CSS Selector Engines versus Native Selectors API. (sd). Opgehaald van 2008: http://www2.webkit.org/perf/slickspeed/ Garrett, J. J. (2005). Ajax: A New Approach to Web Applications. Opgehaald van Adaptive Path: http://adaptivepath.com/ideas/essays/archives/000385.php Goodman, D. (2001). JavaScript Examples Bible. Hungry Minds. Goodman, D., Morrison, M., & Eich, B. (2007). JavaScript Bible. John Wiley and Sons.
Eindwerk: JavaScript-frameworks
54
Mathias Bynens
Guthrie, S. (2008). jQuery and Microsoft. Opgehaald van ScottGu’s Blog: http://weblogs.asp.net/scottgu/archive/2008/09/28/jquery-and-microsoft.aspx Haverbeke, M. (2007). Eloquent JavaScript: An opinionated guide to programming. Heilmann, C. (2006). Show love to the object literal. Opgehaald van Wait till I come!: http://www.wait-till-i.com/2006/02/16/show-love-to-the-object-literal/ Heilmann, C. (sd). Unobtrusive JavaScript. Opgehaald van http://onlinetools.org/articles/unobtrusivejavascript/ Henriksson, K. (2007). Javascript prototype versus closure execution speed. Opgehaald van Kristoffer’s tidbits: http://blogs.msdn.com/kristoffer/archive/2007/02/13/javascriptprototype-versus-closure-execution-speed.aspx Higgins, P. (sd). TaskSpeed: Library Task Test Suite. Opgehaald van http://dante.dojotoolkit.org/taskspeed/ How Prototype extends the DOM. (sd). Opgehaald van Prototype JavaScript framework: http://prototypejs.org/learn/extensions Irish, P. (2008). Javascript CSS Selector Engine Timeline. Opgehaald van http://paulirish.com/2008/javascript-css-selector-engine-timeline/ JavaScript. (sd). Opgehaald van Wikipedia: http://en.wikipedia.org/wiki/JavaScript jQuery Support. (sd). Opgehaald van Liferay: http://www.liferay.com/web/guest/services/support/jquery jQuery UI ThemeRoller. (sd). Opgehaald van http://jqueryui.com/themeroller/ Keith, J. (2006). Hijax. Opgehaald van DOM Scripting: http://domscripting.com/blog/display/41 Koch, P.-P. (2007). PPK on JavaScript: The DOM – Part 3. Opgehaald van WebRef: http://www.webreference.com/programming/javascript/ppk3/ Koch, P.-P. (sd). QuirksMode – for all your browser quirks. Opgehaald van http://quirksmode.org/ Laurent, A. M. (2004). The MIT, BSD, Apache, and Academic Free Licenses. Opgehaald van Understanding Open Source and Free Software Licensing: http://oreilly.com/catalog/osfreesoft/book/ch02.pdf
Eindwerk: JavaScript-frameworks
55
Mathias Bynens
Laurent, A. M. (2004). Understanding Open Source and Free Software Licensing. Opgehaald van O’Reilly Media, Inc.: http://oreilly.com/catalog/osfreesoft/book/ Lazy loading. (sd). Opgehaald van Wikipedia: http://en.wikipedia.org/wiki/Lazy_loading Leatherman, Z. (2007). Google Using YUI Grids CSS. Opgehaald van zachleat.com: http://www.zachleat.com/web/2007/04/05/google-using-yui-grids-css/ Microsoft. (sd). ASP.NET AJAX. Opgehaald van http://www.asp.net/ajax/ Microsoft. (sd). attachEvent Method. Opgehaald van HTML and DHTML Reference: http://msdn.microsoft.com/en-us/library/ms536343(VS.85).aspx MIT License. (sd). Opgehaald van Wikipedia: http://en.wikipedia.org/wiki/MIT_License Mozilla. (sd). Core JavaScript 1.5 Guide: Object Manipulation Statements. Opgehaald van Mozilla Developer Center: https://developer.mozilla.org/En/Core_JavaScript_1.5_Guide:Object_Manipulation_Stateme nts Mozilla. (sd). DOM: element.addEventListener. Opgehaald van Mozilla Developer Center: https://developer.mozilla.org/En/DOM:element.addEventListener Mozilla. (sd). Object Literals. Opgehaald van Mozilla Developer Center: https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Literals#Object_Literals Nash, P. (2007). Web Accessibility — JavaScript. Opgehaald van Unintentionally Blank: http://www.unintentionallyblank.co.uk/2007/10/18/web-accessibility-javascript/ Newton, A. (2008). How Many Flavors of Linux Are There? Opgehaald van Clientcide: http://www.clientcide.com/best-practices/how-many-flavors-of-linux-are-there/ Padolsey, J. (2008). Extending jQuery’s selector capabilities. Opgehaald van http://james.padolsey.com/javascript/extending-jquerys-selector-capabilities/ Picture of Brendan Eich. (2008). Opgehaald van Spread Firefox: http://www.spreadfirefox.com/node/3267 Proietti, V. (2008). Sizzle. Opgehaald van MooTools: http://mootools.net/blog/2008/12/04/sizzle/ Proietti, V. (sd). Slickspeed. Opgehaald van GitHub: http://github.com/kamicane/slickspeed/tree/master
Eindwerk: JavaScript-frameworks
56
Mathias Bynens
Prototype JavaScript framework. (sd). Opgehaald van http://prototypejs.org/ Prototype JavaScript Framework logo. (sd). Opgehaald van Best Brands of the World: http://www.brandsoftheworld.com/search/90067430/198652.html Resig, J. (2009). JavaScript Function Call Profiling. Opgehaald van http://ejohn.org/blog/function-call-profiling/ Resig, J. (2008). JavaScript Library Loading Speed. Opgehaald van http://ejohn.org/blog/library-loading-speed/ Resig, J. (2008). JavaScript Library Overview. Opgehaald van SlideShare: http://www.slideshare.net/jeresig/javascript-library-overview-presentation Resig, J. (2008). jQuery, Microsoft, and Nokia. Opgehaald van jQuery Blog: http://blog.jquery.com/2008/09/28/jquery-microsoft-nokia/ Resig, J. (2006). Pro JavaScript Techniques. Apress. Resig, J. (2008). querySelectorAll in Firefox 3.1. Opgehaald van http://ejohn.org/blog/queryselectorall-in-firefox-31/ Resig, J. (2009). Selectors API Test Suite in IE 8. Opgehaald van http://ejohn.org/blog/selectors-api-test-suite-in-ie8/ Resig, J. (2008). Selectors that people actually use. Opgehaald van http://ejohn.org/blog/selectors-that-people-actually-use/ Resig, J. (sd). selectorTest. Opgehaald van http://ejohn.org/apps/selectortest/ Resig, J. (2008). The Performance Paradox. Opgehaald van http://ejohn.org/blog/theperformance-paradox/ Resig, J. (2008). Thoughts on querySelectorAll. Opgehaald van http://ejohn.org/blog/thoughts-on-queryselectorall/ Rojas, J. (2008). Evaluation of JavaScript Libraries. Opgehaald van http://wiki.freaksunidos.net/javascript-libraries Sanheim, R. (2006). Javascript associative arrays considered harmful. Opgehaald van Ajaxian: http://ajaxian.com/archives/javascript-associative-arrays-considered-harmful Shiran, Y. (2001). JavaScript’s object types. Opgehaald van http://www.webreference.com/js/tips/010306.html
Eindwerk: JavaScript-frameworks
57
Mathias Bynens
Sizzle Selector Engine. (sd). Opgehaald van jQuery: http://docs.jquery.com/Release:jQuery_1.3#Sizzle_Selector_Engine Slide 002: “What is a Framework?”. (sd). Opgehaald van Web Lecture Archive Project: http://wlap.physics.lsa.umich.edu/atlas/computing/tutorials/athena/2002/02/real/sld002.ht m Smith, D. (2008). querySelector and querySelectorAll. Opgehaald van Surfin’ Safari: http://webkit.org/blog/156/queryselector-and-queryselectorall/ Software framework. (sd). Opgehaald van Wikipedia: http://en.wikipedia.org/wiki/Software_framework The Dojo Toolkit. (sd). Opgehaald van http://dojotoolkit.org/ The Yahoo! User Interface Library (YUI). (sd). Opgehaald van Yahoo! Developer Network: http://developer.yahoo.com/yui/ Theurer, T. (2007). Performance Research, Part 2: Browser Cache Usage – Exposed! Opgehaald van Yahoo! User Interface Blog: http://yuiblog.com/blog/2007/01/04/performance-research-part-2/ Upfold, P. (2007). The differences between the GPL, LGPL and the BSD. Opgehaald van FOSSwire: http://fosswire.com/post/2007/4/the-differences-between-the-gpl-lgpl-and-thebsd/ Velichkov, P. (2009). MooTools vs. jQuery vs. Prototype vs. YUI vs. Dojo comparison revised. Opgehaald van Peter Velichkov’s Blog: http://blog.creonfx.com/javascript/mootools-vsjquery-vs-prototype-vs-yui-vs-dojo-comparison-revised W3C. (2008). Selectors API. Opgehaald van http://www.w3.org/TR/selectors-api/ Why does everyone like jQuery more than Prototype/script.aculo.us or MooTools or whatever? (2008). Opgehaald van Stack Overflow: http://stackoverflow.com/questions/176324 Willison, S. (2003). getElementsBySelector(). Opgehaald van Simon Willison’s Weblog: http://simonwillison.net/2003/Mar/25/getElementsBySelector/ XML DOM Browser Differences. (sd). Opgehaald van W3Schools: http://w3schools.com/Dom/dom_mozilla_vs_ie.asp
Eindwerk: JavaScript-frameworks
58
Mathias Bynens
ydn-javascript · Yahoo! User Interface Library Group. (sd). Opgehaald van Yahoo! Groups: http://tech.groups.yahoo.com/group/ydn-javascript/ YUI Library: Open Source JavaScript & CSS. (sd). Opgehaald van http://yuilibrary.com/ YUI Loader Utility. (sd). Opgehaald van Yahoo! UI Library: http://developer.yahoo.com/yui/yuiloader/
Eindwerk: JavaScript-frameworks
59
Mathias Bynens
Bijlagen Als bijlage voeg ik onder andere enkele officiële documenten met betrekking tot dit eindwerk toe. 1. 2. 3. 4.
Gebruikt configuratiebestand voor SlickSpeed MIT-licentie van SlickSpeed Voorstel eindwerkonderwerp Logboek
Eindwerk: JavaScript-frameworks
60
Mathias Bynens
Bijlage 1: Gebruikt configuratiebestand voor SlickSpeed ; Dit bestand wordt gebruikt op http://eindwerk.mathiasbynens.be/ ; ; Per framework omvat dit configuratiebestand drie regels: ; 1) De naam van het framework; ; 2) De bestandsnaam van het framework; ; 3) De functienaam van de CSS selector die het framework gebruikt. [Prototype 1.6.1 RC2] file = "prototype.js" function = "$$" [MooTools 1.2.2] file = "mootools.js" function = "$$" [jQuery 1.3.2] file = "jquery.js" function = "jQuery" [Dojo Base 1.3.0] file = "dojo.js" function = "dojo.query" [YUI 2.7.0] file = "yui.js" function = "YAHOO.util.Selector.query" ; Zoals besproken in het eindwerk, is Sizzle niet echt een 'framework'; ; eerder een stand-alone CSS selector engine. ; Het is dan ook louter ter vergelijking opgenomen in deze testcase. [Sizzle 1.0] file = "sizzle.js" function = "Sizzle" ; Zoals besproken in het eindwerk, is de Selectors API geen 'framework', ; maar een stand-alone CSS selector engine dat native in moderne ; browsers is ingebouwd. ; Het werd dan ook louter ter vergelijking opgenomen in deze testcase. [Selectors API] file = "dummy.js" ; Leeg bestand function = "document.querySelectorAll"
Eindwerk: JavaScript-frameworks
61
Mathias Bynens
Bijlage 2: MIT-licentie van SlickSpeed Hoewel te betwisten valt of bovenstaand configuratiebestand een “substantieel aandeel” van de SlickSpeed-testsuite is (zie cursieve tekst), voeg ik de gebruikte licentie toe als bijlage. The MIT License Copyright (c) 2006-2009 Valerio Proietti, http://mad4milk.net/ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Eindwerk: JavaScript-frameworks
62
Mathias Bynens
Bijlage 3
Voorstel eindwerkonderwerp 2008-2009 Uiterste indiendatum: maandag 3 november 2008 STUDENT: BYNENS MATHIAS
1. Eindwerkonderwerp Titel: JavaScript-frameworks Subtitel: Een vergelijkende studie van de bekendste JavaScript-frameworks, alsook de invloed van het gebruik ervan op de JavaScript-code die webontwikkelaars schrijven Motivatie: Waarom heb je dit onderwerp gekozen? De laatste tijd worden er meer en meer van deze frameworks ontwikkeld; het gaat zelfs zo ver dat JavaScript-beginners de echte scripttaal niet meer leren kennen, maar enkel het framework beheersen. Het lijkt me interessant dit nader te onderzoeken. Welke invloeden heeft dit op het internet, op de eindgebruikers van websites, op de kennis van de oorspronkelijke scriptingtaal bij scripters, op de JavaScript-codeurs in het algemeen en op de onderhoudbaarheid / leesbaarheid van onze code? Verder zou ik ook willen ingaan op de verschillen tussen de meest gekende frameworks, zoals jQuery, MooTools of Prototype. Zijn er opmerkelijke verschillen? Op welke manier breiden deze de oorspronkelijke scriptingtaal uit? Het zou voor mij ook zeer leerrijk zijn om dit onderwerp te behandelen, aangezien ik (net als de gemiddelde gebruiker) slechts ervaring heb met de gewijzigde syntax van de verschillende frameworks. Op vlak van JavaScript en scripting in het algemeen zou het voor mij zeker en vast een vernieuwende ervaring betekenen om verder dan alleen dat te gaan, en dit voor niet één, maar voor meerdere frameworks. Tevens kadert dit ook in mijn stageproject. Deze week kreeg ik immers het voorstel van m’n stagebedrijf om tijdens mijn stageperiode te werken aan een WYSIWYG form-editor. Hiermee zou je via HTML, CSS, JavaScript (met Ajax) en PHP op eenvoudige wijze en zonder technische kennis een formulier kunnen samenstellen met invoervakken, grote tekstvelden, checkboxes en selectieknopjes. Zowel via JavaScript als PHP zou hier dan validatie op moeten toegepast worden. Het lijkt me evident om in dit geval gebruik te maken van een JavaScript-framework. Dit eindwerkonderwerp zou me perfect kunnen voorbereiden op deze opdracht, alsook m’n kennis van JavaScript vergroten, hetgeen ook mooi meegenomen is. Verduidelijk je subtitel! Mijn subtitel geeft een vrij duidelijk beeld van hoe het eindwerk er inhoudelijk zal uitzien. Wie zich door de hoofdtitel aangesproken voelt, weet na het lezen van de subtitel meteen of mijn eindwerk hem werkelijk zal interesseren.
2. Inhoud / uitwerking Structuur: welke items komen aan bod? Onderzoek: wat wil je concreet onderzoeken via een praktische toepassing?
Voorstel eindwerkonderwerp
1
Mathias Bynens
Bijlage 3
3. Externe Promotor Naam: Krijn Hoetmer Motivatie: Wie is je promotor en waarom heb je deze persoon gekozen? Krijn Hoetmer is een zeer ervaren webontwikkelaar uit Nederland. Hij houdt zich niet alleen bezig met de front-end-ontwikkeling (HTML, CSS, JavaScript) van websites, maar ook met back-end-programmering ervan (PHP, MySQL, Ruby on Rails, ASP.NET…). Ook wat dit laatste betreft, zijn z’n vaardigheden groot; zo heeft hij onder de naam Qontent z’n eigen Content Management System (CMS) geschreven. Met Qontent sponsort hij Fronteers. Dit is een Nederlandse vakvereniging voor webontwikkelaars, maar dan met een grotere serieux dan pakweg FeWeb. Fronteers organiseert regelmatig bijeenkomsten waarbij ook niet-leden welkom zijn. Meestal gaan deze meetings gepaard met enkele presentaties over de nieuwste technieken op het vlak van webontwikkeling. In september dit jaar vond er ook een tweedaags Fronteers-congres plaats, met internationale sprekers zoals Pete LePage van Microsoft, Bert Bos van het W3C, Chris Heilmann van Yahoo, JavaScript-goeroes Dean Edwards (gekend van onder meer JSframework base2) en Tom Occhino (van JS-framework MooTools). Ook ikzelf was ondanks de (voor een student) vrij hoge kostprijs aanwezig, en het was dankzij de vele sessies over JavaScript aldaar dat ik het idee kreeg om dit onderwerp te behandelen. Meneer Hoetmer zit als vrijwilliger in de organisatie van Fronteers, en is omwille van zijn technische kennis en vaardigheden internationaal gerespecteerd in webontwikkelaarskringen. Het toeval wil overigens dat ik indirect via hem (namelijk door één van z’n sites te bezoeken) kennis maakte met JavaScript-frameworks. Naar mijn mening is hij de geknipte persoon om een objectieve analyse te maken van een eindwerk over JavaScript-frameworks. Tevens heb ik het gevoel dat ik veel kan bijleren van hem, en dat zijn ervaring dus voor een deel zal bijdragen aan m’n eindwerk.
4. Interne Promotor Naam: Ann Audenaert Motivatie: Eventuele voorkeur voor een interne promotor. In de mate van het mogelijke wordt getracht bij toewijzing hiermee rekening te houden. Mevrouw Ann Audenaert is jarenlang mijn lector Webtechnologie geweest aan deze school. Gezien haar kennis van JavaScript meen ik dat zij de ideale persoon is om m’n eindwerk op te volgen.
Gedeelte voorzien voor de eindwerkcoördinator DATUM INDIENING: STATUS: OPMERKINGEN / SUGGESTIES:
Voorstel eindwerkonderwerp
2
Mathias Bynens
Bijlage 4
LOGBOEK EINDWERK MMP 08-09 Student: Mathias Bynens Onderwerp: JavaScript-frameworks Externe promotor: Krijn Hoetmer Interne promotor: Ann Audenaert datum
actie
inhoud
to do
opmerkingen
09-10-2008
Briefing
Afspraken rond keuze eindwerkonderwerp
Deadline: 3 november
18-10-2008
Mail naar Ann Audenaert Mail naar Krijn Hoetmer Schrijven
Aanvraag tot interne promotor
Onderwerpkeuze uitwerken op basis van briefing Antwoord afwachten
Aanvraag tot externe promotor
Antwoord afwachten
Gemotiveerd voorstel voor eindwerkonderwerp Krijn Hoetmer is bereid m'n externe promotor te worden. Hij stelt zelf voor de communicatie hoofdzakelijk via internet (email, chat...) te laten verlopen, gezien hij in Nederland woont, maar sluit een 'real-life' ontmoeting niet uit. Mevrouw Audenaert is bereid m'n interne promotor te worden. Gezien ze wegens persoonlijke redenen vanaf januari niet op school aanwezig kan zijn, stelt ze voor de communicatie hoofdzakelijk via e-mail te laten gebeuren. Eindwerkcontract opstellen, gegevens van contactpersonen aanvullen Ik vraag hoe we, gezien de situatie, de
Goedkeuring afwachten
18-10-2008 18-10-2008 18-10-2008
Mail van Krijn Hoetmer
19-10-2008
Mail van Ann Audenaert
15-12-2008
Formulier invullen
07-01-2009
Mail naar Ann
Logboek eindwerk MMP
1
Antwoord sturen met bedanking
Naar DiLeAHS-dropbox verstuurd om 22:07 Ik verstuurde mijn antwoord op 19 oktober om 08:43.
Antwoord sturen met bedanking
Ik verstuurde mijn antwoord diezelfde dag om 17:33.
Document vier maal afdrukken en laten ondertekenen door alle betrokkenen Antwoord afwachten
Naar DiLeAHS-dropbox verstuurd om 09:43
Mathias Bynens
Bijlage 4 Audenaert 07-01-2009
Mail van Ann Audenaert
11-01-2009
Mail naar Krijn Hoetmer
12-01-2009
Mail van Krijn Hoetmer
12-01-2009
Indienen eindwerkcontract
15-01-2009
Fax naar Krijn Hoetmer
21-01-2009
Fax van Krijn Hoetmer
24-01-2009
Eindwerkcontract aan Tom Neuttiens bezorgen Interview met Krijn Hoetmer
04-02-2009
20-02-2009
Eindwerkcontract
Logboek eindwerk MMP
ondertekening van het eindwerkcontract best zouden kunnen regelen. Mevrouw Audenaert laat weten dat ik de documenten voor haar 'in opdracht' mag tekenen. Ik vraag hoe we, gezien de situatie, de ondertekening van het eindwerkcontract best zouden kunnen regelen. Eerder die week had ik dit probleem reeds aangekaart via chatberichten. Hoewel meneer Hoetmer toen al vermeldde dat ik de documenten eventueel voor hem 'in opdracht' kon tekenen, vroeg ik hiervan bij dezen nog schriftelijke bevestiging, teneinde juridisch in orde te zijn. Meneer Hoetmer laat weten dat ik de documenten voor hem 'in opdracht' mag tekenen. Meneer Neuttiens heeft liever niet dat er 'in opdracht' van de externe promotor wordt getekend, en aanvaardt m'n contracten niet. Ik fax het eindwerkcontract naar meneer Hoetmer, zodat hij het kan ondertekenen en terugfaxen. Meneer Hoetmer heeft het contract ondertekend en doorgefaxt. Ik bezorg het eindwerkcontract aan Tom Neuttiens, zodat hij zijn handtekening kan toevoegen. Op basis van de reeds opgestelde structuur en te behandelen items, stel ik m’n externe promotor enkele vragen. Meneer Neuttiens heeft als laatste het
Afgedrukte exemplaren van het eindwerkcontract ondertekenen Antwoord afwachten
Afgedrukte exemplaren van het eindwerkcontract ondertekenen Een andere manier zoeken om de documenten van de nodige handtekening te voorzien: via de post, of via fax Antwoord afwachten
Eindwerkcontract aan meneer Neuttiens bezorgen, zodat hij zijn handtekening kan toevoegen. Reactie afwachten
Ik heb bijzonder nuttige informatie verkregen, dewelke ik nu kan verwerken in het eindwerk.
2
Mathias Bynens
Bijlage 4
10-03-2009
ondertekend door Tom Neuttiens Evaluatie voorlopige versie met Krijn Hoetmer
15-03-2009
Mail naar John Resig
17-03-2009
Tussentijdse evaluatie
18-03-2009
Evaluatie voorlopige versie met Krijn Hoetmer
18-03-2009
Mail van John Resig
18-03-2009
Tussentijdse evaluatie
20-04-2009
Mail naar Ann Audenaert
20-04-2009
Mail van Ann
Logboek eindwerk MMP
contract ondertekend, en bezorgt de documenten nu terug aan mij. Mijn externe promotor overloopt de nieuwste versie van mijn eindwerk, en brengt vele verbeteringen en suggesties voor aanvullingen aan. Ik mail de lead developer van het jQueryframework en vraag naar enige statistieken i.v.m. de omvang en activiteit van de jQuery-community, aangezien deze de grootste community van alle JSframeworks lijkt. Ik drop de voorlopige versie van m’n eindwerk samen met dit logboek op DiLeAHS. Mijn externe promotor overloopt de voorlopige versie van mijn eindwerk, en brengt vele verbeteringen aan, zowel grammaticaal als op inhoudelijk. Helaas beschikt hijzelf niet over gegevens die ik nog niet had. Hij geeft wel een link naar de download-teller van jQuery op Google Code, maar vermeldt erbij dat deze data onbruikbaar is, aangezien het niet enkel downloads telt maar ook mensen die het bestand ‘hotlinken’. Ik drop de verbeterde voorlopige versie van m’n eindwerk samen met dit logboek op DiLeAHS. (De deadline is pas vanavond om 23u59.) Aangezien ik nog steeds geen reactie heb gekregen op mijn tussentijdse eindwerkversie, vraag ik nog eens specifiek naar een reactie. Mijn interne promotor laat weten nog geen
3
Verbeteringen doorvoeren, opzoekingswerk verrichten i.v.m. aanvullingen en verwerken in de tekst. Antwoord afwachten
Feedback afwachten
Naar DiLeAHS-dropbox verstuurd om 22:40.
Foutjes verbeteren, suggesties bewaren om later in het eindwerk te verwerken.
Andere manier zoeken om te peilen naar communitygrootte en -activiteit
Feedback afwachten
Naar DiLeAHS-dropbox verstuurd om 16:02.
Antwoord afwachten
Feedback afwachten
Mathias Bynens
Bijlage 4 Audenaert
26-03-2009
Evaluatie voorlopige versie met Krijn Hoetmer
27-04-2009
Mail naar Ann Audenaert Mail van Ann Audenaert
27-04-2009
02-05-2009
Evaluatie voorlopige versie met Krijn Hoetmer
03-05-2009
Evaluatie laatste versie met Krijn Hoetmer
tijd te hebben gehad om de voorlopige versie van mijn eindwerk te lezen. Ze belooft er zo snel mogelijk naar te kijken en haar bemerkingen door te sturen. Mijn externe promotor overloopt de nieuwste versie van mijn eindwerk, en brengt vele verbeteringen en suggesties voor aanvullingen aan. Ik mail de nieuwste versie van mijn eindwerk naar mijn interne promotor. Mijn interne promotor overloopt de voorlopige versie van mijn eindwerk, en brengt verbeteringen en suggesties aan. Mijn externe promotor overloopt de nieuwste versie van mijn eindwerk, en brengt vele verbeteringen en suggesties voor aanvullingen aan. Mijn externe promotor overloopt de nieuwste versie van mijn eindwerk, en brengt nog enkele verbeteringen en suggesties voor aanvullingen aan.
Verbeteringen doorvoeren, opzoekingswerk verrichten i.v.m. aanvullingen en verwerken in de tekst. Feedback afwachten Verbeteringen doorvoeren.
Verbeteringen doorvoeren, opzoekingswerk verrichten i.v.m. aanvullingen en verwerken in de tekst. Verbeteringen doorvoeren, opzoekingswerk verrichten i.v.m. aanvullingen en verwerken in de tekst.
VERDUIDELIJKING BIJ DIT DOCUMENT Datum: datum van actie Actie: omschrijving van actie: bezoek, meeting, tel, briefings, mail met/naar … (indien nodig: vermelden naar of met wie actie gebeurde) Inhoud: korte omschrijving van wat de actie opleverde, inhield. To do: gevolgtrekking uit deze actie, te ondernemen actie na deze actie. Opmerkingen: belangrijke gegevens (tel nr, nieuwe gemaakte afspraak voor latere datum) vul dit document na elke belangrijke actie verder aan en bewaar onder je naam. Dit document kan ten allen tijde opgevraagd worden en wordt als addendum aan je eindwerk toegevoegd.
Logboek eindwerk MMP
4
Mathias Bynens