“gzip” für Webseiten

Um das Verhalten von “gzip / deflate” besser zu verstehen, möchte ich als erstes ganz kurz auf den Algorithmus hinter der Komprimierung eingehen. Dafür muss man zumindest zwei Grundlegende Theorien verstehen. Zum einen die sogenannte Huffman-Kodierung, dabei geht darum Text mit möglichst wenig Bits (0 || 1) zu übersetzen.

Es folgt ein einfaches Beispiel:

String: “im westen nichts neues”

Die Länge des Strings beträgt 22 Zeichen, was bei einem 4-Bit-Code (0000, 0001 …) eine Anzahl von 22 * 4 Bit = 88 Bit ergeben würde.

Berücksichtigt man jedoch die Häufigkeit der wiederkehrenden Zeichen, kann man für bestimmte Zeichen, welche oft im String vorkommen, kürzere Bit-Codes nutzen.

huff1

Als erstes Zählen wir die Anzahl der vorkommenden Zeichen. Die Zeichen welche die geringste Häufigkeit aufweisen werden anschließend als erstes miteinander Verknüpft und jeweils addiert.

huff4

Wie man bereits erkennt bekommen die Zeichen welche nicht so häufig auftreten längere Strecken und somit gleich auch längere Bit-Codes.

huff7

Wenn man alle Zweige verknüpft hat, entsteht daraus dann ein Binär-Baum, welcher von oben nach unten gelesen wird.

Die eindeutigen Bit-Codes sind nun z.B.: 00 für e, 100 für n, 1011 für t und so weiter. Nun benötigen wir nur noch 73 Bit anstatt 88 Bit, um den String binär darzustellen. ;)

Das zweite Prinzip hat auch mit Wiederholung von Zeichen zu tun. Die sogenannte “LZ77″ Kompression, welche wiederkehrende Muster in Strings erkennt und durch Referenzen von vorherigen Strings ersetzt.

Es Folgt ein einfaches Beispiel:

String: “Blah blah blah blah blah!”

 vvvvv     vvvvv     vvv
Blah blah blah blah blah!
      ^^^^^     ^^^^^

Wenn man nun die Wiederholung durch eine Referenz angibt, welche aus der Länge des Wortes (” blah” = 5) und Länge der Wiederholungen. (“lah blah blah blah” = 18). Daraus ergibt sich anschließend der folgende komprimierte Text.

Blah b(5,18)!

… aber nun endlich zum praktischen Teil! Es folgen ein paar Beispiele und Überlegungen im Zusammenhang mit Webseiten / Webservern.

1.) “gzip”, ABER weniger ist manchmal mehr

Bei kleinen Webseiten und schwachen V-Servern kann es vorkommen, dass die serverseitige Komprimierung im Gesamtkontext keinen Geschwindigkeitsvorteil bietet, da die Komprimierung ggf. mehr Overhead (Payload, CPU-Rechenzeit, Verzögerung der Auslieferung) mit sich bringt als es Vorteile (geringere Dateigröße) bietet. Zumal viele Dateien (Bilder, CSS, JS) nach dem ersten Seitenaufruf im Cache sind und nicht wieder vom Server ausgeliefert werden müssen. Gerade für mobile Geräte macht die Komprimierung jedoch fast immer Sinn, daher würde ich die Komprimierung immer aktivieren!

PS: hier noch ein Blog-Post zum Thema Webseiten Beschleunigen

moelleken_org-gzip
mit gzip
moelleken_org-nogzip
ohne gzip

GRÜN = Download
GELB = Wartet
BLAU = Verbindung zum / vom Server

Bei “nginx” gibt es zudem ein Modul (HttpGzipStaticModule) welches direkt vorkomprimierte Dateien ausliefert, anstatt diese bei Anfrage zu komprimieren. Jedoch muss man bisher selber dafür sorgen, dass eine entsprechende Datei mit dem selben Timestamp vorhanden ist. (z.B.: main.css & main.css.gz) Falls jemand hier eine Alternative oder ein einfaches Script zum erstellen der zu komprimierenden Dateien hat, meldet euch bitte bei mir oder einfach in den Kommentaren.

2.) “gzip”, ABER nicht für alles

Zunächst sollte man bereits komprimierte Dateien (z.B. JPEG, PNG, zip etc.) nicht noch zusätzlich via „gzip“ ausliefern, da die Dateigröße im schlimmsten Fall noch steigen kann oder zumindest wird für sehr wenig Dateigröße, sehr viel CPU-Zeit auf der Server (Komprimierung) und auf dem Client (Dekomprimierung) verbraucht.

gzip_images

Ich empfehle an dieser Stelle mal wieder die “.htaccess“-Datei vom HTML5-Boilerplate, welche bereits viele Einstellungen für den Apache-Webserver liefert. Außerdem gibt es dort auch eine optimierte Konfiguration “nginx.conf” für den nginx-Webserver.

3.) “gzip”, ABER nicht immer

Die “gzip”-Komprimierung kann Ihre Stärken bei größeren Dateien viel besser ausspielen, da wir ja bereits im theoretischen Teil gelernt haben, dass die Komprimierung auf Wiederholungen aufbaut und wenn wenig wiederkehrende Zeichen und Muster vorhanden sind lässt es sich schlecht komprimieren.

Beim “nginx”-Webserver kann man die minimale zu bearbeitende Dateigröße angeben, sodass eine 6 Byte große Datei mit dem Inhalt “foobar” bei schwacher „gzip“ nicht auf 40 Byte vergrößert wird.

gzip_small_file

4.) “gzip”, ABER nicht so hoch

Zudem sollte man nicht mit der höchsten Komprimierungsstufe komprimieren, da man pro Komprimierungsstufe immer weniger Erfolg bei immer mehr CPU-Zeit bekommt. Man sollte weniger stark komprimieren und dadurch Rechenleistung /-zeit einsparen, um die Webseite schneller ausliefern zu können.

gzip_level

test2_1.js.gz (schwache Komprimierung)
test2_2.js.gz (normale Komprimierung)
test2_3.js.gz (starke Komprimierung)

5.) „gzip“ + Minifizierung

Durch Minifizierung von CSS und JS kann man die Dateigröße ebenfalls reduzieren, auch wenn man nicht an die Dateigröße von komprimierten Dateien herankommt, außerdem sinkt der Erfolg der Komprimierung, da wir durch die Minifizierung bereits einige Wiederholungen minimiert haben.

