zurück zum Artikel

jQuery 1.4 setzt auf Tempo

Daniel Koch

Längst hat sich jQuery zu einem der beliebtesten und meistgenutzten JavaScript-Frameworks entwickelt. Die aktuelle Version 1.4 implementiert zahlreiche Neuerungen. Darüber hinaus soll sie aber vor allem eines sein: deutlich schneller als ihre Vorgänger.

Längst hat sich jQuery zu einem der beliebtesten und meistgenutzten JavaScript-Frameworks entwickelt. Die aktuelle Version 1.4 implementiert zahlreiche Neuerungen. Darüber hinaus soll sie aber vor allem eines sein: deutlich schneller als ihre Vorgänger.

Vier Jahre ist es seit der Veröffentlichung der ersten jQuery-Version her. Wer die letzten Major-Releases des Frameworks beobachtet hat, konnte feststellen, dass es jedes Mal signifikante Überarbeitungen gab. Beispielsweise führte jQuery 1.3 Sizzle und die .live()-Methode für das Eventhandling ein. Zu den enormen Veränderungen der neuen Version zählen nicht nur zusätzliche Methoden und Funktionen, gerade auch die Performanceverbesserungen sprechen für jQuery 1.4.

Aus dem geplanten kleinen Release ist eine vollwertige neue jQuery-Version geworden. Gerade der Aspekt wirft die berechtigte Frage nach Inkompatibilitäten auf, die bei einem Umstieg von jQuery 1.3 auf die 1.4er-Version auftreten können. Darauf geht der Artikel noch genauer ein, so viel aber bereits hier: In der Tat muss man einige Dinge beim Upgrade beachten. Das gilt jedoch nicht für die breite Masse der Webentwickler, da die Inkompatibilitäten allein im Zusammenhang mit Funktionen und Anwendungen auftreten, die nicht weit verbreitet sind. Sollte es dennoch zu Problemen kommen, gibt es ein Plug-in, das die Entwickler speziell für den Zweck entwickelt haben.

Die Website zum 1.4er-Release

Einen ersten Eindruck zum neuen Framework kann man sich auf der eigens eingerichteten Website "The 14 Days of jQuery [1]" verschaffen. Sie riefen die jQuery-Entwickler während der finalen Entstehungsphase ins Leben. Über 14 Tage hinweg konnte man dort täglich Neuigkeiten rund um das anstehende Release erfahren. Zu ihren Höhepunkten gehören sicherlich die detaillierten Performancevergleiche und die wichtige Neuerungen vorstellenden HD-Videos.

Die neue Version lässt sich wie üblich von der offiziellen Website [2] herunterladen. Ebenso bietet sie Googles AJAX Library [3] an, und zwar komprimiert [4] und unkomprimiert [5]. Einbinden lässt sich das Framework von dort zum Beispiel folgendermaßen:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/
jquery/1.4.0/jquery.min.js"></script>

Selbstverständlich kann man jQuery auf seinem eigenen Server hosten und direkt von dort in seine Seiten einbinden. In der Hinsicht hat sich nichts im Vergleich zur Vorgängerversion verändert.

Im Zusammenhang mit JavaScript-Frameworks bringen Kritiker immer wieder einen Punkt ins Spiel: Durch den Einsatz solcher Frameworks sinkt die Performance der Seite. Gerade auf die Verbesserung der Performance haben die jQuery-Entwickler daher ihr Augenmerk gelenkt, und das Ergebnis weiß zu überzeugen. Vor allem die meistgenutzten Methoden haben sie deutlich weniger komplex gestaltet.

Laut den Core-Entwickler wurden die internen Funktionsaufrufe beliebter jQuery-Methoden teilweise von ursprünglich knapp 30.000 auf circa 500 verringert. Daraus resultieren deutliche Geschwindigkeitsvorteile. Beispielsweise soll die Methode .html() dreimal schneller sein als in jQuery 1.3. Viermal schneller verhalten sich die beiden Methoden .remove() und .empty(). Positiv wirkt sich zudem das Cachen von HTML-Fragmenten aus.

Auf "14 Days of jQuery" finden sich einige Performancetests, über die sich die versprochenen Geschwindigkeitsvorteile anhand standardisierter Tests nachprüfen lässt. Insgesamt stehen vier Testvarianten zur Auswahl:

Die Tests basieren auf dem bekannten SlickSpeed [10]-Framework. Zudem weisen die jQuery-Entwickler explizit darauf hin, dass sie ausschließlich solche Selektoren in die Tests einbezogen haben, die in der Praxis relevant sind. Um welche Selektoren es sich handelt, beschreibt John Resig – seines Zeichens "Erfinder" von jQuery – in dem Blogeintrag "Selectors that People Actually Use [11]".

