On Github Schepp / HTTP-2
Die Zukunft beginnt jetzt.
Wir schreiben das Jahr...
und
findet seine erste Erwähnung
offiziell als HTTP/1.0 spezifiziert.
Je eine kurzlebige TCP-Verbindung pro HTTP-Abfrage/Antwort-Pärchen
Daten werden ASCII codiert übertragen
Header sind beliebig erweiterbar und werden bei jeder Anfrage mitgeschickt
GET /fotostrecke/screenshots-spiegel-online-1996-bis-heute-fotostrecke-16056-3.html HTTP/1.1 Host: www.spiegel.de Connection: keep-alive Cache-Control: no-cache Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Pragma: no-cache User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36 DNT: 1 Accept-Encoding: gzip,deflate,sdch Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4,fr;q=0.2 Cookie: POPUPCHECK=1402636825271; JSESSIONID=FC8674D0216AB1B92E09619BCD8CC9C7; spVcData2=6-10%3B10-15; __utma=159392383.976977501.1321345516.1402553897.1402569936.627; __utmc=159392383; __utmz=159392383.1402553897.626.40.utmcsr=facebook.com|utmccn=(referral)|utmcmd=referral|utmcct=/; __utmv=159392383.|1=custID=f380b31359c26298908199a247d8a3f1=1; mx_nam_id=03de4a6b-b79e-4c74-81eb-7c4999e36205
wird HTTP/1.1 entwickelt. Es wird 1999 spezifiziert.
Spezifiziert persistente TCP-Verbindungen
...helfen, den Effekt von TCP Slow Start zu reduzieren
Um die Serverlast herunterzufahren wird die Anzahl erwünschter TCP-Verbindungen eingeschränkt:
single-user client SHOULD NOT maintain more than 2 connections with any server or proxy.
In der Praxis halten die Browser 6 Verbindungen zu einem Host auf.
Stehen sie hinter einem Proxy sind es nur 2 - 4.
Spezifiziert außerdem Pipelining
Beim Pipelining kann ein Requests abgesetzt werden, noch BEVOR die Antwort des vorherigen da ist.
Durch Pipelining werden Latenzen zwischen den Requests einer TCP-Verbindung nicht mehr aufaddiert.
Pardon: WÜRDEN...
Schade.
HTTP Requests: von 3 auf 96
An increase from 5Mbps to 10Mbps results in a disappointing 5% improvement in page load times.
Zeitverlust abhängig von Servergeschwindigkeit
Browser machen nur 6 parallele TCP-Verbindungen auf.
(bzw. 2 - 4 hinter einem Proxy)
Das Ergebnis: Aufaddieren von Latenzen
Requests müssen in Reihe abgearbeitet werden.
Pipelining würde da helfen.
Auch ein Problem: Das "First in Line Blocking"
Sind alle TCP-Verbindungen mit Anfragen belegt, kann sich der Browser vorerst nicht mehr umentscheiden.
Blöd, wenn der Browser genau dann das <script>-Tag im Fuß der Seite findet.
Das ständige Mitsenden der Header führt zu langsameren Anfragen.
Ein durchschnittlicher Header liegt bei 600 Bytes.
Der SPON Header mit samt Cookie kommt z.B. auf knapp 1 KB.
Übertragungszeit bei einem 1 MBit/s Upstream: 10 ms pro Request.
grunt.initConfig({ concat: { options: { separator: ';', }, dist: { src: ['src/a.js', 'src/b.js', 'src/c.js'], dest: 'dist/scripts.js', }, }, });
grunt.initConfig({ sprite:{ all: { src: 'path/to/your/sprites/*.png', destImg: 'destination/of/spritesheet.png', destCSS: 'destination/of/sprites.css' } } });
<svg viewBox="0 0 100 100"> <use xlink:href="defs.svg#icon-1"></use> </svg>
Ändert sich ein Fragment aus diesen Datei-Paketen, muss alles neu übertragen werden.
"Domain Sharding"
Jeder zusätzliche Host muss per DNS-Abfrage aufgelöst werden.
Jeder zusätzliche Host muss durch die TCP Slow Start Phase.
Ab 4 Hosts dreht sich der Vorteil ins Negative um.
(siehe auch: Genesis)
Daten werden binär codiert übertragen.
textual protocols like HTTP/1.x [...] often have a number of affordances to “help” with things like whitespace handling, capitalisation, line endings, blank links and so on.
Headerdaten werden nur einmal zwischen den Parteien ausgetauscht. Sie gelten fortan für alle nachfolgenden Requests automatisch.
Wenn sich Header-Abschnitte später ändern, werden nur diese Teile neu übertragen (z.B. nach einem Login).
Headerdaten werden komprimiert.
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.
Es wird nur eine einzelne TCP-Verbindung zu jedem Host geöffnet.
Alle Übertragungsfragmente werden in diesen einen Datenstrom hineingewoben (gemultiplexed)
Es handelt sich also um ein automatisches Spriting/Concatenieren auf Protokollebene!
HTTP/2 kann das Mischverhältnis der in seinen Datenstrom gewobenen Daten zu jeder Zeit verändern und an neue Gegebenheiten anpassen.
Auch kann die Übertragung einer angefangenen Datei komplett gestoppt und verworfen werden.
Der Browser kann so Ressourcen mit verschiedenen Prios anfordern:
Ebenso kann der Server Ressourcen, die er für relevant hält, initiativ durch die Leitung drücken.
Das nennt sich dann "Server Push".
Von 640 Bildfragmenten werden zuerst die des Schriftzugs Übertragen:
ist bestandskompatibel und vollkommen transparent.
HTTP/2 wird grundsätzlich SSL-verschlüsselt verpackt, damit keine Übermittlungsstelle und auch kein Proxy etwas kaputt macht.
(um zu vermeiden, was mit HTTP-Pipelining passiert ist)
Zudem wird die SSL-Handshake-Phase genutzt, um sich gegenseitig über HTTP/2-Fähigkeiten zu informieren.
Eine Aushandlung via unverschlüsseltem HTTP ist möglich:
GET /page HTTP/1.1 Host: server.example.com Connection: Upgrade, HTTP2-Settings Upgrade: HTTP/2.0 HTTP2-Settings: (SETTINGS payload in Base64)
Gegenstelle kann kein HTTP/2:
HTTP/1.1 200 OK 3 Content-length: 243 Content-type: text/html (... HTTP 1.1 response ...)
Gegenstelle kann HTTP/2:
HTTP/1.1 101 Switching Protocols 4 Connection: Upgrade Upgrade: HTTP/2.0 (... HTTP 2.0 response ...)
(Anwendungsszenario: Server-zu-Server-Kommunikation)
SPDY clients consume one Apache worker instead of six
Ramp-up from 1 to 1000 users for 20 minutes.1 page call, wait for 5s, restart.
(weniger ist besser)
*= ab OSX 10.11+ **= auf Windows 10+, auf Windows 8 nur SPDY
*= Wird gerade durch Chrome (Views) ersetzt **= IE 11 auf Windows Mobile 8.1 kann nur SPDY
Siehe HTTP/2 Implementations und Wikipedia
(Notfalls via zwischengeschaltetem HTTP/2-fähigem Load-Balancer)
Es bringt uns keinerlei Vorteile mehr.
(stattdessen erzeugt es nur überflüssige DNS-Lookups)
Außerdem: Ein einzelner Host kann die Ressourcen-Priorisierung besser verwalten.
Stattdessen: Zusehen, ob man seine Dateien nicht automatisiert noch kleiner bekommt!
(verrückt, oder?)
(Aber so kommen wir nah an das Konzept von Delta-Updates heran)
Server Push für alle kritischen Ressourcen konfigurieren!
Inoffizieller Standard , solche Ressourcen für den Server zu kennzeichnen, läuft via Header-Directive:
X-Associated-Content: "/foo.css":1,"/bar.js":1,"/baz.js":1
(Prio 0 = Hoch, Prio 7 = Niedrig)
Was tun, wenn man gleichzeitig viele alte Clients bedienen muss?
# Disable concatenation for SPDY/HTTP 2.0 clients <ModPagespeedIf spdy> ModPagespeedDisableFilters combine_css,combine_javascript </ModPagespeedIf> # Shard assets for HTTP 1.x clients only <ModPagespeedIf !spdy> ModPagespeedShardDomain www.site.com s1.site.com,s2.site.com </ModPagespeedIf>