binary-garden.com – Project Diary für ein Start Up

Am Anfang war...

Ausgangspunkt dieser Case Study war das Project Diary des Start Ups peopleatventure.de, das Anfang Dezember 2014 in der Website Boosting veröffentlicht wurde: "Start-up Diary – Begleiten Sie ein Gründerteam durch die Höhen und Tiefen seines Webauftritts". Zum Schluss die Aufforderung an die Leser "Haben Sie einen Tipp für das ambitionierte Unternehmen? Schreiben Sie an...".

Eigentlich bin ich ja gerade dabei unsere eigene Site zu überarbeiten. So richtig Ruhe dazu finde ich eben nur in der Zeit zwischen Weihnachten und Neujahr. Ach, was soll's... nur mal 'nen Blick draufwerfen, dann geht's weiter.
Kurzer Aufruf der Website... Oh je, das dauert ja ewig. Eigentlich ein Fall für ein nettes kleines Weihnachtsprojekt und viel mehr Spass macht es auch, das letzte Bisschen Ladezeit aus einer Webseite rauszuquetschen denn wie sagt Google:

"Fast and optimized pages lead to higher visitor engagement, retention, and conversions."

Als Ziel setzte ich mir, dass die bestehende Seite soweit wie möglich in ihrem Design weiterbestehen sollte und nur dort Alternativen anzuwenden wo sie mir sinnvoll schienen, wie z.B. bei den Social Icons, die von 2 auf 3 angewachsen sind und dadurch das "Suchen"-Feld in Bedrängnis brachten.

Um das Ergebnis vorwegzunehmen:
durch Onpage Optimierung ist es gelungen, die ursprüngliche Ladezeit von 5 Sekunden zu drücken auf ganze 0,25 Sekunden. Allerdings ist das Ergebnis stark abhängig von dem aktuellen Traffic da die Anfrage über einen Londoner Server läuft. So bin ich für die optimierte Version auch schon bei Werten um 1,4 Sekunde gelandet die Überprüfung der Original Seite lag zur gleichen Zeit dann allerdings bei knapp 8 Sekunden. In Relation war die optimierte Version jedoch grundsätzlich um ein vielfaches schneller.

Original Seite: Ladezeit 5 Sekunden
Optimierte Seite: Ladezeit 0,25 Sekunden

Wie es dazu kam lesen Sie hier...

Check up

Alles was ich wissen muss, erfahre ich aus einem Blick in den Quelltext und durch den Einsatz von ein paar Tools aus dem Internet.

Blick in den Quellcode und ich fühle mich 15 Jahre jünger:

• XHTML
style-Anweisungen in den HTML-Tags < style="..." >
• und auch wiedermal Mediengestalter's Liebling: Text als Bild

Insgesamt finden sich 18 eingebundene .css-Dateien sowie 16 .js-Dateien.
Hinzu kommen doppelte Objekt-IDs und doppelte <title>.

<Hx> Überschriften fehlen völlig und auch ein HOME-Button ist nicht vorhanden (erst später merke ich, dass diese Funktion das Logo übernimmt).

Analyse #1
www.feedthebot.com

Gelegenheit einen Tip aus der Website Boosting auszuprobieren: feedthebot.com.
"Text may be too short - (spiders see about 23 words)" heisst es dort.

Leider erfahre ich nicht um welche 23 Worte es sich handelt. Können ja eigentlich nur Sachen sein wie "Vorstellungsgespräch", "Bewerbungsunterlagen" etc.

Ha, ha, von wegen:

Keine Frage:
da läuft wohl irgendetwas falsch zwischen Content Management System und Datenbank.

Analyse #2
www.seitenreport.de

Nächster Halt seitenreport.de.

• 27 XHTML Fehler
• Verhältnis von Content zu Quelltext = 7,2%
• lediglich 1 von 46 <title>-Attributen der Links ist gefüllt

Analyse #3
Google PageSpeed / www.gtmetrix.com

Google billigt beim crawlen jeder Webseite lediglich ein bestimmtes Zeitlimit (Crawl Budget) zu. Ist es aufgebraucht, verlässt GoogleBot sie wieder - unter Umständen ohne jemals bis zum Inhalt vorgedrungen zu sein.
Kurze Ladezeiten bedeuten aus der Sicht von Google, im gleichen Zeitraum mehr Seiten durchsuchen und indexieren zu können.