Es folgt ein Beispiel mit „jquery.js / jquery.min.js“:

Zustand

Größe der Datei

gewonnene Größe durch die Komprimierung

nicht minifiziert + nicht komprimiert Datei

250 kB (¼ MB)

nicht minifiziert + schnelle Komprimierung

76,3 kB

173,7 kB

nicht minifiziert + normale Komprimierung

68,3 kB

181,7 kB

nicht minifiziert + hohe Komprimierung

68 kB

182 kB

minifiziert + nicht komprimiert Datei

82,3 kB

minifiziert + schnelle Komprimierung

30,8 kB

51,5 kB

6.) “gzip” + Komprimierung verbessern

Im Gegensatz zur Programmierung, wo man Wiederholungen vermeidet, sollte man im Frontend (HTML, CSS) gezielt Wiederholungen nutzen, um die Komprimierung zu optimieren. So zeigt  das folgende Beispiel wie man die Dateigröße durch die korrekte Positionierung von Attributen der HTML-Tags verbessern kann.

Zwei Dateien mit dem selben Dateigröße, nur die Reihenfolge der Attribute in der zweiten HTML-Dateien (“test1_2.html”) wurden nicht in der selben Reihenfolge angegeben.

html_order_3
test1_1.html
html_order_2
test1_2.html

html_order

Wie man in dem Bild erkennen kann, haben wir die Dateigröße der HTML-Datei um zirka 10% reduziert indem wir den Komprimierungsalgorithmus  bei der Arbeit unterstützen. ;)

Videos:

 

Multi-Platform Mobile Apps via Ionic

Ionic ist ein Frontend-Framework, mit welchem man via HTML5 / JavaScript und CSS native Apps bauen kann. Diese Apps können via “Apache Cordova” auf native Funktionen (Kamera, GPS, etc.) der Geräte zugreifen. Zudem wird Google’s JavaScript Framework “AnguarJS” genutzt und natürlich wird auch “SASS” unterstützt.

Vorbereitung

Man kann Multi-Platform Mobile Apps sowohl unter Windows, Linux oder Mac OS X entwickeln, jedoch ist die Vorbereitung unter Linux / Mac OS X um einiges einfacher.

Ich empfehle an dieser Stelle mal wieder die “.dotfiles” zu installieren.

cd ~ 
git clone https://github.com/voku/dotfiles.git 
cd dotfiles 
source bootstrap.sh

# Standard- & Webworker-Tools installieren

~/dotfiles/firstInstall.sh

Bei der Frage nach den “webworker tools”,  muss diese mit “y” beantwortet werden.

# Android SDK installieren

sudo ~/dotfiles/android_sdk_install.sh

# Java installieren

sudo add-apt-repository -y ppa:webupd8team/java
sudo aptitude update
sudo aptitude install oracle-java7-installer

# Ant installieren

sudo apt-get install ant

 

Nachdem die Installation komplett abgeschlossen ist, muss die “~/.extra”-Datei angepasst werden.

z.B.:

#!/bin/bash                                                                                                                                                                                                       

DEFAULT_USER="lars"
GIT_AUTHOR_NAME="Lars Moelleken"
GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"
git config --global user.name "$GIT_AUTHOR_NAME"
GIT_AUTHOR_EMAIL="lars@moelleken.org"
GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"
git config --global user.email "$GIT_AUTHOR_EMAIL"
git config --global push.default simple

# java - example
export JAVA_HOME=/usr/lib/jvm/java-7-oracle
export JDK_HOME=$JAVA_HOME
export JRE_HOME=$JAVA_HOME
export PATH=$JAVA_HOME/bin:$PATH

# android - example
export ANDROID_SDK_ROOT=/usr/local/android-sdk/
#export ANDROID_NDK=/usr/local/android-ndk/
export ANDROID_HOME=$ANDROID_SDK_ROOT
export PATH=$ANDROID_SDK_ROOT/tools/:$ANDROID_SDK_ROOT/platform-tools/:$ANDROID_SDK_ROOT/build-tools/19.1.0/:$PATH

 

PS: bei Debian (sid) musste ich noch ein wenig nachhelfen, so dass die Android-SDK auch korrekt funktioniert:

sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get install lib32z1 lib32stdc++6

 

Beispiel-App für Android erstellen

ionic start planet-ubuntuusers
cd planet-ubuntuusers
rm -rf www/
git clone https://github.com/voku/planet-ubuntuusers-app www
ionic platform android
ionic build android

Man kann die App nun im Browser (ionic serve), im Android Emulator (ionic emulate android) oder direkt auf seinem Android-Gerät (ionic run android) ausprobieren!!!

 

Links

Es folgen ein paar Links zur App / API / Dokumentation  und zum Beispiel-Quellcode

ANDOIRD APP-DOWNLOAD:
 http://suckup.de/planet-ubuntuusers-json/PlanetApp-debug.apk

QUELLCODE ZUR APP:
https://github.com/voku/planet-ubuntuusers-app

SCREENSHOT:
Planet App

JSON-API: 
http://suckup.de/planet-ubuntuusers-json/json.php

HTML-OUTPUT VIA TWIG:
http://suckup.de/planet-ubuntuusers-json/

QUELLCODE ZUR API:
https://github.com/voku/planet-ubuntuusers-json (in zirka 2 Minuten geschrieben & deployed -> composer is great!!!)

 

DOKUMENTATION:
https://docs.angularjs.org/
http://ionicframework.com/docs/
http://cordova.apache.org/

Twig – PHP

Als erstes möchte ich hier klären was “Twig” ist und wie man diese PHP-Bibliothek verwendet.

Was ist Twig?

Twig ist eine Open Source Template-Engine für PHP und wird z.B. von Symfony verwendet. Damit ist es möglich die Programmierung vom Layout zu trennen und Projekte somit übersichtlicher und sicherer zu erstellen. Zudem kann man Twig relativ einfach erweitern und neue Funktionen oder Filter hinzufügen. Außerdem ist die Dokumentation wirklich gut und die Einarbeitungszeit ist sehr kurz.

 

Schnelle Installation

Damit man einen schnellen Einstig in Twig bekommt, habe ich eine kleine Wrapper-Klasse geschrieben und in einem zweiten Projekt “Twitter Bootstrap” als Twig-Beispiel -Template integriert.

git clone https://github.com/voku/twig-wrapper-example/

