Sonntag, 31. Januar 2010

SVG - Vektorgrafik mit Geschwindigkeitsvorteil

In einem meiner letzten Projekte musste ich Grafiken für eine vertikale Navigation erstellen. Um die Ladezeiten zu reduzieren, entschied ich mich für die CSS-Matrix-Technik. Mit dieser Technik speichert man alle Hintergrundgrafiken in einer einzelnen großen Grafik und greift per CSS auf einen Ausschnitt zu. Soweit so gut.

Leider war die Navigation durch ein ungewöhnliches Design sehr komplex:

  1. Es gibt verschiedene Ebenen mit unterschiedlichen Höhen und Hintergründen.

  2. Wenn ein Menüelement ein Unternemenü anzeigt, ändert sich die Höhe und der Hintergrund des Menüelements.

  3. Es gibt verschiedene Zustände für ein Menüelement: normal, mouseover und selected.

  4. Es gibt unterschiedliche Farbkennzeichnungen für einen gleichen Menütyp.

Ganz schön kompliziert, obwohl das Design kinderleicht aussieht. Wer sich nichts darunter vorstellen kann, kann sich gerne die Website als Beispiel ansehen: www.phibu.de

Die dazugehörige background-Grafik sieht so aus:

Ein Designer legt eine solche Grafik mittels Hilfslinie in Photoshop an. Als Geek programmiert man dagegen ein kleines PHP-Script, das einem die Grafik erstellt. Ursprünglich wollte ich das Bild über Imagemagick erstellen. Doch ich entschied mich aufgrund des einfachen Handlings für die Nutzung von SVG.
SVG steht für Scalable Vector Graphics und nutzt die XML-Auszeichnung für die Beschreibung von zwei-dimensionalen Vektor-Grafiken. Jeder, der HTML versteht, kann SVG für die Erstellung von Grafiken nutzen. Es ist ganz einfach. Zu erst definiert man den Doctype:

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

Dann leitet man die Grafik ein:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events" version="1.1" baseProfile="full" width="932" height="306">

Dann macht es Sinn, einen Titel und eine Beschreibung zu vergeben:

<title>phibu</title>
<desc>Hintergründe für Menüs erstellen</desc>

Nun kommt die eigentliche Beschreibung der geometrischen Figuren:

<!-- Hintergrundfarbe -->
<rect x="0" y="0" width="233" height="306" fill="#fff" />
<!-- Dicke Balken -->
<rect x="0" y="0" width="233" height="34" fill="#fff" />
<rect x="0" y="34" width="233" height="34" fill="#ede8da" />
<rect x="0" y="68" width="233" height="34" fill="#bcad92" />
<rect x="0" y="102" width="233" height="26" fill="#fff" />
<rect x="0" y="128" width="233" height="26" fill="#ede8da" />
<rect x="0" y="154" width="233" height="26" fill="#bcad92" />
<rect x="0" y="180" width="233" height="16" fill="#ede8da" />
<rect x="0" y="196" width="233" height="16" fill="#ede8da" />
<rect x="0" y="212" width="233" height="16" fill="#bcad92" />
<rect x="0" y="228" width="233" height="26" fill="#ede8da" />
<rect x="0" y="254" width="233" height="26" fill="#ede8da" />
<rect x="0" y="280" width="233" height="16" fill="#bcad92" />
<rect x="0" y="296" width="233" height="16" fill="#ede8da" />
<!-- 13px Left -->
<rect x="0" y="0" width="13" height="306" fill="#bcad92" />
<!-- Trenner -->
<rect x="0" y="0" width="233" height="1" fill="#bcad92" />
<rect x="0" y="32" width="233" height="2" fill="#fff" />
<rect x="0" y="34" width="233" height="1" fill="#bcad92" />
<rect x="0" y="66" width="233" height="2" fill="#fff" />
<rect x="0" y="100" width="233" height="2" fill="#fff" />
<rect x="0" y="102" width="233" height="1" fill="#bcad92" />
<rect x="0" y="128" width="233" height="1" fill="#bcad92" />
<rect x="0" y="252" width="233" height="2" fill="#fff" />
<rect x="0" y="278" width="233" height="2" fill="#fff" />
<rect x="0" y="304" width="233" height="2" fill="#fff" />
<!-- Pfeile -->
<polygon points="13,199, 18,203,13,207" style="fill:#bcad92;" />
<polygon points="13,257, 18,261,13,265" style="fill:#bcad92;" />

