HTML5-Buch, zweite Auflage: 194 Seiten mehr mit Sachen, die nicht im IE6 funktionieren

Veröffentlicht am 21. Februar 2011

Cover des HTML5-Buchs, zweite Auflage

Ich muss mich entschuldigen – dieser Blogpost kommt viel zu spät, aber ich war leider die letzten Tage echt ekelhaft krank und damit außer Betrieb. Aber wer aufmerksam mittwittert, der weiß bereits seit einiger Zeit: Die zweite Auflage des HTML5-Buchs ist fertig, bereits vorbestellbar und wird am 28. Februar erscheinen. Sie enthält 194 neue Seiten und vier neue Kapitel (insgesamt 592 Seiten, 14 Kapitel) auf dem Stand vom Anfang Februar 2011 – also inklusive Internet Explorer 9 und Firefox 4. Fast alles, was nicht völlig neu ist, wurde aktualisiert, erweitert oder mit zusätzlichen begleitenden Infos (Links, Polyfills) ausgestattet. Es ist ein neues Buch geworden.

Was steht Neues drin?

Es gibt 194 Seiten mit neuem Stoff, wobei eins der vier neuen Kapitel nur entstanden ist, weil ein altes Kapitel wegen überbordender Länge gesplittet werden musste. Auch in den alten Kapiteln hat sich einiges getan. Insgesamt gibt es folgende größere Neuheiten:

  • Neue Kapitel über Web­ Wor­kers, die File API sowie Er­ken­nung und Nach­rüs­ten von HTML5-Fea­tures
  • Ak­tua­li­sier­te Brow­ser-Kom­pa­ti­bi­li­täts­ta­bel­len für In­ter­net Ex­plo­rer 9 und Firefox 4
  • Enthält alle jün­ge­ren Ent­wick­lun­gen vom Streit und Mul­ti­me­dia-Co­decs bis hin zur Zukunft der Web­stan­dards
  • Über­ar­bei­te­ter Ein­stieg, zu­sätz­li­che Bei­spie­le und neue Tech­ni­ken für se­man­ti­sches HTML5
  • Er­wei­ter­ter Anhang mit zu­sätz­li­chen Co­de­bei­spie­len, detaillierteren Ta­bel­len sowie neuen Listen, Links und Po­ly­fills

Alle übrigen Kapitel wurden aktualisiert und teilweise erheblich erweitert oder umstrukturiert. Sämtliche sonstigen Infos zum Buch (also auch all das, was schon vorher drin stand) sind zusammen mit Code-Downloads, dem kompletten Inhaltsverzeichnis und einer aktualisierten Leseprobe auf dem überarbeiteten html5-buch.de zu finden.

FAQ

Ich hab schon die erste Auflage. Sollte mich die zweite Auflage interessieren?
Nur wenig von dem, was in der ersten Auflage steht, hat im Jahr 2011 noch uneingeschränkte Gültigkeit. Fast alles hat sich in irgendwelchen Details geändert, und das betrifft auch nicht nur die nerdigen JS-APIs –zum Beispiel sind ein paar weitere semantische HTML-Tags hinzugekommen und fast keiner hat es gemerkt. Ich würde die erste Auflage echt nur noch mit größter Vorsicht aufschlagen, denn das Teil ist einfach veraltet.
Gibt es ein preisgünstigeres Upgrade für Besitzer der ersten Auflage?
Leider nein. Der Hauptgrund dafür ist, dass sich mehr als nur die neuen Seiten und Kapitel geändert haben. Bis auf wenige Abschnitte, in denen es in den letzten 12 Monaten keine umwälzenden Entwicklungen gab (Canvas, Drag&Drop), hat sich auf so ziemlich jedem Kapitel etwas getan. Veraltete Informationen wurden entfernt, neue Tricks und Hinweise eingefügt, Erklärungen ausgeweitet, Fehler korrigiert und so weiter. Da wäre ein Upgrade auch nur 50 Seiten weniger dünn als das komplette Buch.
Warum ist das Buch teurer geworden?
Daran sind einfach die zusammen mit der Seitenanzahl angestiegenen Material- und Transportkosten schuld.
Ich möchte das Buch in meinem Blog/Podcast/Magazin besprechen oder verlosen!
Einfach bei melden. Postadresse und Link zu Blog/Podcast/Magazin nicht vergessen
Was kommt in der dritten Auflage?
Falls es auch in Zukunft noch Interesse am Thema gibt, würde ich ganz gerne Kapitel über barrierefreies HTML5 und Web Sockets schreiben. Außerdem wird es Zeit, die Passagen über die Internet Explorer 6 bis 8 so langsam irgendwie auf das Abstellgleis zu schieben … sie vielleicht noch nicht löschen, aber irgendwie in einen Extra-Anhang auslagern oder so. Die stören sonst nur bei der Arbeit. Und ich bin natürlich für Vorschläge offen!