Das Projekte ist mit Gunt + SASS + Bower + Composer etc. aufgesetzt, jedoch habe ich alle Vendor-Dateien mit in dem Repository eingecheckt, so dass man keine komplette Toolchain benötigt um die folgenden Beispiele auszuprobieren.

PS: um das Projekt zu updaten bzw. weiterzuentwickeln kann man folgende Befehle ausführen:

cd twig-wrapper-example/
rm -rf vendor/
rm composer.lock
npm install
bower install
composer install
grunt build
grunt watch

 

Syntax

Die Allgemeine-Syntax lässt sich in “output”, “function” und “comment” unterteilen.

output” ->  {{ … }}  -> um Variablen in das Template einzufügen

function” -> {% … %} -> um Funktionen auszuführen

comment” -> {# … #} -> um einen Kommentar einzufügen, welche nur im Twig sichbar ist (nicht im späterem “html”-output)

Variablen

Man kann sowohl Arrays, einfache Variablen oder ganze Objekte an Twig übergeben.

z.B.:

$object = new Object();
$twig->assign('object', $object);
$array = array(1,2,3,4,5);
$twig->assign('array', $array);
$string = 'test';
$twig->assign('string', $string);

Zudem kann man auch Variablen in einem Twig-Template definieren:

{% set totalimages = 4 %}

Filter

Auf der Kommandozeile ist man bereits an Pipes ( “|” ) gewöhnt und kann dies nun auch bei der Entwicklung nutzen. :)

{% set totalimages = object.images | length %}
{{ array[1] | striptags | raw }}

Kontrollstrukturen

“if”-Bedingungen werden wie folgt geschrieben:

{% if (name == "foo") or (name == "bar") %}
    {{ name }}!!!
{% elseif name == "test" %}
    {{ name }} -> was a test
{% else %}
    {{ name }}
{% endif %}

“loops” in Twig: for

{% for asset in headerObject %}
  <img src="{{ asset.url }}">
  <p>{{ asset.caption }}</p>
  {% if loop.index0 is divisibleby(2) %}
    <hr />
  {% endif %}
{% endfor %}

PS: außerdem kann man wie im vorherigen Beispiel – “loop” nutzen, um den Anzahl von aktuellen Durchläufe zu analysieren

 

extends

Eine Hauptfunktionalität ist die Twig-Funktion “extends“. Mit dieser Funktion kann man sein Template erweitern und zuvor definierte Bereiche (block – endblock) wiederum ersetzten.

{%extends “base.twig” %}

base.twig -> index.twig

Der vorherige Befehl bewirkt in der “index.twig” Datei, dass das angegebene Template erweitert wird. Dabei ist es sehr hilfreich möglichst viel HTML-Code in einem Basis-Twig unterzubringen. Anders wie bei vielen anderen PHP-Projekten sollte man nicht so oft via “include” inkludieren, sondern bestimmte Bereiche (blocks) im “base.twig” festlegen und diese mit Inhalten befüllen, erweitern oder leeren.

 

include

Die Funktionalität “include” lässt sich einsetzten um Template-Komponenten (z.B.: einen Slider) an mehreren Stellen einzufügen. Man hat die Möglichkeit beim “include”-Aufruf Variablen zu übergeben, jedoch kann man keine “blocks” von bereits inkludierten Templates mehr ändern.

{% include “inc_carousel.twig” %}

base.twig -> inc_carousel.twig

 

embed

Beim “embed” handelt es sich um eine Mischung aus extending & including, so kann man innerhalb des embed-Aufrufes darin befindliche “blocks” ersetzten.

{% embed “content_sidebar.twig” %}

index.twig -> content_sidebar.twig

 

Twig_Extension

Wem ein bestimmter Filter oder Funktion fehlt, kann dies sehr einfach in Twig  integrieren z.B. -> PluginHtml.php

$twig->addExtension(new PluginHtml());

 

Links

http://knpuniversity.com/screencast/twig/basics | Basics – Video
http://twig.sensiolabs.org/ | Dokumentation

Moderner Build & Development Workflow via Bower, Grunt & Yeoman

Wer die entsprechenden Tools aus der Überschrift noch nicht installiert hat, der sollte zur folgenden Post lesen: -> Toolchain für Webentwickler <-


Modernes Frontend-Development mit Bower, Grunt, Yeoman | IPC13

Slides: https://speakerdeck.com/thorsten/modern-frontend-development

International PHP Conference: Thorsten Rinne (@ThorstenRinne) zeigt die Möglichkeiten von Tools wie Bower, Grunt und Yeoman, mit denen man den kompletten Entwicklungsworkflow im Frontend-Bereich abdecken kann. (auf deutsch)


CSS-Tricks Screencast #124: A Modern Web Designer’s Workflow

Slides: https://speakerdeck.com/chriscoyier/a-modern-web-designers-workflow

CSS-Tricks: Chris Coyier (@Real_CSS_Tricks) Screencast where Chris Coyier explains his workflow.


JavaScript Development Workflow of 2013

Slides: http://dl.dropboxusercontent.com/u/39519/talks/fluent/index.html#/

Fluent 2012: Paul Irish (@paul_irish) Learn what a modern development workflow looks like, from editors and plugins, to authoring abstractions, testing and DVCS integration.


Paul Irish on Web Application Development Workflow

Slides: http://dl.dropboxusercontent.com/u/39519/talks/html5dc-workflow/index.html#1

HTML5DevConf: Paul Irish (@paul_irish) Iterating faster, avoiding bugs through tools, and improved automated testing are great ideas, but in this talk Google’s Paul Irish will show how to really incorporate them into a functional and realistic developer workflow.


… und zum Schluss noch ein Beispiel, wie man mit “Yeoman” & “Grunt” & “Bower” & “AngularJS” eine modere Web-App baut: http://yeoman.io/codelab.html

Toolchain für Webentwickler

Vorwort: Ich arbeite in Düsseldorf bei der “menadwork GmbH” als Webentwickler und vor einigen Monaten habe ich mein Betriebssystem auf Linux (Debian) umgestellt, daher musste ich meine Toolchain / Programmierumgebung neu einrichten. Vorweg kann ich schon mal verraten, dass man sehr gut und effizient damit arbeiten kann. Nur drei, vier Programme (IE, Photoshop, Outlook, MS Office) musste ich per VIrtualBox (Win7) virtualisieren.

Im folgenden wird eine Toolchain / Programmierumgebung für Webprojekte (PHP, HTML, CSS, Sass, JavaScript) eingerichtet. Diese Anleitung werden ich im parallel für Windows und Linux beschreiben.