Und zum Schluss sollte man das schließende Tag nicht vergessen:

</svg>

Um ehrlich zu sein, habe ich nur die erste Spalte erstellt und dann in PHP mit sprintf() und einer array-Schleife die gesamte Grafik erstellt. Das ging recht schnell und zeigt auch den Vorteil dieser Technik.

Am liebsten hätte ich die SVG-Grafik direkt im CSS benutzt. Leider kann der IE bis heute kein SVG interpretieren (es seie denn, man installiert ein Adobe-Plugin). Daher habe ich die Grafik als PNG gespeichert. Firefox, Chrome, Safari und Opera haben zum Glück keine Probleme mit SVG.

Die schnellste Möglichkeit, eine SVG-Grafik in ein anderes Grafik-Format zu konvertieren: In Opera (dem besten Browser der Welt) kann man mit der rechten Maus-Taste eine SVG-Grafik in die Zwischenablage kopieren und dann in einem beliebigen Grafikprogramm einfügen und im gewünschten Format speichern. Ich habe keine Möglichkeit gefunden, die SVG-Grafik schneller zu konvertieren:-P

Ich empfehle allen Interessierten folgende Links:

Einige weitergehende Möglichkeiten mit SVG:

Für die Zukunft sollte man SVG und das data URI Schema im Auge behalten. Mit der data-URL-Technik kann man Daten wie z.B. eine SVG-Grafik direkt im HTML-Code verankern. Leider sammelt der Internet Explorer auch hier wieder Minuspunkte. Erst der IE8 unterstützt data-URI und dann auch nur bis 32kB:-P

Sonntag, 17. Januar 2010

Komprimierung von statischen Dateien mit PHP

In dem heutige Artikel schreibe ich über die Möglichkeit, die Komprimierung von statischen Dateien durch PHP zu realisieren. Ob diese Lösung sinnvoll ist, muss jeder selbst entscheiden.

Fangen wir zu erst mit der technischen Umsetzung an. Wenn wir PHP-Anweisungen in CSS-, Javascript- oder HTML-Dateien ausführen wollen, können wir dies sehr einfach über .htaccess-Anweisungen tun:

AddHandler application/x-httpd-php .css
AddHandler application/x-httpd-php .js
AddHandler application/x-httpd-php .htm .html
php_flag zlib.output_compression on
php_value zlib.output_compression_level 9
auto_prepend_file = "pre.php"
short_open_tag = 0

Die AddHandler-Anweisungen bewirken, dass alle Dateien mit der Endung .css, .js, .htm oder .html durch den PHP-Interpreter gejagt werden. Mit der vierten Zeile schalten wir die Komprimierung für die Ausgabe ein und mit der fünften Zeile wird die Ausgabe maximal komprimiert. In der sechsten Zeile wird die Ausgabe durch die pre.php gejagt. Diese Angabe nutzen wir, um den richtigen Header zu setzen. Die siebte Zeile verhindert, dass z.B. XML-Angaben (<?xml) fälschlicherweise als PHP-Angabe interpretiert werden.

Die Datei pre.php könnte wie folgt aussehen:

<php
$path = pathinfo($_SERVER['SCRIPT_NAME']);

if ($path['extension'] == 'css') {
header('Content-type: text/css');
}

if ($path['extension'] == 'js') {
header('Content-type: application/x-javascript');
}

if ($path['extension'] == 'htm' || $path['extension'] == 'html') {
header('Content-type: text/html');
}
?>


Mit diesen wenigen Handgriffen werden nun alle CSS-, Javascript- oder HTML-Dateien komprimiert ausgegeben. Eine ideale Lösung, wenn der Hoster die Anweisungen mod_gzip_on oder mod_deflate in der .htaccess nicht erlaubt.

