Diesen Artikel habe ich bereits im Firmen Blog von menadwork GmbH veröffentlicht: Düsseldorf, am 04.11.2015 von Lars Moelleken
Der im Mai 2015 veröffentlichte Webstandard HTTP/2 bewirkt, dass Webseiten schneller angezeigt werden. Die Kompatibilität von HTTP/2 ist in fast allen aktuellen Webbrowsern gegeben, wer dies jedoch einsetzen will muss zwangsläufig ein SSL-Zertifikat einsetzen, so dass die Webseite verschlüsselt übertragen wird.
In Kürze vorab:
Haben Browser und Server im vorherigen HTTP/1.x Standard aus dem Jahr 1996 noch sehr viel Zeit mit „Warten“ verbracht, können durch den neuen Webstandard HTTP2 Webseiten schneller angezeigt werden.
Die Kompatibilität von HTTP/2 ist in fast allen aktuellen Webbrowsern gegeben – ein guter Grund, auf das neue Protokoll zu setzen. Serverseitig unterstützt der Apache Webserver (v2.4.17) den entsprechenden Webstandard.
Wer HTTP/2 einsetzen will muss zwangsläufig ein SSL-Zertifikat einsetzen, so dass die Webseite verschlüsselt (via https://) übertragen wird.
Und nun zu den Details …
Um zu erklären, was HTTP/2 ist, sollte man zuerst verstehen wie das Internet grundsätzlich funktioniert. Alle Daten im Computer und auch im Internet sind digital, das bedeutet so viel wie „die Daten werden intern binär verarbeitet“ (z.B. a => 01100001, b => 01100010, c => 01100011).
Um diese Daten nun an einen anderen Computer zu übertragen, benötigt jeder Computer, jedes Smartphone usw. eine eindeutige Adresse, die sogenannte IP-Adresse.
Die Daten werden bei der Übertragung im Internet bzw. im Netzwerk zu sogenannten Paketen zusammengefasst. Jedes Paket wird zusätzlich mit der Information bestückt von welcher IP-Adresse diese gesendet und an welche IP-Adresse diese gesendet werden sollten, solche Informationen nennt man Header-Informationen.
Um nun eine Verbindung von einem zum anderen Computer herzustellen, nutzt man sogenannte Netzwerkprotokolle: Diese definieren einen Standard, so dass unterschiedliche Systeme miteinander kommunizieren können. Im Internet werden UDP (User Datagram Protocol) bzw. TCP (Transmission Control Protocol) verwendet.Das Netzwerkprotokoll UDP ist im Gegensatz zu TCP verbindungslos, d. h. es wird keine eindeutige Verbindung aufgebaut. UDP wird z. B. verwendet um eine Domain (menadwork.com) in die entsprechende IP-Adresse aufzulösen.
Diese Netzwerkprotokolle nutzen unterschiedliche Ports, welche man sich wie Türen vorstellen kann: Jeder Computer hat – ähnlich einem Haus – eine eindeutige Adresse (IP-Adresse) und bietet Platz für unterschiedliche Dinge. diese Dinge können z. B. Webseiten (Port:80), E-Mails (Port:143) oder Dateien (Port:21) sein. Dies ist der Grund, warum man beispielsweise eine Webseite auch wie folgt aufrufen kann: “menadwork.com:80“.
Auch diese Ports sind zumindest von 0 bis 1023 mit fest definierten Anwendungsprotokollen (z. B. HTTP: 80, IMAP: 143, FTP: 21) belegt, so dass man verschiedene Anwendungen über TCP bzw. UDP ansteuern kann.
Die Einführung von HTTP/1.0 und HTTP/1.1
HTTP (Hypertext Transfer Protocol) wurde zusammen mit den Konzepten für die URL und HTML geschaffen und 1996 als HTTP/1.0 publiziert. Für jede verknüpfte Datei in einem HTML-Dokument – wie z. B. Bilder – wurde eine neue TCP-Verbindung aufgebaut.
Im Jahr 1999 wurde dann HTTP/1.1 publiziert, welches unter anderem Pipelining ermöglicht: Dabei werden mehrere HTTP-Anfragen über eine TCP/IP-Verbindung geschickt, so dass man den Overhead beim Verbindungsauf- und -abbau nicht bei jeder HTTP-Anfrage (Bilder, JavaScript-Dateien oder CSS-Dateien) hat. Jedoch ist dieses Feature bei fast allen Browsern standardmäßig deaktiviert und kann somit meistens nicht genutzt werden. Zudem kollidiert hier mal wieder Theorie und Praxis, da zwar theoretisch mehrere Anfragen direkt nacheinander abgearbeitet werden können, aber das sogenannte “head-of-line blocking”-Problem tritt auf: Denn die Anfragen werden noch immer nach dem FIFO-Prinzip (First In – First Out) verarbeitet und die erste Anfrage muss vor der zweiten Anfrage vom Server verarbeitet werden. Man kann sich dies wie die Kasse beim Supermarkt vorstellen: Nur, weil man mehrere Kunden an einer Kasse bedient heißt dies nicht, dass diese schneller bedient werden, solange man auch hier nach dem FIFO-Prinzip arbeitet.
Der neue Webstandard HTTP/2
HTTP/2 wurde im Mai 2015 veröffentlicht und unterstützt unter anderem das Zusammenfassen von mehrere HTTP-Anfragen über ein Multiplexverfahren. Beim Multiplexen werden Daten gebündelt und gemeinsam übertragen. Außerdem werden die Daten und Header nun komprimiert übermittelt und Daten werden binär kodiert übermittelt.
Webseite via HTTP/1.1 laden | Webseite via HTTP/2 laden |
1. Erstellt sechs bis acht HTTP-Verbindungen zum Server | 1. Erstellt eine Verbindung zum Server |
2. Anfrage der HTML-Seite | 2. Anfrage der HTML-Seite |
3. Empfang der HTML-Seite | 3. Empfang der HTML-Seite |
4. Decode der HTML-Seite | 4. Decode der HTML-Seite |
5. Erstellt sechs bis acht Verbindungen zu Dateien in der HTML-Seite, ohne Prioritäten
(unkomprimierten, plain-text Header) |
5. Empfang von allen Dateien in der HTML-Seite, mit Prooritäten
(komprimierte, binary Header) |
6. Die Verbindung wartet, bis die angeforderte Datei ankommen ist | (Dateien werden über den gemultiplexten
Stream gesendet) |
7. Fordert die nächste Datei, auf der jetzt offenen Verbindung an | — |
8. Wiederhole Punkt 6-7 bis alle Dateien angekommen sind | — |
9. Schließe sechs bis acht HTTP-Verbindungen | 8. Schließe die eine Verbindung |
Quelle: https://www.nginx.com/wp-content/uploads/2015/09/NGINX_HTTP2_White_Paper_v4.pdf
Statement von Google: “Google observed an ~88% reduction in the size of request headers and an ~85% reduction in the size of response headers after enabling compression. This amounted to a saving of between 45 and 1142 ms in the overall page load time.” Quelle: http://www.chromium.org/spdy/spdy-whitepaper
Diese binären Daten werden als Streams bezeichnet und können mit unterschiedlichen Priorisierungen angefordert werden, zum Beispiel 1. HTML, 2. JavaScript, 3. CSS, 4. Fonts, 5. Bilder. Zudem kann man theoretisch mit der Funktion “Server-Push” auch Dateien zum Client senden, welche dieser gar nicht angefragt hat, so könnte man HTML, CSS und Font senden, wenn nur das HTML angefragt wurde, jedoch ist dieses Funktion z. B. in der aktuellen Version von Apache (v2.4.17) noch nicht implementiert.
Im offiziellen Standard ist HTTP/2 zwar auch ohne SSL (https://) geplant, aber die Browser-Hersteller bieten HTTP/2 nicht ohne Verschlüsselung an. Da SSL-Zertifikate jedoch momentan nicht kostenlos sind, haben Mozilla, die Electronic Frontier Foundation (EFF), Cisco, Akamai und IdenTrust eine neue SSL-Zertifizierungsstelle (CA) mit dem Namen “Let’s Encrypt” gegründet, welche in Zukunft kostenlose Zertifikate ausstellt.
UPDATE: (04.11.2015)
Let’s Encrypt hat heute sein Beta-Programm gestartet, sodass man über wenige Zeilen auf der Kommandozeile bereits ein gültiges SSL-Zertifikat nutzen kann.
git clone https://github.com/letsencrypt/letsencrypt
cd letsencrypt
./letsencrypt-auto --agree-dev-preview --server \
https://acme-v01.api.letsencrypt.org/directory certonly
Was ändert sich für Webentwickler?
Jede Technik, welche HTTP-Anfragen reduziert, ist mittels HTTP/2 obsolet, da einzelne kleine HTTP-Anfragen nun schneller abgearbeitet werden als eine große Anfrage. Zu diesen Techniken zählen z. B. das Zusammenfassen (concat) von JavaScript- und CSS-Dateien oder auch das Sprite-Image, welches mehrere kleine Bilder zu einem Bild darstellt. Aber auch das aufteilen von HTTP-Request auf verschiedene Subdomains ist nicht länger sinnvoll, da ansonsten wieder neue TCP-Verbindungen aufgebaut werden müssen. Zudem ist das „Inlinen“ von z. B. Bildern via Data-URIs (data:image:png;base64,…) nicht mehr zweckmäßig.
Mit der „Server-Push-Funktion“ können bereits einige Webserver umgehen, so dass man serverseitig bestimmen kann, dass bestimmte Dateien zusätzlich ausgeliefert werden sollen, wenn z. B. eine HTML-Datei angefragt wird. Dafür müssen in den meisten Fällen bestimmte Header-Daten definiert werden (z. B. X-Associated-Content: “/foo.css”:1,”/bar.js”:1,”/baz.js”:1).
Alle diese Änderungen spielen Frameworks wie Polymer in die Hände, da der Quelltext hier in einzelne Pakete bzw. Komponenten geordnet ist und somit schneller übertragen werden kann.
Was ändert sich für Administratoren?
Administratoren müssen zunächst Server aktualisieren, da z. B. nur die aktuelle Version von Apache (v2.4.17) HTTP/2 unterstützt. Darüber hinaus müssen Pakete für die verschiedenen Linux-Distributionen müssen gebaut werden.
Indem via HTTP/2 die HTTP-Anfragen über eine TCP-Verbindung laufen, werden weniger Verbindungen pro User zum Server aufgebaut, der Web-Server benötigt weniger Speicher und die CPU-Last wird verringert.
HTTP | HTTPS | SPDY (HTTP/2) | |
Max. pages/s | 16.3 @ 120 users | 15.9 @ 120 users | 98 @ 777 users |
Response @ 100 users | 1.1s | 1.3s | 1.1s |
Response @ 120 users | 1.4 s | 1.5s | 1.1s |
Response @ 200 users | 7.1s | 7.8s | 1.1s |
Response @ 777 users | 70.2s | 72s | 2.7s |
First error | 405 Users | 225 Users | 884 Users |
Quelle: http://www.neotys.com/blog/performance-of-spdy-enabled-web-servers/
Server-Anfrage | Speicherverbrauch (für die selbe Beispiel-Anfrage) |
HTTP | 59 MB |
HTTPS | 79 MB |
SPDY (HTTP/2) | 24 MB |
Quelle: http://www.neotys.com/blog/performance-of-spdy-enabled-web-servers/
Vergleich der Ladezeiten
Außerdem sollte man sich ein wenig mehr mit dem Thema SSL auseinandersetzen, so kann man z. B. über den “Strict Transport Security“-Header die Ladezeit von HTTP/2 Seiten weiter reduzieren. Dies geschieht, indem die Nutzung von HTTPS sozusagen gecacht wird und Anfragen via HTTP direkt via HTTPS verarbeitet werden.
Quellen:
Apache & HTTP/2: http://www.apache.org/dist/httpd/CHANGES_2.4.17
“Can I use” HTTP/2: http://caniuse.com/#search=http%2F2
Info zu HTTP/2: http://http2-explained.readthedocs.org/en/latest/
FAQ zu HTTP/2: https://http2.github.io/faq/
Spec zu HTTP/2: https://http2.github.io/http2-spec/
Präsentation zu HTTP/2 (von @derSchepp): https://schepp.github.io/HTTP-2/#/
Präsentation zu HTTP/2 (von @mnot): https://www.mnot.net/talks/http2-expectations/#/
W3C – preload: http://w3c.github.io/preload/
nghttp2 – Server-Push: https://nghttp2.org/documentation/nghttpx.1.html#server-push
heise: HTTP/2: http://www.heise.de/netze/artikel/Wie-HTTP-2-0-das-Surfen-beschleunigt-2164146.html
Free SSL: https://letsencrypt.org/2015/10/19/lets-encrypt-is-trusted.html
heise: Free SSL: http://www.heise.de/netze/meldung/Let-s-Encrypt-Meilenstein-zu-kostenlosen-SSL-Zertifikaten-fuer-alle-2679600.html
Demos:
https://http2.akamai.com/demo
http://http2.golang.org/gophertiles?latency=0