Übersicht:
1. GIT
2. Webserver + PHP
3. Netbeans / PHPStorm / Sublime Text
4. Composer
5. Ruby && Node.js
6. Bower
7. SASS 
8. Compass
9. auto-prefixer
10. Grunt

1.) git – git-scm.com

Als erstes Installieren / Konfigurieren wir “git” zur Versionskontrolle und um Quellcode von github.com laden zu können. Auch wenn du mit wenigen Leuten oder alleine an einem Projekt arbeitest ist der Einsatz von “git” sehr empfehlenswert. Da man so auch noch nach Wochen / Monaten nachvollziehen kann, warum man welche Änderung gemacht hat und diese zudem ganz einfach rückgängig machen kann.

1.1) Installation:

1.1.1) Linux (Debian / Ubuntu)

sudo apt-get install git

 

1.1.2) Windows
http://msysgit.github.io/

Tipp:

– nutze von Anfang an die git-bash!

– bei der Installation wird nach “PATH” gefragt, hier sollte der zweite Punkt ausgewählt werden, da man ansonsten nur mit der git-bash arbeiten kann

git in der Windows-CMD
git für Windows

– Aktiviere “quick-edit-mode” in den Einstellungen der git-bash (nach der Installation), so dass man schnell kopieren und einfügen kann

– Windows-Laufwerke (Partitionen) sind direkt unter “/” aufgehangen -> z.b. cd /d/xampp/

– “vim ~/.vimrc” -> Konfiguration für “vim

z.B.:

:syntax enable
:set tabstop=2
:set shiftwidth=2
:set expandtab

 

1.2) Konfiguration

1.2.1) “line ending”

Es wird wahrscheinlich zu Probleme (Änderung in jeder Zeile der gespeicherten Datei) bei der Zusammenarbeit von “git unter Windows” & “git unter Linux (Mac)” geben, da diese ein anderes “line ending” haben (\n bzw. \r\n). – http://git-scm.com/book/ch7-1.html#Formatting-and-Whitespace

 

# Windows – Diese wandelt “LF” (\n) in “CRLF” (\r\n) Endungen um, wenn der Befehl “git pull” ausgeführt wird und wandelt dies beim “git commit” wieder zurück

git config --global core.autocrlf true

 

# Linux (Mac) – Diese wandelt “CRLF” (\r\n) in “LF” (\n) Endungen um, wenn der Befehl “git commit” ausgeführt wird

git config --global core.autocrlf input

-> somit sind die Dateien auf dem Repository (z.B.: github oder gitlab) und in der lokalen git-history immer mit “LF” (\n) codiert.

 

1.2.2) “push” 

git config --global push.default simple

-> der Befehl “git push” schiebt nur commits von der aktuellen “branch” zum Repository (branch mit dem selben Namen)

 

1.2.3) “user”

Teile “git” mit wer du bist:

git config --global user.name DEIN_NAME
git config --global user.email DEINE_MAIL@ADRESSE

 

1.2.4) “alias”

Wie in der Linux-Bash (~/.bashrc), kann man auch für git “aliases” (~/.gitconfig) vergeben:

git config --global alias.last 'log -1 HEAD'
git config --global alias.unstage 'reset HEAD --'
git config --global alias.hard 'reset --hard'
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status
git config --global alias.cam commit -a -m

 

1.2.5) “color”

git config --global color.diff auto
git config --global color.ui auto
git config --global color.status auto
git config --global color.branch auto

 

2.) Webserver + PHP

Als Webserver installieren wir uns lokal den “Apache”-Webserver, da diese bei vielen Web-Projekten später auch im Live-System zum Einsatz kommt und wir bereits lokal Dinge wie “.htaccess“-Umleitungen etc. testen kann.

2.1) Installation:

2.1.1) Linux (Debian / Ubuntu)

sudo apt-get install apache2 libapache2-mod-php5 php5-mysql php5-curl php5-gd php5-intl php-pear php5-imagick php5-imap php5-mcrypt php5-memcache php5-ming php5-ps php5-pspell php5-recode php5-snmp php5-sqlite php5-tidy php5-xmlrpc php5-xsl php5-apcu php5-xdebug

Achtung: “php5-xdebug” sollte man nur auf seiner lokalen PC installieren!!!

 

2.1.2) Windows

http://www.apachefriends.org/de/index.html

 

2.2) Konfiguration

Wenn man unter Linux bzw. Mac arbeitet, sollte man den Webserver bzw. PHP so konfigurieren, dass die entsprechenden PHP-Skript-Prozesse mit dem User des Webs laufen. Dies kann man z.B. via suphp oder via php-fpm bewerkstelligen. (Quick & Dirty: die Skripte mit dem eigenen User laufen lassen und das htdocs-Verzeichnis in das eigene Home-Verzeichnis legen)

Unter Windows braucht man sich an dieser Stelle noch keine Gedanken über User-Rechte machen, jedoch spätestens wenn man das Projekte zum ersten mal auf dem Server deployed muss man diesen Schritt auf dem Server wiederholen.

Tipp: hier findet man viele Anleitungen für die Installation von Linux-Servern -> http://www.howtoforge.de/

 

  2.2.1) xDebug -> http://xdebug.org

Unter Windows (XAMPP) ist xDebug bereits vorinstalliert und muss nur noch in der “php.ini”-Datei aktiviert werden. Unter Linux befinden sich die Konfigurationen für PHP-Erweiterungen unter “/etc/php5/config.d/”.

z.B.: für Windows, wenn xampp unter “D:\xampp\” installiert ist

[XDebug]
;zend_extension = /path/to/xdebug.so
zend_extension = "D:\xampp\php\ext\php_xdebug.dll"
;xdebug.profiler_append = 0
;xdebug.profiler_enable = 1
xdebug.profiler_enable_trigger = 1
xdebug.profiler_output_dir = "D:\xampp\tmp"
xdebug.profiler_output_name = "cachegrind.out.%t-%s"
xdebug.remote_enable = 1
xdebug.remote_handler = "dbgp"
xdebug.remote_host = "127.0.0.1"
xdebug.trace_output_dir = "D:\xampp\tmp"
xdebug.remote_port=9000

Info: http://wiki.netbeans.org/HowToConfigureXDebug#How_to_configure_XDebug

 

2.3) erster Test mit PHP

php -v

