für die Untoten

Seit Jahren dreht sich Frontend-Code nicht mehr um den IE6. Um halbwegs sauber zu coden und für Kunden und ihren IE6 ein vorzeigbares Ergebnis zu haben, empfiehlt es sich zu Dean Edwards IE7.js zu greifen. Im Nachgang sollte man allerdings so weit möglich mit CSS und Conditional Comments nacharbeiten.

Dann ist allerdings das Javascript viel zu fett und wenigstens im IE6 auch viel zu langsam. Und weil das Javascript nichts anderes als DOM-Manipulation macht und jQuery darin auch ganz gut ist, kann man sich ein eigenes IE7.js ganz schnell aus jQuery bauen.

Ich habe lange gerätselt, warum das Script bei komplexen Seiten derartig langsam ist. Der Grund sind imho beinahe ausschließlich Schreibprozesse, also das Hinzufügen von DOM-Nodes, hauptsächlich verursacht von den Pseudoklassen :after und :before. Sie weglassen ist keine Alternative, ich arbeite noch an einer Optimierung. Die Grundsätzliche Funktion des Scripts ist ziemlich einfach:


$.get(stylesheetUrl, function(data){
parsen(data);
});

Anders als die Stylesheets nachzuladen kommt man leider nicht an das komplette Stylesheet heran.