PS.: Sobald ich die letzten Reste meiner Bazillen losgeworden bin, werde ich auch wieder bloggen wie früher™. Versprochen!

XmlHttpRequest und die Worker API

Veröffentlicht am 18. Januar 2011

Ein Gastbeitrag von Rodney Rehm

Browserscope liefert uns eine schöne Übersicht über die HTTP-Spielchen unserer Browser. Leider fehlt ein Test. Nämlich der, der uns mitteilt wie viele XmlHttpRequests (XHR, AJAX) der Browser parallel ausführen kann. Offenbar gehen die Meisten davon aus, dass XmlHttpRequests der Regulierung »Connections per Hostname« unterliegen. Ich übrigens auch - bis letzte Woche.

HTML5 Worker API

Die Worker API erlaubt die reale Parallelisierung von Rechenaufgaben. Wo Worker aus Gründen der Thread-Safety keinen Zugriff auf den DOM haben, dürfen sie aber sehr wohl mit der Außenwelt sprechen. So stellte sich die Frage welchen Regeln diese "wirklich asynchronen XmlHttpRequests" unterliegen würden. Ein kleiner Test sollte ein wenig Licht ins Dunkel bringen. Dabei ist mir aber nicht nicht nur ein einzelnes Licht aufgegangen…

Parallele XmlHttpRequest im window?

Eingangs erwähnt gehen viele Entwickler davon aus, dass so ein aktueller Firefox bis zu 6 XHR-Verbindungen simultan verarbeitet, weil er ja auch 6 HTTP-Verbindungen bedienen kann. Dem ist nicht so. Firefox 3.6 und Chrome 8 verarbeiten immer nur einen einzigen XHR simultan. Nicht so der Safari 5, denn der Held aus Cupertino peitscht auch die XmlHttpRequests mit voller HTTP-Verbindungsbandbreite durch.

XHR in Firefox
XHR in Firefox

Meine Tests waren noch nicht bei der Worker API angekommen, schon hing die Kinnlade auf der Tastatur. Himmel, ich dachte ich wäre WebDeveloper und wüsste was ich mache? Interessant ist auch der Fakt, dass Chrome 8 sich in diesem Punkt wie Firefox 3.6 verhält, wo er doch wie Safari auf Webkit basiert. Das hätte ich nun gar nicht erwartet.

Parallele XmlHttpRequest mit Worker?

Der Test geht weiter. 10 Worker-Instanzen mit jeweils einem XHR stehen nun 10 XHR im normalen window gegenüber. Firefox lässt jeweils 3 XHR aus Workern und 1 XHR aus dem window laufen. Also max. 4 parallele XmlHttpRequests für den Firefox. Safari, der ja schon im window 6 XHR parallel ausführte, zeigt keine Änderung. Chrome verblüfft am meisten. Zum einen ist der Chrom'sche WebInspector nicht in der Lage XmlHttpRequest aus einem Worker im Resources-Tab anzuzeigen. Zum anderen führt er 5 Worker XHR und einen window XHR simultan aus. Also max. 6 parallele XmlHttpRequests für den Chrome.

Firefox führt 4 XHR simultan aus
Firefox: Parallele XmlHttpRequests mit Worker

Erstes Fazit: Mittels den neuen Workern können im Firefox 3.6 max. 4 XmlHttpRequests parallel ausgeführt werden, im Chrome 8 sogar 6 XHR simultan.

Parallele XmlHttpRequest und »Connections per Hostname«?

Nun stellt sich noch die Frage wie sich diese XmlHttpRequests auf die »Connections per Hostname« Restriktion auswirken. Firefox 3.6, Safari 5 und Chrome 8 erlauben jeweils 6 HTTP Verbindungen zum selben Host. Was passiert, wenn 10 XmlHttpRequests und 10 Bilder geladen werden sollen?

Wie zu erwarten war bleibt es auch beim Einsatz der Worker API bei max. 6 HTTP Verbindungen pro Host. Wie mit den unterschiedlichen HTTP-Anfragen umgegangen wird, stellt aber schon die nächste interessante Beobachtung dar. Werden die 10 Bilder und 10 XHR im window angefragt, scheint Safari die XmlHttpRequests zu bevorzugen. Das könnte an der Anfragereihenfolge liegen: ein XHR, ein Bild, ein XHR, ein Bild, […]. Verschieben wir die 10 XHR in Worker, scheinen sich die Anfragen etwas mehr zu vermischen.

