Going Mobile mit Apache Wicket – Teil 3 – JavaScript im Footer

Im letzten Teil haben bereits einen großen Schritt für die Performance-Optimierung unserer Responsive-Wicket Anwendung gemacht, indem wir Requests minimiert und Ressourcen gebundlet haben.

Ein weiterer Tipp aus den Yahoo Web Performance Best Practices ist es, Skripte ans Ende der Seite zu legen. Bedingt durch das Verhalten der meisten Browser werden nicht mehr als zwei Ressourcen gleichzeitig geladen. Haben wir jetzt ein Skript im <head/>-Tag, das sehr lange lädt, kann es passieren, dass die Seite blockiert und keine neuen Ressourcen geladen werden. Die Beschreibung bei Yahoo ist hierfür sehr gut.

Aktuell sieht der Page-Header folgendermaßen aus.

&lt;head&gt;
    &lt;!-- Skalierung auf devices, volle Skalierung auf die Weite --&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
    &lt;script type="text/javascript" src="./wicket/resource/de.effectivetrainings.WicketApplication/app-ver-1371750352000.js"&gt;&lt;/script&gt;
    &lt;link rel="stylesheet" type="text/css" href="./wicket/resource/de.effectivetrainings.WicketApplication/app-ver-1368356946000.css" /&gt;
&lt;/head&gt;

 

JavaScript muss in den Footer

Versuchen wir dem Tipp zu folgen und rendern das Javascript im Footer.  Der Effekt lässt sich leider an einer solchen Anwendung nicht so einfach nachstellen, wie im letzten Artikel.

Zunächst definieren wir in der  init-Methode der Klasse WicketApplication einen neuen HeaderResponseDecorator (IHeaderResponseDecorator ist übrigens ein wirklich wunderbares Feature – ich habe hiermit beispielsweise für ein Projekt HTML5-Cache-Manifest-Support für Wicket implementiert).

Mit einem HeaderResponseDecorator haben wir die völlige Freiheit, alles was im <head/>-Tag landen würde nochmals zu bearbeiten.

setHeaderResponseDecorator(new IHeaderResponseDecorator() {
            @Override
            public IHeaderResponse decorate(IHeaderResponse response) {
                return new JavaScriptFilteredIntoFooterHeaderResponse(response, WicketApplication.FOOTER_BUCKET);
            }
        });

Wicket rendert alle JavaScript-Ressourcen ab jetzt in einen Bucket, was intern nichts anderes ist als eine HashMap mit dem BucketNamen als Key. Den Namen des Buckets definieren wir als Konstante in der WicketApplication als “footerBucket“, denn der andere Bucket (quasi der Opposite, wenn man die Bezeichnung aus dem Wicket-Code übernimmt) nennt sich “headerBucket“.

Zusätzlich müssen wir dafür sorgen, dass die Bucket-Ressourcen korrekt in der Page gerendert werden. Hierfür verwenden wir den HeaderContainer.

public HomePage(final PageParameters parameters) {
	super(parameters);
        add(new HeaderResponseContainer("footerJS",WicketApplication.FOOTER_BUCKET));
    }

Zuletzt brauchen wir im Markup noch einen Tag, in den später der neue Javascript-Bucket gerendert wird.

&lt;!DOCTYPE html&gt;
&lt;html xmlns:wicket="http://wicket.apache.org"&gt;
	&lt;head&gt;
        &lt;!-- Skalierung auf devices, volle Skalierung auf die Weite --&gt;
        &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
    &lt;/head&gt;
	&lt;body&gt;
    &lt;div class="container"&gt;

        &lt;div class="masthead"&gt;
            &lt;ul class="nav nav-pills pull-right"&gt;
                &lt;li class="active"&gt;&lt;a href="#"&gt;Home&lt;/a&gt;&lt;/li&gt;
                &lt;li&gt;&lt;a href="#"&gt;About&lt;/a&gt;&lt;/li&gt;
                &lt;li&gt;&lt;a href="#"&gt;Contact&lt;/a&gt;&lt;/li&gt;
            &lt;/ul&gt;
            &lt;h3 class="muted"&gt;Going Mobile&lt;/h3&gt;
        &lt;/div&gt;

        &lt;hr&gt;

        &lt;div class="jumbotron"&gt;
            &lt;h1&gt;Jetzt wirds mobil!&lt;/h1&gt;
            &lt;p class="lead"&gt;Responsive Design mit Bootstrap ist so einfach!&lt;/p&gt;
            &lt;a class="btn btn-large btn-success" href="#"&gt;Klick me!&lt;/a&gt;
        &lt;/div&gt;

        &lt;/div&gt;
        &lt;div wicket:id="footerJS"&gt;&lt;/div&gt;
	&lt;/body&gt;
&lt;/html&gt;

Das war es schon. Wir starten die Anwendung erneut und prüfen das Markup.

Wir sehen am Ende der Seite folgendes.

&lt;script type="text/javascript" src="./wicket/resource/de.effectivetrainings.WicketApplication/app-ver-1371750352000.js"&gt;&lt;/script&gt;
&lt;link rel="stylesheet" type="text/css" href="./wicket/resource/de.effectivetrainings.WicketApplication/app-ver-1368356946000.css" /&gt;
&lt;/body&gt;

Wir sehen, das JavaScript wird direkt am Ende der Seite gerendert.
Seltsamerweise aber auch unser CSS. Eine der Best-Practices von Yahoo sagt, CSS soll im Header gerendert werden, da dadurch der Browser früher anfangen kann, die Seite zu rendern.

Das Problem ist, wir haben es hier mit einem Exoten zu tun. Wir haben eine CSS-Ressource-Referenz, die eine Abhängigkeit auf Javascript-Ressourcen deklariert. Dies scheint nicht korrekt aufgelöst zu werden, was ein echter Bug ist (Stand Wicket 6.8.0).

Prinzipiell funktioniert der Mechanismus aber sehr gut, und ich habe ihn schon mehrfach in verschiedenen Wicket-Projekten erfolgreich eingesetzt.

Im nächsten Artikel lassen geht es weiter und zwar mit Clientseitiger Validierung.

Links

Yahoo WebPerformance Best Practices
Source-Code auf Github

Und zu guter Letzt, noch viel genauer können wir über das Thema im Effective Wicket Workshop sprechen. Rufen Sie mich doch einfach an.

Effective Trainings & Consulting - Martin Dilger



Hat Ihnen dieser Blog-Eintrag gefallen? Ich stelle in diesem Blog Informationen über Tools, Frameworks und Werkzeuge zur Verfügung, die mich produktiver machen. Vielleicht kann ich auch Ihnen helfen, produktiver zu werden.


Ich unterstütze Sie als freier Mitarbeiter bei der Entwicklung von Software-Projekten, Agiler Arbeit sowie Schulungen / Fortbildungen.


Jeden Tag ein bisschen produktiver - ab heute