function parsen(data){
var lines = data.match(/[\s\w#,-\.>:]+:[\s\w#,-\.>:]+{[\w\W]+?}/gmi);
$.each(lines, function(i,val){
var style = val.split("}");
$.each(style[0].split(","), function(i,val){
if (val.indexOf(":after")>-1)
$(val.replace(":after", "")).after("<span style='" + style[1].replace("}", "") + "' />");
});
});
}

var line enthält alle Styleanweisungen auf Pseudoklassen. Daraus picken wir uns die :after-pseudoklassen heraus und hängen an die Selektoren ein span-Element mit den Style-Anweisungen. Gibt es eine content Anweisung, empfiehlt es sich, die Zeile umzuschreiben:


$("<span style='" + style[1].replace("}", "") + "' />").insertAfter(val.replace(":after", "")).html(content);

Hier kurz umrissen das weitere Vorgehen. Um wirklich nachhaltig zu arbeiten empfiehlt es sich, in parsen() erstmal ein Style-Object zu erzeugen, über das man dann iteriert.

auch wenns weh tut

Lange habe ich mich gewehrt, den wirklich einfachsten Performance-Trick einzubauen. Jetzt habe ich mich getraut – ich habe meine Javascripte ans Seitenende verbannt. Das hat für eine komplette Site ungefähr 23 Sekunden gedauert. Der gefühlte Geschwindigkeitsgewinn ist unfassbar. Die Seite wird in einem Bruchteil der zuvor benötigten Zeit angezeigt.

Der Geschwindigkeitszuwachs ist aber rein psychischer Natur. Die Seite ist keinesfalls schneller fertiggeladen, sie wird lediglich eher angezeigt. In den allermeisten Fällen sollte das aber auch völlig ausreichen.

zusammenhalten

Sizzle, die neue CSS-Selector-Engine von John Reisig, dem Vater von jQuery, ist für mich ganz klar das neue jQuery-Herz – und ich freue mich drauf. Gerade las ich hier, dass auch Dojo und Prototype mit dem Gedanken spielen, Sizzle einzusetzen. Damit dürften sich die Javascript-Frameworks geschwindigkeitsmäßig und im Funktionsumfang annähern.

Wenn jetzt noch die Browserhersteller …

Javascript nachladen

Viele Seiten setzen inzwischen ziemlich viel Javascript ein. Das kann dazu führen, dass die Seite länger braucht, um angezeigt zu werden. Zum einen, weil eine relativ große Datenmenge heruntergeladen werden muss (leitungsabhängig), zum Anderen, weil das gesamte Script auch noch interpretiert werden muss (hardware- und browserabhängig).

Ich habe begonnen, den Großteil meiner Scripte erst nachzuladen, wenn die Seite fertig gerendert ist. Zum Glück kommt inzwischen oft jQuery und Google-maps zum Einsatz, so dass sich anbietet, den google-Ajax-Loader zu verwenden.

… und die eigenen Scripte?

Beim konsequenten Einsatz von jQuery sollten die eigenen Scripte eigentlich vernachlässigbar kurz sein ;P.
Kommt dennoch mal mehr Code zum Einsatz, könnte man eigentlich auch mehr nachladen. Aktuell sind das bei uns zum Beispiel das Adserverscript, das Statistikscript und unsere eigenen Scripte. Hier wiederum bietet sich an, nur ein winziges Javascript gleich im Seitenkopf einzubetten:

var loadAnyScript = function(url){
    var head = document.getElementsByTagName("head")[0];
    var script = document.createElement("script");
    script.src = url;
    script.type = "text/javascript";
    head.appendChild(script);
    script.onload = function(){
        head.removeChild(script);
    }
};

Für mehrere Scripte bietet sich an, das Ganze noch ein Wenig zu pimpen:

var speedingUpJs = {
    scripts: ["/sript1.js", "script2.js", "http://url1.de/script.js"],
    init: function() {
        for each (script in this.scripts)
            this.loadAnyScript(script);

        // die restliche Initialisierung
    },
    loadAnyScript: function(url){
        var head = document.getElementsByTagName("head")[0];
        var script = document.createElement("script");
        script.src = url;
        script.type = "text/javascript";
        head.appendChild(script);
        script.onload = function(){
            head.removeChild(script);
        }
    }
};

Laut AJAX-API lässt sich sogar das google-Script nachladen.

PS: Im Script habe ich for each als Seitenhieb untergebracht. Der IE kanns nämlich nicht.
PPS: Im gesamten Script kommt kein jQuery vor, weil wir das Framwork ja erst nachladen wollen.

MacBook, Javascript und Firefox

Die Ereignisse überschlagen sich. Beinahe hätte ich Steve Jobs Keynote verpasst, weil ich mir gerade Chris Heilmanns „Maintainable Javascript“ Tutorial angesehen hatte.
Hier beschreibt er, wie man möglichst verhindert, dass Scripte schon nach wenigen Monaten Einsatz selbst für den damalien Urheber nicht mehr wartbar sind. Wie man Javascript in seinen Seiten richtig einsetzt und wie man mit Javascript das Aussehen von HTML-Seiten richtig verändert. Dies erscheint mir so wichtig, dass ich es hier nochmals zitieren möchte:
Natürlich kann man mit Javascript und
Element.style.height = neuerWert;
das Aussehen einzelner Elemente verändern. jQuery drängt sich hier mit
Element.css({ height: neuerWert });
geradezu auf. Viel besser jedoch ist in jQuery
Element.removeClass(alteKlasse);
und
Element.addClass(neueKlasse);.
In normalem Javascript löst das
Element.className = „neueKlasse“;.
Das Aussehen wird hier weiterhin über das Stylesheet und css-Klassen, nicht über ein viel schwerer wartbares Script bestimmt.

Diese Zeilen schreibe ich übrigens mit dem Wunsch, möglichst bald das neue MacBook zu besitzen und im neuen Firefox 3.1 beta1, bei dem sich nicht wahnsinnig vie geändert hat – bis auf den wirklich spürbaren Geschwindigkeitsgewinn.
Wow. Damit ist er gefühlt nahezu gleichauf mit Iron, dem entgoogelten Chrome.

use frameworks

Lisa hat eine wöchentliche Fotostunde eingerichtet und verbietet gleich in der ersten Stunde, die Default-Einstellungen zu benutzen. Dasselbe verbietet Darkmotion bei der Benutzung von Filtern. Zeit für mich, auch irgendwas zu postulieren.

Benutze Frameworks

Bei Stylesheets sind sie umstritten, bei Javascript ein Muss. Wenn Ihr irgendwas mit Javascript machen wollt nehmt ein Framework. Oder als Verbot formuliert: sucht nicht für jedes Problem ein Script bei Google. Seit ich jQuery benutze bastele ich Funktionen, die ohne Framework undenkbar waren. Dazu kommt, dass es für nahezu jede Anforderung schon ein passendes Plugin gibt. Ein angenehmer Nebeneffekt ist, dass man den Internet-Explorer weniger hasst, weil man nicht mehr jedes Script nochmal schreiben muss.