Die bessere Performance wirkt sich auf nahezu alle Teile von jQuery aus. Teils dramatische Verbesserungen gibt es bei den folgenden Methoden:

Im Vergleich zu den Vorgängerversionen fällt auf, dass vor allem .empty(), .html(), addClass() und removeClass() deutlich schneller sind. Zudem zeigen erste Benchmark Tests, wie schlecht die Performance ist, wenn man DOM-Elemente in einen Container einfügt, in dem Elemente bereits enthalten sind. Schneller ist hingegen das Hinzufügen von Elementen in einen leeren Container. Und noch etwas ist deutlich performanter geworden: Dass das Löschen von Elementen an die Ereignisse gebunden ist.

Interessant sind auch die Geschwindigkeitsunterschiede zwischen den einzelnen Browsern. Wie deutlich sie ausfallen, zeigt Tino Dietel in seinem Blog [12]. Dort werden die teils dramatischen Performanceverluste deutlich, die Benutzer des Internet Explorer 6 in Kauf nehmen müssen, wenn in der jQuery-Anwendung bestimmte Methoden verwendet werden. So dauert der Aufruf von .empty() im IE6 sechsmal länger als in Googles Chrome und 20-mal länger als im Firefox.

Auch wenn die Geschwindigkeitsvorteile im Einzelnen gering erscheinen mögen, gerade bei komplexeren Anwendungen sind sie durchaus mess- und spürbar. (Wenngleich man nicht übersehen darf, dass Performanceeinbußen oftmals andere Ursachen als die hohe Anzahl jQuery-interner Funktionsaufrufe haben.)

Hinsichtlich der Events beziehungsweise der Ereignisbehandlung gibt es ebenfalls einige Neuerungen. Interessant ist vor allem die Methode jQuery.proxy(). Vergleichbar ist jQuery.proxy() mit der aus Prototype bekannten [13] bind()-Funktion. Ein Beispiel:

<script type="text/javascript">
/* <![CDATA[ */
$(document).ready(function() {
var obj = {
programm: "Writer",
ausgabe: function() {
alert( this.programm );
$("#bereich").unbind("click", obj.ausgabe);
}
};
//Beide Varianten funktionieren
$("#bereich").click( jQuery.proxy( obj, "ausgabe" ) );
$("#bereich").click( jQuery.proxy( obj.ausgabe, obj ) );
});
/* ]]> */
</script>

Der jQuery.proxy()-Methode übergibt der Webentwickler eine Funktion, deren Kontext er verändern möchte.

jQuery.proxy( Funktion, Kontext )

Die beiden Ereignisse .change() und .submit() wurden normalisiert. Somit verhalten sie sich endlich in allen gängigen Browsern gleich. Um das zu erreichen, hat man das Standardverhalten des Internet Explorer überschrieben. Einen solchen Cross-Browser-Support gibt es übrigens jetzt auch für .focusin(), .focusout(), .mouseenter() und .mouseleave(). Mit ersteren beiden haben die Entwickler zwei neue Events eingeführt. Sie sind größtenteils mit .focus() und .blur() identisch. Die Entwickler haben sie hauptsächlich deswegen eingeführt, um Entwicklern das Schreiben eigener Events zu erleichtern.

Durch die neue .dtach()-Methode lassen sich Elemente aus dem DOM entfernen. Das Besondere dabei: Die an die Elemente gebundenen Eventhandler bleiben hiervon unberührt. Zu erkennen ist das beispielsweise, wenn man ein Element lediglich vorübergehend aus dem DOM löschen möchte. Ebenfalls neu ist die Methode .unwrap(), mit der sich die ein Kindelement umschließenden Elternelemente entfernen lassen. Die Methoden .before(), .after() und .replaceWith() lassen sich nun auf Elemente anwenden, die nicht Teil des DOM sind.

Die meisten Events – Ausnahmen bilden lediglich .ready(), .focus() und .blur() – lassen sich als Live-Events nutzen. Sie sind Ereignisse, die sich an alle aktuellen und künftigen Elemente binden lassen. Vor allem die Optionen, die die .live()-Methode zu bieten hat, haben die Entwickler deutlich erweitert. So unterstützt jQuery jetzt Events, die nicht bubbeln. Außerdem können Programmierer explizit festlegen, welchen DOM-Elementen der Eventlistener hinzuzufügen ist. Die .live()-Methode stößt allerdings nicht überall auf Gegenliebe. Vor allem die mangelnde Dokumentation hat Kritik nach sich gezogen – obwohl man zugeben muss, dass sich die Methode vergleichsweise schwer erklären und dokumentieren lässt. Die Kritiker sind der Meinung, sie führe in zahlreichen jQuery-Anwendungen zu fehlerhaftem Code. Allerdings haben die Entwickler die Dokumentation bereits angepasst. Dort sind die Unterschiede zwischen der alten

