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.
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.
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.
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.
Kommentare (6)
Maik Wagner ¶
18. Januar 2011, 16:42 Uhr
Ja Hallo!
Nicht, daß ich mit dem Nerdkram gerade was anfangen kann, aber schön, Dich in einer anderen Welt wiederzufinden. Welcome to the pleasuredome ;)
Rodney Rehm ¶
18. Januar 2011, 17:03 Uhr
Zitat Maik Wagner:
Tach auch!
Du findest mich doch jederzeit im #selfhtml IRC-Channel - und bekommst mich einmal im Jahr in natura zu Gesicht. Mehr willst du von mir auch gar nicht sehen ;)
Grüße nach E.
Schepp ¶
18. Januar 2011, 23:17 Uhr
Schöner Artikel. Viele wichtige Erkenntnisse bekommen. Danke dafür!
Nur schade dass Du die Browser nicht einmal mit der dicken Webworker-Haubitze dazu kriegen konntest, über ihr (allgemeines) HTTP-Connection-Limit zu springen.
Nehmen wir in Zukunft halt Websockets und jagen da alle Ressourcen en bloc durch! :D
Rodney Rehm ¶
19. Januar 2011, 00:09 Uhr
Naja, Firefox 4 wird ja nun erst mal ohne WebSockets kommen. Bis die Sicherheitsbedenken ausgeräumt wurden, sehe ich den vollflächigen Einsatz von WebSockets leider noch nicht so ganz. Wurmt mich ehrlich gesagt etwas. Hätte durchaus Anwendung dafür. Momentan muss ich die ganzen Nicht-HTTP-Protokolle durch Actionscript (Flash gedöns) schieben. Würgh.
Nachdem ich meinen Artikel hier nochmal gelesen habe, stellen sich mir aber gleich noch ein paar weitere Fragen… Wie beispielsweise verhält sich der Browser wenn 2 Tabs die selbe Seite abrufen in punkto Connection per Hostname?
Oder auch die Frage ob man den Worker dazu missbrauchen kann eine Menge von 10 Bildern, die vom Server in eine Ressource zusammengeführt wurden (Sprite, DataUri, MultiPart, …) zu laden, aufzutrennen und dann so in den Browser Cache bringen, um die Elemente beim Einsatz direkt zur Verfügung zu haben. Und wenn es möglich ist, was es bringt…
Peter: Mir fällt gerade auf, dass das erste Bild nicht stimmt. Eigentlich müsste es das hier sein: http://rodneyrehm.de/b/xmlhttprequest-and-worker/images/firefox-waterfall-regular.png
Peter ¶
19. Januar 2011, 08:14 Uhr
Korrigiert!
misiri ¶
30. Januar 2012, 08:31 Uhr
Vielen Dank für die erweiterten Erkenntnisse, sitze derzeit in einem AJAX/XML-Kurs und weiss somit nun auch um die derzeitigen Limits... ;)