#MYSQL
php -r 'var_dump(function_exists("mysql_query"));'
php -r 'var_dump(function_exists("mysqli_query"));'

#JSON
php -r 'var_dump(function_exists("json_encode"));'

#BCMATH
php -r 'var_dump(function_exists("bcmod"));'

#MAIL
php -r 'var_dump(function_exists("mail"));'

#GD-LIB
php -r 'var_dump(function_exists("imagejpeg"));'

#SESSION
php -r 'var_dump(function_exists("session_start"));'

#SSH
php -r 'var_dump(function_exists("ssh2_connect"));'

#ZIP
php -r 'var_dump(function_exists("zip_open"));'

#GZIP
php -r 'var_dump(function_exists("gzopen"));'

#HASH
php -r 'var_dump(function_exists("hash_hmac"));'

#MCRYPT
php -r 'var_dump(function_exists("mcrypt_module_open"));'

#XML
php -r 'var_dump(function_exists("DomDocument"));'

#CURL
php -r 'var_dump(function_exists("curl_init"));'

#APC
php -r 'var_dump(function_exists("apc_store"));'

 

2.4) PHPUnit installieren

pear config-set auto_discover 1
pear install --alldeps pear.phpunit.de/PHPUnit
pear install --alldeps phpunit/PHPUnit_SkeletonGenerator

 

3.) Netbeans (HTML5 & PHP) || PhpStorm (kostenpflichtig) || Sublime Text

Als nächsten großen Schritt werden wir uns nun eine IDE installieren hier würde ich für größere PHP-Projekte “Netbeans” bzw. “PhpStorm” empfehlen, obwohl “Sublime Text” auch seine Stärken hat und jeder der das Programm noch nicht ausprobiert hat, sollte es einmal testen!!!

3.1) Konfiguration

3.1.1) Netbeans

3.1.1.1) PHPUnit

Unter den Tools -> Options -> PHP -> PHPUnit-> kann man automatisch nach dem bereits installiertem PHPUnit und dem Skeleton-Generator suchen lassen und anschließend aus jeder PHP-Klasse ein PHPUnit-Template erstellen lassen.

php_skeleton php_skeleton_confignetbeans_php_unit_beispiel

3.1.1.2) xDebug

Auch dieses Tool müssen wir einmal konfigurieren unter Tools -> Options -> PHP -> Debugging

netbeans_debug_xdebug netbeans_debug_xdebug_action

Tipp: Wir können unser PHP-Projekt nun nicht nur Debuggen, sondern auch Profilen. Indem wir den Parameter “XDEBUG_PROFILE=1” per GET oder POST übermitteln und den Output anschließend z.B.: via  KCachegrind visualisieren lassen.

kcachegrind1

 

4.) “composer” – getcomposer.org

composer ist ein Manager für externe Bibliotheken (libs) und dessen Abhängigkeiten in PHP-Projekten.

4.1) Installation

4.1.1) Linux

curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin

 

4.1.2) Windows
https://getcomposer.org/Composer-Setup.exe

 

4.2) Repository -> https://packagist.org/

Auf der Webseite Packagist.org findet man alle Projekte, welche man ohne weitere Anpassungen in seinem Projekt verwenden kann und man kann seine eigenen Projekte einstellen (oder auch eigene Repositories verwenden, falls man diese nicht öffentlich machen will). z.B.: mein Profil -> packagist.org/users/voku/

 

4.3) Konfiguration

Man lege eine Datei mit dem Namen “composer.json” an und sucht sich seine zu installieren Bibliotheken aus, anschließend ein “composer install –optimize-autoloader” bzw. “composer update” und schon kann man die Bibliotheken verwenden (include von “vendor/composer/autoload.php” nicht vergessen).

 

5.) Ruby && Node.js

Bower ist auch ein Manager für externe Bibliotheken, jedoch auf JavaScript, jQuery, SASS, LESS, CSS etc. (A package manager for the web) ausgerichtet. Für die Installation muss man auch Ruby und Node.js installieren, jedoch benötigen noch andere wichtige Tools in unserer Toolchain diese Programme, daher folgt nun zuerst die kurze Installation unter Linux und die etwas ausführlichere für Windows. :P

 

5.1) Installation

5.1.1) Linux (Debian / Ubuntu)

sudo aptitude install ruby-full build-essential nodejs

 

  5.1.2) Windows

Downlaod & Installation von Ruby & Node.js:

http://rubyinstaller.org/ + “DevKit”
http://nodejs.org/download/

Nachdem wir Ruby Installiert haben müssen wir noch das “DevKit” für Ruby herunterladen und in das Verzeichnis in welchem du Ruby installiert hat in das Unterverzeichnis “\DevKit” entpacken. – z.B.: “D:\xampp\Ruby200-x64\DevKit” und dann folgenden Befehl auf der Kommandozeile (ggf. muss man ruby noch zum PATH hinzufügen oder Windows mal wieder neu-starten)

ruby dk.rb init

Anschließend müssen wir die Datei “dk.rb” noch wie folgt anpassen:

# This configuration file contains the absolute path locations of all
# installed Rubies to be enhanced to work with the DevKit. This config
# file is generated by the 'ruby dk.rb init' step and may be modified
# before running the 'ruby dk.rb install' step. To include any installed
# Rubies that were not automagically discovered, simply add a line below
# the triple hyphens with the absolute path to the Ruby root directory.
#
# Example:
#
# ---
# - C:/ruby19trunk
# - C:/ruby192dev
#
---
- D:/xampp/Ruby200-x64

… und können die Installation mit folgenden Befehlen abschließen:

ruby dk.rb review
ruby dk.rb install

 

6.) Bower” – bower.io

Zurück zu Bower, nachdem wir nun Ruby && Node.js installiert haben, können wir nun weiter Tools sehe einfach über die Kommandozeile via npm installieren lassen.

 

6.1) Installation

npm install -g bower

 

6.2) Repository

http://bower.io/search/

 

6.3) Konfiguration

Auch Bower hat eine Konfigurationsdatei “bower.json”, in welcher man die entsprechenden Abhängigkeiten eintragen kann.

Tipp: Video anschauen -> https://egghead.io/lessons/bower-introduction-and-setup

 

7.) “Sass” – sass-lang.com