.live( eventType, handler )

und der neuen Syntax

.live( eventType, eventData, handler )

deutlich zu sehen. Das Problem dürfte ohnehin weniger die Methode an sich als vielmehr das Event-Bubbling-Thema im Allgemeinen sein.

Man kann seit einiger Zeit eine Funktion via .attr() übergeben und den Rückgabewert der Funktion in das Attribut aufnehmen. Die Funktion wurde nun auf alle Setter-Funktionen erweitert. Es handelt sich um .css(), .attr(), .val(), .html(), .text(), .append(), .prepend(), .before(), .after(), .replaceWith(), .wrap(), .wrapInner(), .offset(), .addClass(), .removeClass() und .toggleClass(). Da Setter-Methoden eigene Funktionen enthalten können, lassen sich die Rückgabewerte der Funktionen direkt verarbeiten, sie sind nicht wie bisher zunächst zwischenzuspeichern.

Wer Erfahrung mit PHP und Ruby hat, kennt die Arbeit mit verschachtelten (nested) Parametern. In jQuery 1.3 erfolgte die Seralisierung von {foo: ["eins", "zwei"]} durch foo=eins&foo=zwei. Die Serialisierungsvariante funktionierte in der Form, allerdings konnten Single-Element-Arrays den Ansatz nicht nutzen. Durch die neuen verschachtelten Parameter kann man {foo: ["eins", "zwei"]} als "foo[]=eins&foo[]=zwei" serialisieren. Insgesamt gibt es drei unterschiedliche Serialisierungsvarianten:

// Für alle Serialsierungen
jQuery.ajaxSettings.traditional = true;
// Für eine einzelne Serialisierung
jQuery.param( stuff, true );
// Für einen einzelnen Ajax-Request
$.ajax({ data: stuff, traditional: true });

Wer die alte Serialisierungsart benötigt, kann sie auch in jQuery 1.4 nutzen. Dazu muss man lediglich auf die traditionellen Ajax-Einstellungen umschalten, was am einfachsten über jQuery.ajaxSettings.traditional geht. Hinsichtlich der Ajax-Unterstützung stellt die neue Version zusätzliche Funktionen bereit, mit deren Hilfe man deutlich komfortabler als bisher auf DOM-Elemente zugreifen und sie manipulieren kann. Zudem erkennt jQuery automatisch, wenn es sich bei Antworten auf Ajax-Requests um ausführbaren JavaScript-Code oder um JSON (JavaScript Object Notation) handelt. Dank des ebenfalls unterstützten ETags kann der Entwickler mit ifModified: true endlich überprüfen, ob die entsprechende Datei oder das Dokument seit dem letzten Aufruf überhaupt verändert wurden. Selbstverständlich ließ sich JSON in anderen jQuery-Versionen nutzen. jQuery 1.4 geht auf dem Gebiet aber einen Schritt weiter. Denn stellt der Browser einen nativen JSON-Parser bereit, nutzt jQuery ihn. Zusätzlich überprüft jQuery ankommendes JSON, was fehlerhafte Aufrufe verhindern soll.

Um ein striktes Parsen zu erzwingen, verwendet man jQuery.getJSON(). jQuery erkennt JSON automatisch, wodurch es nicht mehr explizit im dataType anzugeben ist.

Auch das Auswählen bestimmter Elemente haben die Entwickler vereinfacht. Zu dem Zweck stehen unter anderem die Methoden .nextUntil(), .prevUntil() und .parentsUntil() zur Verfügung. .nextUnitl() ermittelt alle nachfolgenden Geschwister der einzelnen Elemente, allerdings nicht das, das der Selektor ausgewählt hat. Ähnlich arbeitet .prevUntil(). Darüber lassen sich alle vorhergegangenen Geschwister der einzelnen Elemente ermitteln. Hier ist das Element wieder ausgeschlossen, das der Selektor direkt angesprochen hat. Über .nextUntil() kann man die Vorfahren jedes Elements bestimmen. Allerdings gilt auch bei der Methode: Das durch den Selektor ausgewählte Element bleibt außen vor. Mit .hash() gibt es eine Methode, die vom gleichnamigen Filter abstammt. Interessant gestaltet sich hier der Umgang mit Selektoren. Denn genauso wie .toggleClass() kann man nun bei .closet() mehrere Selektoren anwenden.

Mit .delay() haben die Entwickler eine Methode in das Framework aufgenommen, dank der man Animationen pausieren lassen kann. Dabei lässt sich die Dauer der Verzögerung explizit festlegen. Erlaubt sind Millisekunden-Angaben sowie die beiden Strings fast und slow. Wichtig ist .delay() zum Beispiel für das Einfügen einer Verzögerung zwischen dem Ein- und Ausblenden von Elementen.