Zur Verbesserung der Ladezeit empfiehlt Google sein Analyse Tool PageSpeed:
"Analyze and optimize your website with PageSpeed tools to implement the web performance best practices."

Eine erweiterte Version von PageSpeed bietet gtmetrix.com und meldet u.a:

• Ladezeit von mehr als 5 Sekunden
• 58 Requests
• PageSpeed von 50%


Auf mögliche Probleme beim Erfassen der Inhalte deutet der bei der Analyse angefertigte Screenshot hin - er bleibt nämlich leer.

Fazit

Wie nicht anders zu erwarten: mit ein bisschen optimieren ist es hier nicht getan.
Was die vielen JavaScript-Dateien machen? Keine Ahnung.
Wozu so viele .css-Dateien nötig sind? Ich weiss es nicht.

Bis morgen habe ich genug Zeit mir darüber Gedanken zu machen wie sich die einzelnen Bereiche am Effektivsten umsetzen lassen.
Ein wenig Kopfzerbrechen bereitet mir die Überblendung der beiden Startbilder. Das schiebe ich erst mal nach hinten...


Der Mittelteil

Heiligabend ist vorüber und wie immer starte ich mit dem was einfach geht und schnell. "Kilometer fressen" – das motiviert.

Die Vorgehensweise ist dabei immer dieselbe:
ich erstelle einen <div>-Container, fertige anschliessend einen Screenshot von dem entsprechenden Bereich der Original Seite, binde diesen als background-image ein und lege den neuen Quellcode darüber.

Die Anzahl der (Bild)-Requests ist mit 14 viel zu hoch. Jedes Anfordern von Ressourcen vom Server unterbricht das Laden der Seite. Deshalb packe ich alle <img> (Bilder) in ein einziges CSS Image Sprite...

...und baue sie in Form von <div>s mit background-image ein.
Aus dem Anfragen von 14 Resourcen wird so 1.

Das im Original ausgelieferte Apfel Bild hat die Größe 629×346 und wird im Browser runterskaliert auf 274×163. Hier passe ich die Größe an.

Als nächstes kümmere ich mich um den eigentümlichen Pfeil links von dem Wort "Lebenslauf", in Wirklichkeit ein Minus Zeichen kombiniert mit einem spitzen Winkel.
Das Minus Zeichen liesse sich mit vertical-align mehr nach oben in die Mitte ziehen. Ich entscheide mich jedoch dafür, ein vernünftiges Symbol zu verwenden.

Geht es um Symbole zur Verwendung auf Webseiten, gibt es für mich zwei Anlaufpunkte:
Font Awesome mit einer sehr umfangreichen Bibliothek oder wenn es, so wie in diesem Fall, auch etwas weniger sein darf, ein Zeichen im dezimalen numerischen Code wie sie auf der Website von mediaevent.de zu finden sind.

Der Rest ist Handwerk:
Headline "Der Lebenslauf - So bringen Sie Ihr Berufsleben in Form" ist definiert als Tabellenzelle (<td>) - daraus mache ich eine Überschrift (<h2>).
Danach alles an die richtige Stelle rücken, Schrift anpassen, Hintergrundfarbe, runde Ecken - das war's auch schon.

Nächste Station: der Footer

Der Footer ist der Bereich ganz am Ende der Seite wo sich all die Links zu den einzelnen Themen befinden. Gefällt mir gut. Besser als so'n rumgeoggle mit Klappmenüs.

Allerdings wimmelt es dort im Quelltext nur so vor lauter <div>s und <p>s und jeder Menge Style Anweisungen in den HTML Tags. Alles muss raus... Stattdessen packe ich die Links in eine unsortierte Liste mit Listelementen, also <ul> und <li>.

Ich könnte dafür auch eine Tabelle nehmen. Die unsortierte Liste jedoch bietet den Vorteil, dass sich die 3 Bereiche bei einem kleineren Bildschirm noch ein wenig länger automatisch anordnen.

Vor den Links stehen wieder Pfeile, diesmal jedoch in einem anderem Design (weil hier default = bold).
Ich mag's gerne einheitlich und tausche auch sie gegen den Pfeil aus dem Mittelteil – ausserdem gibt es mir eine gute Gelegenheit für ein wenig...