Firefox unterliegt der 1 XHR pro window Limitierung. Deshalb werden die 10 Bilder, von denen jeweils 5 neben einem XHR geladen werden können, augenscheinlich bevorzugt. Aber auch im Worker Kontext haben die XHR eindeutig das nachsehen. Reguläre HTTP-Anfragen scheinen eine höhere Priorität als XmlHttpRequest zu besitzen.

Chrome verhält sich beim window wie der Firefox. 1 XHR und 5 Bilder füllen die 6 verfügbaren HTTP-Verbindugnen. Setzen wir die Worker ein, vermischen sich die Anfragen wie auch beim Firefox. Allerdings scheinen nun die XmlHttpRequests bevorzugt zu werden.

Normale HTTP Anfragen und XmlHttpRequests gleichzeitig angstoßen, XHR wird benachteiligt
Firefox: Bilder und XHR

Zweites Fazit: Worker erhöhen zwar die Anzahl parallel ausgeführter XmlHttpRequests, sind aber immer noch an die Limitierung von 6 HTTP-Verbindungen pro Host gebunden.

Zusammenfassung

Wer in seiner AJAX-Applikation unbedingt mehrere XmlHttpRequests ausführen muss, sollte sich die Worker API etwas genauer anschauen – aber übertreibt das Spielchen nicht. Irgendwann werden die Resultate der parallelen XHR wieder in das window gebracht und ins DOM geschossen. Hier kann es schnell zu Engpässen kommen, wenn die DOM-Interaktionen entsprechend schwergewichtig sind.

Über den Autor

Rodney Rehm ist Jahrgang ‘84, hat seine Wurzeln nahe der schweizer Grenze, ist im Internet eher als „globe“ bekannt, und führt seit 2008 eine kleine Agentur am Bodensee. Und das ist auch gut so. Er ist WebDeveloper mit den Schwerpunkten PHP, SQL und Javascript und spielt gerne mit absurden Ideen zur Geschwindigkeitsoptimierung herum. Mit dem Internet beschäftigte er sich seit seines zweijährigen Besuchs einer amerikanischen Privatschule Mitte der 90er. Sein Studium brachte er, wie so viele Webdeveloper, wegen mangelnder Zeit nicht zu Ende. Wo das Interesse seit Anbeginn das Backend war, drang Javascript und somit das Frontend Mitte des letzten Jahrzents immer mehr in den Vordergrund. Er steht für ungepflegte private Webseiten, minimalistische geschäftliche Seiten und twittert gelegentlich.

Kategorie- und Archiv-Dropdowns mit unobtrusive JavaScript

Veröffentlicht am 14. Dezember 2010

Eine gute Website funktioniert, wenn ein Benutzer mit deaktiviertem JavaScript vorbeikommt, genau so gut wie mit aktiviertem Scripting. Man trennt die JS-Schicht der Website sauber von allem anderen (und verzeichtet zum Beispiel auf onclick-Handler im HTML) und legt seine Scripts so an, dass nur die schon vorhandene Funktionalität der Seite verbessern und umformen. So kommen die Besucher sowohl mit als auch ohne JS an ihr Ziel, wenn der Weg ohne Scripting vielleicht etwas mühsamer oder weniger schön ausfällt. Diese Herangehensweise an Scripting auf Websites nennt sich Unobtrusive JavaScript und warum das eine gute Sache ist, erklärt Jenn Lukas in diesem Talk von der JSConf 2010. Neben all den guten Gründen ist das wichtigste Argument für unobtrusive JavaScript, dass es bei entsprechender Planung so einfach umzusetzen ist, dass es grundlos verschenktes Potenzial wäre wenn man darauf verzichten würde. Problematisch kann es allein dann werden, wenn das einem das für die Website verwendete CMS einem einen Strich durch die Rechnung macht – womit wir beim Thema WordPress wären.

Gelegentlich möchte man in seiner Blog-Sidebar Dropdowns-Menüs (select-Elemente) zur Navigation der Kategorien und des Archivs unterbringen und der WordPress-Codex bietet in den Dokumentationen auch entsprechende Lösungen für Kategorien und Archiv an, die allerdings beide nur mit aktiviertem JavaScript funktionieren. In beiden Fällen wird die URL der Ziel-Seite im value-Wert der im Dropdown-Menü verbauten option-Elemente gespeichert und sobald man einen Eintrag auswählt, wird man via JavaScript auf eben jene URL weitergeleitet. Die fast gleiche Funktionalität ließe sich aber auch ganz ohne Scripts erreichen:

  1. Ein altmodisches GET-Formular mit Absendebutton anlegen, das an die Basisadresse der Website sendet
  2. Das select in eben dieses Formular stecken und name="cat" angeben
  3. Den option-Elementen als value den Slug der Kategorien geben