Sass ist ein Preprocessor für CSS, so dass man Variablen, Schleifen, Funktionen etc. in CSS nutzten kann. Große Projekte wie z.B.: Bootstrap bieten Ihren Quellcode als scss-Version an. Der Code-Style unterscheidet sich nur minimal von “normalem” CSS, wobei hier normal in Anführungszeichen stehen, da man die verschiedenen CSS-Selektoren nicht zwingend verschachteln muss. Man kann auch einfach seine bestehende CSS-Datei in eine SCSS-Datei umbenennen und per “sass” kompilieren oder eine bestehen CSS-Datei (z.B.: test.css) per “sass-convert” Konvertieren.

sass-convert -F css -T scss css/test.css scss/test.scss

 

7.1) Installation

gem install sass [--pre]

 

 7.2) Links

Basics: http://sass-lang.com/guide

Playground: http://sassmeister.com/

HowTos: http://thesassway.com/

 

7.3) Video

 

 8.) “compass” – compass-style.org

compass ist ein Framework, welches auf sass aufbaut und dieses um CSS3-Funktionen und z.B. automatisches erstellen und aktualisieren von CSS-Sprites bietet.

 

8.1) Installation

gem install compass [--pre]

Tipp: wenn man noch Browser unterstützen muss, welche keine Transparenzen via CSS (opacity) können, dann sollte man sich mal “compass-rgbapng” anschauen. Damit werden automatisch Fallback-Bilder (png’s) in der entsprechenden Farbe / Transparenz erstellt und im CSS eingebaut.

 

8.2) Konfiguration

Wir starten indem wir folgende Datei anlegen -> “config.rb”

# Require any additional compass plugins here.
#require "rgbapng"

#add_import_path "vendor/bower/foundation/scss/"
#add_import_path "vendor/bower/normalize-scss/"

# Set this to the root of your project when deployed:
http_path = "/"
css_dir = "css"
sass_dir = "scss"
images_dir = "images"
javascripts_dir = "js"

# You can select your preferred output style here (can be overridden via the command line):
# output_style = :expanded or :nested or :compact or :compressed
output_style = :expanded

# To enable relative paths to assets via compass helper functions. Uncomment:
# relative_assets = true

# To disable debugging comments that display the original location of your selectors. Uncomment:
# line_comments = false
line_comments = true

# If you prefer the indented syntax, you might want to regenerate this
# project again passing --syntax sass, or you can uncomment this:
# preferred_syntax = :sass
# and then run:
# sass-convert -R --from scss --to sass sass scss && rm -rf sass && mv scss sass

 

8.3) HowTo

Nachdem wir die Konfiguration angelegt und ggf. angepasst haben, wird mit dem folgendem Befehl automatisch (bei Änderungen) die entsprechende scss-Datei in eine css-Datei kompeliert.

compass watch

compass_watch

 

9.) “auto-prefixer” – github.com/ai/autoprefixer-rails

Anstatt die entsprechenden CSS3-Funktionen von compass zu verwernden, erscheint es mir einfacher und Sinnvoller entsprechende Vendor-Prefixes automatisch zu erstellen und genau das macht dieses Tool! Man kann es entweder selber aufrufen, in compass oder via “grunt” (dazu kommen wir gleich) integrieren.

 

9.1) Installation

gem install autoprefixer-rails [--pre]

 

9.2.1) HowTo: Grunt + autoprefixer

(Auch wenn ich noch gar nicht zu grunt geschrieben habe, zeige ich schon mal wie, man dies nutzten kann.)

Als erstes wird das Plugin “grunt-autoprefixer” installiert und dann folgender Task in der Datei “Gruntfile.js” angelegt:

    autoprefixer: {
      options: {
        browsers: ['last 4 version']
      },
      multiple_files: {
        expand: true,
        flatten: true,
        src: 'css/*.css',
        dest: 'css/'
      }
    },

 

9.2.2) HowTo: compass + autoprefixer

Folgendes in die compass-Konfiguration “config.rb” einfügen:

  require 'autoprefixer-rails'

  on_stylesheet_saved do |file|
    css = File.read(file)
    File.open(file, 'w') do |io|
      io << AutoprefixerRails.process(css)
    end
  end

 

10.) “Grunt” – gruntjs.com

Grunt ist ein Task-Runner, dass heißt das Programme automatisch z.B. nach dem Speichern einer Datei ausgeführt werden können. Falls jemand das Tool noch nicht im Einsatz hat -> einfach mal Testen!!! Erst dieses Tool verknüpft alle hier vorgestellten Tools zu einer “Toolchain”. Und man ist nur noch einen Schritt davon entfernt automatisierte Tests im Browser, Live-Reload im Brower etc. zu nutzen.

 

10.1) Installation

npm install -g grunt-cli
npm install -g grunt-init

 

10.2) HowTo: Init

Entweder man legt sich selber ein entsprechendes “Gruntfile.js” (Konfiguration) und “package.json”- Datei an oder man nutzt den Befehl:

grunt-init TEMPLATE_NAME

 

10.3) Video

 

Wie im Video erklärt wird, kann man gunt, nachdem man dies einstellt hat, mit dem Befehl “grunt watch” auf Änderungen von beliebigen Dateien, beliebige Tasks ausführen lasse. In meinem Fall lasse ich z.B. bei Änderungen von “*.scss”-Dateien diese via compass in CSS compilieren, anschließend per “autoprefixer” überarbeiten, minifizieren und zum Schluss wird automatisch ein reload von dem entsprechendem Brower-Tab durchgeführt. :)

 

10.4) Pluginshttp://gruntjs.com/plugins

Nachdem man ein Plugin in der Datei “package.json” eingetragen hat, kann man diese über diesen Befehl installieren:

npm install

Tipp: Mit dem Plugin “matchdep” muss man die entsprechenden Plugins nicht noch in der Datei “Gruntfile.js” registrieren.

PS: hier noch mein aktuelles Gruntfile + package

 

Viel Spaß beim programmieren!!! :)

Google – Neue Schriftarten für deine Webseite

“Alle aktuellen Browser können Schriftarten per CSS vom Server holen, um die auf dem Rechner vorinstallierte Auswahl von Fonts zu ergänzen und Webdesignern typografische Handlungsfreiheit zu ermöglichen. In der Praxis scheitern diese Webfonts bisher aber oft am technischen Aufwand, an Lizenzfragen und an unterschiedlichen Implementierungen in den Browsern. Die auf der Google-Entwicklerkonferenz Google I/O vorgestellten Google Font API und Google Font Directory könnten dieser Technik endlich zum Durchbruch verhelfen und das Aussehen von Webseiten nachhaltig verändern.” – heise.de


Google Font Directory
Google Font Directory