$("bereich").click(function() {
$("div.ueberschrift").slideUp(300).delay(800).fadeIn(300);
$("div.kapitel").slideUp(300).fadeIn(400);
});

Und noch etwas wurde hinsichtlich der Effekte getan: In Animationen lassen sich einzelnen Eigenschaften einzelne Effekte hinzufügen. Dadurch gestaltet sich die Arbeit mit den Effekten deutlich flexibler.

Intern hat sich einiges getan. Die Entwickler haben etwa den Framework-Code auf eine verständlichere Basis gestellt. Um das zu erreichen, haben sie massive Umstellungen der Code-Basis vorgenommen müssen. Hierzu gibt es nun neue Codierungsrichtlinien, die in den jQuery Core Style Guidelines [14] zusammengefasst sind. Neben der Anwendung der Richtlinien hat man am Basis-Code umfangreiche Umstrukturierungen realisiert. So findet sich zum Beispiel die alte core.js – das Herzstück früherer jQuery-Versionen – in mehrere Dateien aufgeteilt. Bei ihnen handelt es sich um attribute.js, css.js, data.js, manipulation.js, traversing.js und queue.js. Darüber hinaus nahmen die Core-Entwickler das .ready()-Event in den jQuery-Kern mit auf.

jQuery 1.4 deckt deutlich mehr Tests ab. So kam jQuery 1.3.2 mit 1504 Tests daher, wohingegen jQuery 1.4 immerhin 3060 Tests erfüllt. Dabei besteht es die Tests in allen relevanten Browsern. Das sind Safari 3.2, 4 und höher, Firefox 2, 3, 3.5 und höher, Internet Explorer 6, 7 und 8 sowie Opera 10.10 und Chrome.

Für Entwickler, die auf ihren Seiten die Vorgängerversion 1.3 einsetzen, stellt sich die Frage nach der Rückwärtskompatibilität. Laufen alle Funktionen nach dem Umstieg auf jQuery 1.4? Prinzipiell lässt sich sagen, dass jQuery 1.4 durchaus rückwärtskompatibel ist. Es dürfte auf den meisten Webseiten nach dem Umstieg auf die neue Version keine Probleme geben. Bei genauerer Betrachtung gibt es aber Aspekte, auf die man achten sollte.

Trotz der Punkte lässt sich festhalten: jQuery 1.4 ist größtenteils rückwärtskompatibel, und der Umstieg auf die neue Version sollte auf nahezu allen Webseiten problemlos vonstatten gehen. Gibt es dennoch Schwierigkeiten, hilft das Plug-in jquery-compat-1.3 [15] weiter. Es handelt sich um ein Rückwärtskompatibilitäts-Plug-in für den Umstieg von jQuery 1.3 auf die Version 1.4.

Die neue jQuery-Version ist gelungen, keine Frage. Neue Methoden, Funktionen und Events erweitern die ohnehin große Anzahl an Fähigkeiten des Frameworks deutlich. Zudem tragen erweiterte Ajax-Funktionen und die deutlichen Performancesteigerungen zum positiven Gesamtbild bei. Auch der Aspekt der Rückwärtskompatibilität spricht für den Einsatz der 1.4er-Version. Denn gerade auf dem Gebiet hat man darauf geachtet, dass die, die jQuery letztlich einsetzen, durch ein Update so wenige Probleme wie möglich haben.

Daniel Koch
arbeitet als freiberuflicher Entwickler und Autor.

(ane [16])


URL dieses Artikels:
https://www.heise.de/-948638

Links in diesem Artikel:
[1] http://jquery14.com/
[2] http://jquery.com/
[3] http://code.google.com/intl/de-DE/apis/ajaxlibs/
[4] http://ajax.googleapis.com/ajax/libs/jquery/1.4.0/jquery.min.js
[5] http://ajax.googleapis.com/ajax/libs/jquery/1.4.0/jquery.js
[6] http://ejohn.org/files/jquery1.4/slick/?type=attr
[7] http://ejohn.org/files/jquery1.4/slick/?type=class
[8] http://ejohn.org/files/jquery1.4/slick/?type=dom
[9] http://ejohn.org/files/jquery1.4/slick/?type=empty
[10] http://mootools.net/slickspeed/
[11] http://ejohn.org/blog/selectors-that-people-actually-use/
[12] http://blog.projekt2k.de/2010/01/benchmarking-jquery-1-4/
[13] http://www.prototypejs.org/api/function/bind
[14] http://docs.jquery.com/JQuery_Core_Style_Guidelines
[15] http://github.com/jquery/jquery-compat-1.3
[16] mailto:ane@heise.de