Das Absenden des Formulars resultiert dann in einem Aufruf von blog.de/?cat=kategorie und damit der gewünschten Kategorie, ggf. mit einem Redirect auf die suchmaschinenfreundliche Variante der URL. Das funktioniert für den Besucher genau so gute wie die Lösung aus dem Codex, sieht man einmal davon ab, dass man einen Button anklicken muss. Doch genau hier kann man mit JavaScript eingreifen, den Button verstecken und das Absenden des Formulars über einen via Script eingefügten onclick-Handler übernehmen. Das Endresultat sieht dann für Surfer mit Script wie die Codex-Lösung aus und alle anderen kommen dann eben über einen Klick auf den Button an ihr Ziel und alle sind zufrieden. Also an die Arbeit!

Die Grundlage für das Kategorie-Dropdown bildet ein ganz normales HTML-Formular:

<form id="kategorienform" action="<?php bloginfo('url'); ?>" method="get">
    <label for="kategorienselect">Zu Kategorie springen</label>
    <select id="kategorienselect" name="cat">
        <option value="">-- Bitte auswählen</option>
        <?php
            $categories = get_categories('hierarchical=0');
            foreach($categories as $category){
                $selected = (is_category($category->cat_ID)) ? 'selected' : '';
                echo '<option '.$selected.' value="'.$category->cat_ID.'">'.$category->cat_name.' ('.$category->count.')</option>';
            }
        ?>
    </select>
    <input id="kategorienbutton" value="Kategorie abrufen" type="submit">
</form>

Dieses könnte man so in die Seitenleiste des Dokuments werfen und es würde funktionieren, doch wir wollen ja noch den Absenden-Button loswerden und die Umleitung direkt bei der Auswahl einer Kategorie starten. Hierzu braucht es nicht mehr als 6 Zeilen JavaScript, die man direkt unter dem Formular einfügen kann:

<script type="text/javascript">
    document.getElementById('kategorienselect').onchange = function(){
        if(this.value){
            document.getElementById('kategorienform').submit();
        }
    };
    document.getElementById('kategorienbutton').style.display = 'none';
</script>

Ändert der Benutzer seine Auswahl im select-Element, wird (sofern nicht gerade der „Bitte auswählen“-Eintrag gewählt wird) das Formular automatisch abgesendet, auch ohne den mit style.display = 'none' unsichtbar gemachten Button aktivieren zu müssen – und fertig ist das benutzerfreundliche und trotzdem auch ohne JavaScript funktionierende Kategorie-Dropdown! Das ist zwar etwas mehr Code als die drei Zeilen aus dem Codex, funktioniert dafür aber garantiert bei jedem Besucher. Und das Prinzip ist recht simpel, vorausgesetzt man plant von vornherein entsprechend. Da eben das bei WordPress selbst nicht passiert ist, müssen wir etwas mehr tippen – beziehungsweise im Falle des Archiv-Dropdowns sogar sehr viel mehr:

<form id="archivform" action="<?php bloginfo('url'); ?>" method="get">
    <label for="archivselect">Zu Monat springen</label>
    <select id="archivselect" name="m">
        <option value="">-- Bitte auswählen</option>
        <?php
            $query = "SELECT YEAR(post_date) AS `year`, MONTH(post_date) AS `month`, COUNT(ID) as `posts`
                FROM $wpdb->posts
                WHERE post_type = 'post' AND post_status = 'publish'
                GROUP BY YEAR(post_date), MONTH(post_date)
                ORDER BY post_date DESC";
            $key = md5($query);
            $cache = wp_cache_get('select_archives', 'general');
            if(!isset($cache[$key])){
                $arcresults = $wpdb->get_results($query);
                $cache[$key] = $arcresults;
                wp_cache_set('select_archives', $cache, 'general');
            }
            else{
                $arcresults = $cache[$key];
            }
            if($arcresults){
                global $wp_locale;
                foreach((array) $arcresults as $arcresult){
                    $value = $arcresult->year.$arcresult->month;
                    $text = sprintf(__('%1$s %2$d'), $wp_locale->get_month($arcresult->month), $arcresult->year);
                    $count = '&nbsp;('.$arcresult->posts.')';
                    $selected = (is_month() && get_query_var('year').get_query_var('monthnum') == $value) ? 'selected' : '';
                    echo '<option '.$selected.' value="'.$value.'">'.$text.$count.'</option>';
                }
            }
        ?>
    </select>
    <input id="archivbutton" value="Archiv abrufen" type="submit">