Google Web Schriftarten sind mit folgenden Browsern kompatibel:

  • Google Chrome: 4.249.4+
  • Mozilla Firefox: 3.5+
  • Apple Safari: 3.1+
  • Microsoft IE: 6+


1.) Und -> hier <- gibt es ein kleines HowTo von Google, welches zeigt, dass man als erstes folgendes (ggf. Rennie Beanie gegen eine andere Schriftart austauchen) im HTML-Quellcode einfügen muss…



href='http://fonts.googleapis.com/css?family=Reenie+Beanie' rel='stylesheet' type='text/css'>


… du kannst diese Fonts/Schriftarten und auch die nachfolgenden Modifizierungen (CSS) mit WordPress auch über ein Plugin (WP Google Fonts) einstellen.


2.) Als nächstes können wir die Schriftart noch per CSS modifizieren …

.PostHeader a:link
{
font-family: 'Reenie Beanie', Arial, Sans-Serif;
font-size: 32px;
text-decoration: none;
text-align: left;
color: #265273;
}


3.) … und dies z.B. folgendermaßen als Überschrift für WordPress in der Datei (single.php) verwenden. Wie das Ergebnis am Ende aussieht, kannst du hier im Blog sehen. ;-)


<span><h1><a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title(); ?>"><?php the_title(); ?></a></h1></span>


4.) Wer will kann auch erst eine normale Schrift anzeigen lassen und dann die Google-Fonts per JavaScript laden lassen… -> hier <- gibt es diesbezüglich weitere Infos.


<html>
 <head>
 <script type="text/javascript">
 WebFontConfig = {
 google: { families: [ 'Tangerine', 'Cantarell' ] }
 };
 (function() {
 var wf = document.createElement('script');
 wf.src = ('https:' == document.location.protocol ? 'https' : 'http') +
 '://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js';
 wf.type = 'text/javascript';
 wf.async = 'true';
 var s = document.getElementsByTagName('script')[0];
 s.parentNode.insertBefore(wf, s);
 })();
 </script>
 <style type="text/css">
 .wf-loading p {
 font-family: serif
 }
 .wf-inactive p {
 font-family: serif
 }
 .wf-active p {
 font-family: 'Tangerine', serif
 }
 .wf-loading p {
 font-family: serif;
 font-size: 16px
 }
 .wf-inactive h1 {
 font-family: serif;
 font-size: 16px
 }
 .wf-active h1 {
 font-family: 'Cantarell', serif;
 font-size: 16px
 }
 </style>
 </head>
 <body>
 <h1>This is using Cantarell</h1>
 <p>This is using Tangerine!</p>
 </body>
</html>

JavaScript richtig im HTML-Code platzieren

Zurück zur “Webseiten beschleunigen” – Übersicht

3.) JavaScript richtig im HTML-Code platzieren

Zudem sollte man sich überlegen wo man seinen JavaScript Code im HTML-Code platziert, da irgendwelche Effekte für das Menü usw. auch später geladen werden können, so dass erst-einmal die Webseite (Bilder… ) geladen werden kann, sollte jedoch vor dem  </body> platziert werden.


Im allgemeinen kann man jedoch sagen, dass CSS- sowie Javascript-Daten zusammen-gefasst werden können, um HTTP-Requests an dem Server zu verringern. So sollte man also seine CSS- und Javascript-Daten, welche gemeinsam jedoch in verschiedenen Dateien auf einer Webseite genutzt werden, jeweils zu einer einzigen Datei zusammengefasst werden.


Beispiel (ganz schlecht):

<head>
<link rel="stylesheet" type="text/css" href="stylesheet1.css" />
<script type="text/javascript" src="scriptfile1.js" />< script type="text/javascript" src="scriptfile2.js" />
<link rel="stylesheet" type="text/css" href="stylesheet2.css" />
<link rel="stylesheet" type="text/css" href="stylesheet3.css" />
</head>

Hier wird der Download der Dateien stylesheet2.css und stylesheet3.css blockiert, weil die JS-Dateien dazwischen den HTML-Baum verändern könnten.



Beispiel (besser aber noch immer schlecht):

<head>
<link rel="stylesheet" type="text/css" href="stylesheet1.css" />
<link rel="stylesheet" type="text/css" href="stylesheet2.css" />
<link rel="stylesheet" type="text/css" href="stylesheet3.css" />
<script type="text/javascript" src="scriptfile1.js" />
<script type="text/javascript" src="scriptfile2.js" />
</head>

In diesem Beispiel kann man schon mal 100ms einsparen, jedoch können Javascript-Daten nicht parallel heruntergeladen werden…



Beispiel (auch schlecht):

<head>
<link rel="stylesheet" type="text/css" href="stylesheet1.css" />
<script type="text/javascript" > document.write("Hello world!");</script>
<link rel="stylesheet" type="text/css" href="stylesheet2.css" />
<link rel="stylesheet" type="text/css" href="stylesheet3.css" />
</head>

Zuerst wird die Ausführung des Inline-Style-Befehls durch stylesheet1.css verzögert. Anschließend verhindert die Inline-Anweisung wiederum, dass die Stylesheets parallel heruntergeladen werden können.


Beispiel (gut):

<head>
<link rel="stylesheet" type="text/css" href="stylesheet1.css" />
<link rel="stylesheet" type="text/css" href="stylesheet2.css" />
<link rel="stylesheet" type="text/css" href="stylesheet3.css" />
<script type="text/javascript" > document.write("Hello world!");</script>
</head>


Zuerst alle externen Ressourcen einbinden. Alle werden parallel heruntergeladen. Anschließend das Inline-Script. Natürlich sollte das JavaScript möglichst weit unten in den Body stehen, da es genauso das laden von Bildern verzögert.


weitere derartige Beispiele:
code.google.com


Mit folgendem Code können auch JavaScript-Daten parallel geladen werden. Einfach das Array anpassen und fertig…

<script type="text/javascript"> (function() {
var s = [
"/javascripts/script1.js",
"/javascripts/script2.js",
"/javascripts/script3.js",
"/javascripts/script4.js",
"/javascripts/script5.js"
];
var sc = "script", tp = "text/javascript", sa = "setAttribute", doc = document, ua = window.navigator.userAgent;
for(var i=0, l=s.length; i<l; ++i) {
if(ua.indexOf("MSIE")!==-1 || ua.indexOf("WebKit")!==-1) {
doc.writeln("<" + sc + " type="" + tp + "" src="" + s[i] + "" defer></" + sc + "<");
t[sa]("src", s[i]);
t[sa]("type", tp);
doc.getElementsByTagName("head")[0].appendChild(t);
} else {
var t=doc.createElement(sc);
t.setAttribute("src", s[i]);
t.setAttribute("type", tp);
doc.getElementsByTagName("head")[0].appendChild(t);
}
}
})();
</script>