Ich möchte zum Schluss noch einige Hinweise geben:
  • Komprimierung macht wenig Sinn, wenn die Dateien klein sind. Man sollte daher z.B. mehrere CSS-Dateien (oder Javascript) zu einer Datei verschmelzen.
  • Man sollte das Ergebnis immer sinnvoll cachen, um den Server nicht mit überflüssiger Komprimierung zu belasten.
  • Der IE6 kann komprimierte Dateien nicht im Cache halten.
  • Man kann dynamisches CSS (z.B. Hintergrundbild nach Uhrzeit oder Herkunft setzen) sehr leicht mit PHP realisieren. Das führt allerdings bei stark frequentierten Sites zu hoher Systemlast, weil diese Ergebnisse nicht gecacht werden sollten.
  • Man sollte die Komprimierung aus Sicherheitsgründen auf bestimmte Verzeichnisse (z.B. /css/ oder /js/) beschränken.

Sonntag, 3. Januar 2010

Wie man seine Website vor Schurken schützt

Als Neuling freut man sich, wenn die Websitestatistik sehr viele Besucher am Tag ausspuckt. Ein Profi wittert dagegen sofort Ärger. In der Tat sind die meisten Einträge auf einer Website oft keine erwünschten, menschlichen Besucher, sondern automatisierte Datensammler und Hackerprogramme von Schurken.

Solche Schädlinge verursachen in vielfältiger Weise einen Schaden für den Betreiber einer Website:

  1. Es werden automatisiert Daten ausgelesen und für unerwünschte Zwecke missbraucht. Das bekannteste Beispiel ist das Sammeln von Mail-Adressen von Spammern.
  2. Die komplette Website wird kopiert und für betrügerische Absichten missbraucht. Besonders betroffen sind Shopbesitzer. Schurken kopieren einen Shop und nehmen das Geld für Bestellungen an, ohne die Ware zu liefern. Die geprellten Kunden wenden sich erbost an den nichts ahnenden Shopbetreiber und leiten rechtliche Schritte ein.
  3. Es wird auf der Website gezielt nach Schwachstellen gesucht. Diese sogenannten Exploits werden in vielfältiger Weise von den Schurken genutzt. Auf kommerziellen Sites (Shops, Banken, Telekom usw.) werden z. B. Adress- und Bankdaten ausgespäht und später missbraucht. Oft werden gekaperte Websites in Zombies verwandelt und führen im Auftrag der Schurken Schadaktionen aus. Eine Armee von Zombiehostings kann durch permanente Abfragen einen Webserver stilllegen. Diese Angriffe nennt man DDOS - Denial of Service.
  4. Es werden Inhalte wie Texte, Bilder und Dokumente kopiert. Der Schurke integriert die Inhalte auf seiner eigenen Website. Der Websitebetreiber verliert Kunden und hat Einbußen im Pageranking.
  5. Man kann seine Webstatistiken nicht mehr zur Analyse und Marketingplanung verwenden, weil die Daten fehlerhaft sind.

Was kann man tun, um sich vor diesen Problemen zu schützen? Es gibt einfache Regeln zur Bekämpfung von Schurken, die ich als Checkliste mit Verlinkung zu hilfreichen Sites präsentieren möchte:


Bei meinen Untersuchungen habe ich festgestellt, dass sich sehr viele Spider an einer simplen Umleitung die Zähne ausbeissen. Meine berufliche Website leitet z.B. von der Startseite permanent auf eine Unterseite weiter:

www.domain.de/
301 -> www.domain.de/de/

Da ich auf der Website mit relativen Links arbeite, versuchen die schlecht programmierten Spider im root-Verzeichnis anstatt im de-Verzeichnis alle Seiten zu öffnen. Intelligente Spider wie z. B. die von Google, Bing oder !Yahoo indizieren dagegen alle Inhalte korrekt:-)

Wer alle Tipps beherzigt, wird weniger - aber dafür gewollten Traffic auf seiner Website haben. Das bedeutet deutlich mehr Sicherheit vor Schurken und mehr Planungssicherheit beim Internetmarketing.

PS Beim Blocken via .htaccess sollte man Vorsicht walten lassen, um nicht aus Versehen erwünschte Besucher zu blockieren.