</form>

Das Problem beim Monatsarchiv ist, dass man ohne einen eigenen SQL-Query nicht an die Informationen herankommt, die man für ein Monats-Archiv braucht. So kommt man nicht drum herum, manuell die Datenbank zu bemühen und das Ergebnis händisch zu cachen. Das Prinzip ist aber identisch: einfach ein herkömmliches Formular ausgeben und wieder mit sechs kleinen Zeilen JavaScript aufwerten:

<script type="text/javascript">
    document.getElementById('archivselect').onchange = function(){
        if(this.value){
            document.getElementById('archivform').submit();
        }
    };
    document.getElementById('archivbutton').style.display = 'none';
</script>

Wir fassen zusammen: viele Zeilen Code, aber kompliziert ist das Prinzip nicht. Unobtrusive JavaScript ist eine Frage der intelligenten Planung und wenn die mal, wie bei WordPress, nicht von Haus aus mitgeliefert wird, muss man sich eben behelfen. Bei herkömmlichen Websites gibt es keinen Grund, die Bedienung komplett von JavaScript abhängig zu machen und falls doch mal etwas Mehraufwand entsteht, so ist er die saubere Trennung der Schichten und den Zugänglichkeits-Bonus allemal wert.

Noch mehr Fragen zu HTML5 beantwortet

Veröffentlicht am 13. Dezember 2010

Wie schon im ersten Teil wird es mal wieder Zeit, dass ich ein paar von den HTML5-Fragen, die über nicht-öffentliche Kanäle an mich herangetragen werden nochmal für die Allgemeinheit beantworte. Wie immer gilt: wer mehr Fragen von der Sorte hat, nur her damit! Mich kann man jederzeit via Mail oder Twitter kontaktieren.

Mathematische Formeln in HTML5?

Gibt es mit HTML5 eine Möglichkeit mathematische Gleichungen korrekt darzustellen, so dass kein Plugin mehr nötig ist?

Die gibt es! In HTML5 wird das <math>-Element eingeführt, mit dem man MathML in HTML-Dokumenten verwenden kann. MathML (Mathematical Markup Language) ist ein XML-Format, das durch das W3C spezifiziert wird und das so langsam (ganz langsam) auch auch von den diversen Browsern unterstützt wird. Und in HTML5 kann man ganz einfach das Mathe-XML in herkömmliches HTML stecken:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>MathML</title>
    </head>
    <body>
        <math xmlns="http://www.w3.org/1998/Math/MathML">
            <mrow>
                <mi>a</mi>
                <mo>&#x2062;</mo>
                <msup>
                    <mi>x</mi>
                    <mn>2</mn>
                </msup>
                <mo>+</mo>
                <mi>b</mi>
                <mo>&#x2062;</mo>
                <mi>x</mi>
                <mo>+</mo>
                <mi>c</mi>
            </mrow>
        </math>
    </body>
</html>

Voraussetzung für die korrekte Darstellung ist allerdings ein moderner Browser mit aktiviertem HTML5-Parser (siehe auch: Wozu braucht mein Browser eigentlich einen HTML5-Parser?).

Bilder aus Canvas speichern?

Kann man den Inhalt eines Canvas-Elements irgendwie als Grafik abspeichern?

Da gibt es gleich zwei Möglichkeiten: Erstens ist die Bitmap eines Canvas-Elements im Prinzip nichts weiter als ein herkömmliches Bild im Browser und entsprechend kann man es einfach mit Rechtsklick → „Speichern unter“ abspeichern. Zweitens gibt es mit toDataURL() eine Methode für das Canvas-Element (nicht den 2D-Context), mit der sich der Inhalt der Bitmap in Form eines Base64-codierten PNGs exportieren lässt. Den kann man dann abspeichern oder als src eines img-Elements direkt in das DOM der Website einfügen.

Wohin mit Fragen?

Gibts gute Webforen oder MLs für HTML5-Anwenderfragen? Im Usenet wird man angepöbelt, und Sachverstand ist auch eher nicht da.

Die Erfinder des Ganzen haben für alles gesorgt – die WHATWG bietet ein Forum speziell für Anwender. Ebenfalls empfehlenswert ist der HTML5 Doctor, wo Anwenderprobleme in längeren Postings besprochen und auch entgegengenommen werden.

Auch ich beantworte eure Fragen zu HTML5 gerne! Einfach eine E-Mail schreiben oder Formspring bemühen und ein bisschen Geduld haben – falls ich gerade unterwegs bin, kann es mit Antwort manchmal etwas dauern, doch früher oder später schreibe ich garantiert zurück.