...jQuery Theorie

Bei jQuery handelt es sich um ein sogenanntes JavaScript Framework, vereinfacht ausgedrückt: viele Funktionen von nativem JavaScript (der Programmiersprache die, im Gegensatz etwa zu PHP das auf dam Server ausgeführt wird, im Browser läuft) lassen sich durch das Vorschalten von jQuery erheblich verkürzen. Für mich ist jQuery die Weiterentwicklung von JavaScript die niemals stattgefunden hat.

Der Grund warum ich ausgerechnet an dieser Stelle darauf zu sprechen komme, ist folgender:
im Footer Bereich befinden sich nun 24 Links, jeder davon versehen mit einem Pfeil.
Dort steht also 24x der folgende Quellcode:

 <span class="clArrow">&#10142;</span> 

Mit Hilfe von jQuery benötigt man anstatt der 24 Aufrufe im HTML Text lediglich eine einzige Zeile:

 $('#idInnerLinks ul li a').before(<span class="clArrow">&#10142;</span>); 

Bindet man das Ganze dann ein in die Funktion

 $(document).ready(function ( ) { } ); 

werden die Pfeile erst dann in den DOM (Document Object Model) Tree eingehängt, nachdem die Seite vollständig geladen ist oder anders ausgedrückt:

Nicht die 24 Zeilen HTML Text werden zum Browser des Users übertragen, sondern nur eine Zeile JavaScript mit dem Befehl das HTML dazu erst beim User zu erzeugen wenn die Seite komplett dort angekommen ist – ein kleines Minus bei Ladezeit.

Natürlich lässt sich einwenden, dass ja schliesslich jQuery selbst auch erstmal übertragen werden muss (und zwar selbst in der minimierten Variante nicht gerade wenig, gemessen am Rest des Inhaltes) bevor es zum Einsatz kommen kann.

Trotzdem: die Vorteile überwiegen bei Weitem und wie effektiv sich die Ladezeit einer Webseite damit beeinflussen lässt, wird später noch bei der Umsetzung der Animation zu sehen sein.

Blaue Headlines

Als nächstes kümmerte ich mich um die beiden Bereiche oberhalb und unterhalb des Mittelteils.

Business as usual. Alles schon gehabt:
<h2> Headline eingesetzt, Link mit title="..." versehen, Pfeile...

Programmieren besteht zum Großteil aus Routine – gut wenn nebenbei alte Folgen der "Olsen Bande" im TV laufen. Etwas Neues kommt erst wieder im folgenden Abschnitt, den hier geht es um den...

Top Bereich inkl. Navigation

Gleich am Anfang Enttäuschung pur...
Eigentlich wollte ich mich heute zur Einstimmung auf meine weihnachtliche Programmier Session vorher mit ein paar Freunden bei einer Party "Warface" warmmachen. "XBox Live" jedoch verweigert mir den Zutritt.

Team "KillahChinchillah" muss ohne meine Mithilfe die Welt vor der Machtübernahme durch "Blackwood" retten. Meine Aufgabe am heutigen abend aber wird mindestens ebenso wichtig sein. Nach Weihnachten dann werde ich erfahren, dass "XBox Live" Opfer einer Hacker Attacke wurde.

Sprung nach oben.
Hier füge ich in die Menüleiste einen HOME Button ein und die Social Media Icons ergänze ich um den mittlerweile vorhandenen Google+ Account.

Nun jedoch wird es eng für das Suche... Feld. Macht nichts. Das ziehe ich runter, mache es bündig mit facebook & Co und da diese Widgets meist sowieso nicht der Bringer sind, tausche ich es bei der Gelegenheit gleich gegen ein Google Widget aus. Fertig.

Doch halt. Nicht so ganz. Etwas stört noch denn eigentlich sollte die Seite ja konsequent auf Ladezeit optimiert werden. Nun jedoch habe ich mit Suche... ein Element, dass sich mit Google verbindet, auf Rückmeldung wartet und zum Schluss angezeigt wird. Dann erst wird die Seite weiter geladen. Dabei wird es meistens wahrscheinlich ohnehin nicht benutzt – das nervt.

Ich fertige einen Screenshot, schneide den "Suche"-Bereich aus und baue ihn, leerer Platz ist noch vorhanden, zusätzlich in das CSS Image Sprite ein.
Jetzt schiebe ich ihn an die Stelle des Google Widgets, das ich nun wiederum aus dem Quelltext entferne. Wo sich vorher das "Suche"-Feld befand erscheint also nun stattdessen ein Abbild von diesem.

Wer suchen will muss klicken (und dabei die Maus bewegen). Mittels JavaScript und dem User Generated Event mousemove lasse ich das Widget erst nach dem Laden der Seite erscheinen (wenn der Besucher die Maus bewegt) und sich dann pixelgenau über das Bild legen. Das spart Zeit und niemand merkt's.

Da ich bisher noch keinen geeigneten Satz für die <h1> Überschrift gefunden habe, nehme ich "Wir verbinden Mensch und Arbeit" unter dem Logo.

Das soll's gewesen sein für heute.

Animation ( Sorry, leider keine Bilder hier... )

Endspurt. Letzter Tag meines Weihnachts Projekts und er soll ganz im Zeichen der Animation stehen. Ich bin gespannt ob sich das tatsächlich so reibungslos umsetzen lässt wie ich es mir vorstelle.

Bei der Animation handelt es sich um zwei Bilder die im Wechsel zuerst eingeblendet und dann ein wenig rausgezoomt werden. Jedes der Bilder ist versehen mit einem Slogan.

Drei Sachen werde ich ändern.

Laden des 2. Bildes

Für das zweite (vorerst nicht sichtbare) Bild greife ich wieder auf die Technik mit dem User Generated mousemove Event zurück.

Im Original Quelltext finde ich dazu ein delay von 8 Sekunden. Das reicht dicke. In 8 Sekunden hat jeder seine Maus mindestens schon einen Pixel bewegt.

Ausserdem bekommt es beim Laden den identischen Inhalt des ersten, bei mousemove dann wird das "richtige" zweite Bild in den Container geladen.
Auf diese Art habe ich schon ein Carousel (so heissen diese Dinger nämlich) realisiert das aus 4 + 40 Bildern bestand – mit der Ladezeit einer normalen Website.

Überblendungen

Wie ich weiter oben schrieb, sollte das Ziel sein, die Seite zu optimieren, möglichst als 1:1 Kopie der Original Seite. Nur in Ausnahmefällen wollte ich mir erlauben Veränderungen vorzunehmen. Dies ist so ein Ausnahmefall.

Einer der wesentlichen Punkte zur Ladezeitoptimierung ist das Verwenden von CSS Image Sprites. Wegen des Zoom Effektes lässt sich dieser Vorsatz jedoch nicht so ohne Probleme umsetzen.

Ich weiche daher auf eine Alternative aus:
die Bilder überblenden wie gehabt – allerdings ohne den Zoom Effekt.
Als Ausgleich lasse ich die Schrift mit etwas Verzögerung einblenden und sich dann leicht nach rechts bewegen. Ich denke damit lässt's sich leben.

Was in der Theorie einfach klingt, erweist sich in der Praxis jedoch als äusserst unangenehme Aufgabe und wer jemals mit intervalIDs und Transparenzen unter JavaScript gearbeitet hat, wird das bestätigen.

– Bei Transparenzen zählt der eine Browser die Werte von 0.0 bis 1.0, während der anderere nach Werten von 0 bis 100 verlangt.

– Beim Arbeiten mit sich periodisch wiederholenden Abläufen (intervalID) hängt die Flüssigkeit der Ausführung ab von der Leistungsfähigkeit der im Browser zum Einsatz kommenden JavaScript Engine und die wiederum nicht nur vom Browser sondern auch von seiner Versions Nummer.

Eine elende Frickelei, ausser:
man verwendet das jQuery Core PlugIn jquery-timing vom Creative Couple.

Gerade einmal 6 Zeilen JavaScript Code und die gesamte Animation steht.

An dieser Stelle möchte ich erinnern an die ursprünglichen 16 .js-Dateien vom Beginn und erklären wie sich auch hier sehr einfach Requests einsparen lassen.

Da ohnehin verschiedene JavaScript Dateien geladen werden, schreibe ich grundsätzlich alles in jquery-min selbst. Bei diesem Projekt also jQuery + jquery-timing + eigene Scripts. Aus 3 mach 1.

Schrift im Bild

Text als Bild ist immer schlecht. Schliesslich liefert jeder Text Google Informationen. Allerdings nur wenn er nicht, wie hier, in ein Bild eingebettet ist.

Mit Stempel-Tool und Wischfinger entledige ich die beiden Bilder ihrer nichtssagenden Begleiter.

Anschliessend bilde ich aus den beiden Sätzen "Unerlaubte Fragen im Vorstellungsgespräch" und "Körpersprache im Vorstellungsgespräch" eine <h2> Überschrift.
Weiteren Text gibt es nicht und folglich auch keine <p>s.

Nun sollten Bild und Text jeweils zusammen ein- und nach einer Wartezeit von 8 Sekunden wieder ausgeblendet werden. Kurzer Test... geht.

Zum Schluss noch HTML, CSS und JavaScript minimieren (a.k.a. Leerzeilen und WhiteSpaces weg) und die 100% sollten mir gehören. Ein paar Tage Auszeit an der Ostsee waren jetzt eigentlich geplant. Die werde ich mir auch nehmen – sicherheitshalber ohne Computer. Zeit genug also um den Kopf frei zu kriegen. Wieder zurück werde ich alles auf unsere Domain hochladen und testen.

Buuuuhhh, Google. Buuuuhhh... Geh' nach Hause...!

Kein Mensch mag Heulsusen...!
Das fängt ja gut an. Da wollte ich mir nur kurz die 100% von Google abholen und dann das.
PageSpeed meldet:

"Above the fold" – richtig, das gibt's ja auch noch.
Hintergrund: Google möchte gerne, dass Inhalte die beim Start der Seite im sichtbaren Bereich liegen, also all das was gesehen werden kann ohne scrollen zu müssen, zuerst geladen werden. Dabei soll das Laden dieser Inhalte nicht vom Laden einer externen Ressource (hier einer .css-Datei im <head> Bereich) unterbrochen werden.

Klingt kompliziert, heisst in der Praxis jedoch nichts Anderes als: alle Layout Informationen die ich für das Startbild brauche, raus aus der .css-Datei und rein ins HTML.

Schnelle Ladezeiten O.K., aber mir fallen mindestens ein halbes dutzend Gründe ein, warum ausgerechnet "above the fold" kompletter Unfug ist und ich hoffe, dass Google dieses Kriterium für einen ordentlichen PageSpeed, so schnell wie möglich entsorgt.

So lange allerdings wie das noch nicht der Fall ist, beuge ich mich dem starken Arm von Google und hole knapp 60 Zeilen aus aus der Stylesheet Datei um sie in index.htm einzufügen.

Neuer Test... Google ist endlich zufrieden und meldet 100%.

Spannend wird es nun bei GTMetrix.
Wie stark werden sich die Optimierungen im Source Code wohl ausgewirkt haben und konnte ich meine Zielvorgabe von 0,4 Sekunden erreichen?

Tatsächlich: bei allen 10 Durchläufen des Tests lag der Page Load sogar deutlich unter 0,4 Sekunden, nämlich zwischen 0,29 und 0,21 Sekunden.
Zur Erinnerung: die ursprüngliche Ladezeit betrug 5 Sekunden.
Für den Screenshot nehme ich einen Mittelwert von 0,25.

Was wurde eigentlich aus...?

Einige Sachen sind auf der Strecke geblieben. Warum, das erkläre ich hier.

Content Management System (CMS)

Ursprünglich "Joomla!".
Seit 2008 verwenden wir keine herkömmliche CMS mehr. Stattdessen setzen wir auf sogenannte "Hosted CMS".

Der Unterschied:
Anders als bei "Joomla!", "Wordpress" und Co erfolgt die Bearbeitung nicht in der Domain, sondern in einer Art Black Box (oder wie man heute sagt "Cloud"), ähnlich wie bei dem populären squarespace.com. Danach wird die Seite wieder zurückgeladen in die Domain. Man hat so alle Vorteile eines klassischen CMS, nur ohne dessen Nachteile. Niemehr Updates, Bugfixes, Patches etc. für Core und PHP und auch niemehr SoakSoak und Konsorten (hier nur Meldung).

Wir sind begeistert und die Kunden auch. Nicht zuletzt, weil sie nicht mehr mit einer Fülle von Funktionen erschlagen werden, die sie sowieso niemals gebrauchen.
Zurückgewünscht hat sich sein klassisches CMS noch niemand.

Wen's interessiert, dem empfehle ich einfach mal auf den Sites von Surreal CMS, Pagelime oder
Cushy CMS vorbeizuschauen.

Responsives Design

"Mobile First", ja nee, is klar.
Das Ganze sollte niemals eine komplette Startseite mit allen Möglichkeiten werden. Zum "nur mal so nebenbei machen" wäre es dann doch zu aufwendig gewesen. Ich habe mich bei der Optimierung zwar an die Desktop Version gehalten, jedoch bei der Umsetzung strikt darauf geachtet, dass alles problemlos für "Mobile" angepasst werden kann, da alle Grösseneinheiten proportional ("em" anstatt "px") gehalten wurden.

Das Mehr an CSS das dabei anfällt wird durch das Weniger an Datenvolumen (schliesslich gehört zu einer Optimierung auch stets das Anpassen der Auflösung der Bilder) lange wieder reingeholt. Page Loads von weniger als den hier erzielten 0,25 Sekunden sind dann realsitisch.

Was sonst noch (beinahe) war

HTML5 bietet einige Vorteile gegenüber früheren HTML Versionen, erst recht zu dem originär verwendenten XHTML. Ich wollte mich bei der Optimierung so weit wie möglich an das Original halten und so habe ich darauf verzichtet, die einzelnen Bereiche durch Erweiterungen mit MicroFormats zu versehen. Wie soetwas aussehen könnte möchte ich trotzdem kurz an einem Beispiel zeigen (es handelt sich dabei um den Animations Teil).

HTML5 hinzugefügt habe ich die Tags <figure>, <figcaption> und in Orange die MicroFormats Auszeichnungen gemäss schema.org:

 <figure> 
    <div id="idCarouselPic_1" itemscope itemtype="http://schema.org/Product"
       <figcaption> 
          <h2 itemprop="name">Unerlaubte Fragen im Vorstellungsgespräch</h2> 
          <p itemprop="description">Lesen Sie hier, Welche Fragen in einem Vorstellungsgespräch erlaubt sind.</p> 
          <a href="..." title="..." itemprop="url">mehr</a> 
       </figcaption> 
   </div> 
 </figure> 

Über dieses Projekt

Für den Kunden ist eine Webseite meistens nichts anderes als eine Ansammlung von Texten und Bildern. Klickt man irgendwo drauf, erscheint eine neue Seite mit anderen Texten und Bildern.

Dieses Projekt Tagebuch sollte die Sicht der anderen Seite zeigen und dass zwei Sachen die gleich aussehen noch lange nicht gleich sein müssen.

Erkenntnisgewinn für mich? Eher weniger. Vielmehr wieder einmal die Bestätigung, dass Projekte bei denen schon die Grundlage nicht stimmt auch im Nachhinein nicht mehr zu optimieren sind. Optimierung dann = Neuerstellung und zwischen zwei Gänsefüßchen können Welten liegen. Der Unterschied zwischen Programmierer und "Programmierer" jedenfalls ist gross.

Am Anfang stand die Angst viel Geld bei einer Agentur zu lassen die den Webauftritt dann in die (kostengünstigen) Hände von Studenten verfrachtet.
Was man in dieser Phase dringend gebraucht hätte, wären ein paar Tools gewesen, die frühere Projekte der infrage kommenden Agenturen auf Qualität abklopfen. Eigentlich recht simpel und einleuchtend. Letztendlich musste dann das Bauchgefühl entscheiden.

Vielleicht ist es auch einfach so im Leben: beim ersten Mal zahlt man immer Lehrgeld. Ich habe diese Erfahrung machen müssen bei meinem ersten Auto und bei meinem ersten Anzug.

Ich wollte eine Seite abliefern, die technisch gesehen das Optimum rausholt aber das ist noch längst nicht alles. Ich gebe den Stab weiter an jeden der Spass daran hat mit seinem Fachgebiet daran zu arbeiten und Website Boosting damit auf dem Laufenden zu halten.