Außerdem könnte man JavaScript Dateien dynamisch nachladen, so dass diese nur geladen werden wenn man diese auch braucht.

Include ("com.iskitz.ajile.examples.IncludeExample");
function testInclude()
{
if("undefined" != typeof com.iskitz.ajile.examples)
if("undefined" != typeof com.iskitz.ajile.examples.IncludeExample)
com.iskitz.ajile.examples.IncludeExample();
else alert( "Include test was unsuccessful :(nn"
+ "Failed to Include [ com.iskitz.ajile.examples.IncludeExample.js ]");
}
/** InludeExample.js: **********************************************************/
Namespace ("com.iskitz.ajile.examples");
com.iskitz.ajile.examples.IncludeExample = function()
{
var wasImported = typeof window["IncludeExample"] != "undefined";
alert( "[ com.iskitz.ajile.examples.IncludeExample ] was "
+ (wasImported ? "Included *and* Imported." : "successfully Included!"));
};

weitere derartige Beispiele:
ajile.iskitz.com


Tipps:

  • alle CSS-Datei per link-tag im Header-Bereich direkt hintereinander schreiben
  • alle Script-Tags direkt vor Body-Bereich (wenn möglich)
  • möglichst keine JS-Anweisungen (inline oder extern) zwischen CSS-Dateien setzen
  • keine JS-Inline-Anweisungen zwischen mehreren Referenzierungen auf JS-Dateien
  • JS-Inline-Anweisungen vermeiden, da diese vom Browser nicht als Datei zwischengespeichert werden können

Webseiten beschleunigen – Übersicht

Der Artikel beschreibt, wie man seine Webseite bzw. seinen Server analysiert und optimiert um Performance zu gewinnen, Ladezeit zu reduzierten bzw. Traffic einzusparen. Man kann einiges an Performance gewinnen, indem man z.B. Bilder im richtigen Format abspeichert bzw. komprimiert, CSS- / JS-Dateien kombiniert und ebenfalls komprimiert oder auch bestimmt Daten vorkomprimiert zur Verfügung stellt.

1.) Webseiten Analyse
1.1) Webseiten Benchmark

2.) Komprimierung
2.1) Bilder komprimieren
2.1.1) Bilder Sprites
2.1.2) PNG-Bilder komprimieren
2.1.3) JPEG-Bilder komprimieren
2.1.4) Bilder komprimieren – Online
2.2) JavaScript/CSS komprimieren
2.2.1) JavaScript/CSS komprimieren – serverseitig
2.2.2) JavaScript/CSS komprimieren – Online
2.3) Apache gzip-Kompression
2.3.1) Aktiviere mod_deflate (gzip) – serverseitig
2.3.2) Aktiviere mod_gzip – serverseitig
2.3.3) Aktiviere gzip – manuell

3.) JavaScript richtig im HTML-Code platzieren

4.) Browser-Cache nutzen
4.1) Browser-Cache manuell einstellen
4.2) Browser-Cache serverseitig einstellen

5.) Webserver beschleunigen
5.1) Apache-Module deaktivieren
5.2) Reverse Proxy (Nginx)
5.3) Nginx als Webserver
5.4) Nginx mit Varnish (Proxy)

6.) PHP optimieren/caching
6.1) PHP-Daten zwischenspeichern
6.2) SQL-Abfrage mittels PHP zwischenspeichern
6.3) PHP-Module deaktivieren
6.4) php.ini (Konfiguration) optimieren

7.) MySQL optimieren
7.1) MariaDB (MySQL-Fork)


Zusammenfassung

Abschließend möchte ich diesen Thema noch einmal kurz zusammenfassen, so dass man ggf. selber weitere Möglichkeiten erkennt, die Ladegeschwindigkeit seiner Webseite zu verbessern, jedoch nicht auf die Technische Umsetzung eingehen.

Kenne deinen Feind !!!

80 bis 90% der schlechten Performance liegt an der Webseite selber und nicht auf der Serverseite, solange nur wenig Besucher auf deiner Webseite sind, braucht man sich eigentlich um einen Revere-Proxy oder eine alternative zu Apache keine oder zumindest nur wenig Gedanken machen, da die Performance erst mit steigender Besucherzahl einbricht. Jedoch sollte man in jedem Fall die gzip-Komprimierung und den Browser-Cache nutzen.

Externe Dateien (Bilder, JS, CSS, Videos…)

Jeder Aufruf einer Datei kostet Performance und Bandbreite, daher sollte man im allgemeinen weniger Requests produzieren, indem man z.B. JS- bzw. CSS-Dateien kombiniert. Dieser negative Einwirkung steigt dramatisch bei externen Dateien von andern Servern und besonders dann, wenn dieser gerade mal nicht erreichbar ist.

Scripte

Immer wenn eine Browser eine Webseite abruft und im HTML-Code ein Script finde, wird das weitere laden der Webseite eingestellt und erst-einmal die JavaScript Engine damit beansprucht, diesen zu interpretieren. Daher sollte man diese Dateien erst am Ende der Webseite laden lassen, so dass der User die Webseite früher sehen kann, auch wenn z.B. die Animation des Menüs erst nach nachgeladen werden muss. Mit diesem Ansatz, erscheint es nur Sinnvoll CSS-Daten am Anfang laden zu lassen, so dass sich die Webseite dem User direkt im korrektem Layout präsentiert.

Bilder

Ein weites großer Bereich sind Bilder, dabei muss man jedoch ein gutes Mittelmaß an Text und Bildern finden, da die User zwar Bilder immer schön finden.. Logo, Hintergrundbild u.s.w. jedoch macht es nur wenig Sinn seine selbst jeder kleine Datei zu optimieren, wenn man oben über der Webseite ein 300 KB großes Bild eingefügt hat. Wie bereit im Artikel beschrieben gibt es jedoch zahlreiche Methoden (PNG- und JPEG-Dateien) diese zu optimieren.

Yahoo hat zudem eine sehr umfassende Liste von weiteren Regeln zusammengestellt, welche man beachten sollte.