Gedanken zu HTTP/2 und Bündelung

Avatar of Jeremy Wagner
Jeremy Wagner am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

HTTP/2 war eines meiner Interessengebiete. Tatsächlich habe ich allein im letzten Jahr einige Artikel dazu geschrieben. In einem dieser Artikel habe ich diese ungeprüfte Behauptung aufgestellt:

Wenn der Benutzer HTTP/2 verwendet: Sie werden mehr und kleinere Assets ausliefern. Sie werden Dinge wie Image Sprites, eingebettetes CSS und Skripte sowie zusammengefügte Stylesheets und Skripte vermeiden.

Ich war nicht der Einzige, der das sagte, obwohl, fairerweise muss man sagen, Rachel qualifiziert ihre Aussage in ihrem Artikel mit Vorbehalten. Um fair zu sein, ist es theoretisch keine schlechte Beratung. Die Multiplexing-Fähigkeit von HTTP/2 gibt uns Spielraum, auf die Bündelung zu verzichten, ohne die negativen Auswirkungen von Head-of-Line Blocking zu erleiden (etwas, das wir in HTTP/1-Umgebungen schmerzlich gut kennen). Das Entwirren einiger dieser HTTP/1-spezifischen Optimierungen kann auch die Entwicklung erleichtern. In einer Zeit, in der die Webentwicklung komplizierter erscheint als je zuvor, wer würde nicht ein bisschen mehr Einfachheit schätzen?

Wie bei allem, was theoretisch einfach erscheint, kann die Umsetzung in der Praxis eine unübersichtliche Angelegenheit sein. Im Laufe der Zeit habe ich großartiges Feedback von nachdenklichen Lesern zu diesem Thema erhalten, das mich dazu veranlasst hat, meine ungeprüften Behauptungen darüber, welche Praktiken für HTTP/2-Umgebungen am sinnvollsten sind, zu überdenken.

Das Argument gegen Bündelung

Die Debatte über das Entbündeln von Assets für HTTP/2 dreht sich hauptsächlich um Caching. Die Prämisse ist, dass die Caching-Effizienz für wiederkehrende Benutzer mit vorgefüllten Caches besser ist, wenn Sie mehr (und kleinere) Assets anstelle eines riesigen Bundles ausliefern. Das leuchtet ein. Wenn sich ein kleines Asset ändert und der Cache-Eintrag dafür ungültig wird, wird es beim nächsten Besuch erneut heruntergeladen. Wenn sich jedoch nur ein winziger Teil eines Bundles ändert, muss das gesamte riesige Bundle erneut heruntergeladen werden. Nicht gerade optimal.

Warum Entbündelung suboptimal sein könnte

Es gibt Fälle, in denen das Entwirren von Bundles Sinn ergibt. Zum Beispiel fördert Code Splitting kleinere und zahlreichere Assets, die nur für bestimmte Teile einer Website/App geladen werden. Das macht absolut Sinn. Anstatt das gesamte JS-Bundle Ihrer Website im Voraus zu laden, zerlegen Sie es in kleinere Teile, die Sie bei Bedarf laden. Dies hält die Payloads einzelner Seiten gering. Es minimiert auch die Parsing-Zeit. Das ist gut, denn exzessives Parsen kann zu einer ruckeligen und unangenehmen Erfahrung führen, wenn eine Seite gerendert und interaktiv wird, aber noch nicht vollständig geladen wurde.

Aber es gibt einen Nachteil, den wir manchmal übersehen, wenn wir Assets zu fein aufteilen: Kompressionsverhältnisse. Im Allgemeinen komprimieren kleinere Assets nicht so gut wie größere. Tatsächlich vermeiden einige Serverkonfigurationen die Komprimierung, wenn einige Assets zu klein sind, da keine praktischen Gewinne erzielt werden können. Sehen wir uns an, wie gut einige beliebte JavaScript-Bibliotheken komprimieren

Dateiname Unkomprimierte Größe Gzip (Verhältnis %) Brotli (Verhältnis %)
jquery-ui-1.12.1.min.js 247,72 KB 66,47 KB (26,83%) 55,8 KB (22,53%)
angular-1.6.4.min.js 163,21 KB 57,13 KB (35%) 49,99 KB (30,63%)
react-0.14.3.min.js 118,44 KB 30,62 KB (25,85%) 25,1 KB (21,19%
jquery-3.2.1.min.js 84,63 KB 29,49 KB (34,85%) 26,63 KB (31,45%)
vue-2.3.3.min.js 77,16 KB 28,18 KB (36,52%)
zepto-1.2.0.min.js 25,77 KB 9,57 KB (37,14%)
preact-8.1.0.min.js 7,92 KB 3,31 KB (41,79%) 3,01 KB (38,01%)
rlite-2.0.1.min.js 1,07 KB 0,59 KB (55,14%) 0,5 KB (46,73%)

Sicher, diese Vergleichstabelle ist übertrieben, aber sie verdeutlicht einen wichtigen Punkt: Große Dateien liefern in der Regel höhere Kompressionsverhältnisse als kleinere. Wenn Sie ein großes Bundle in winzige Stücke aufteilen, erhalten Sie nicht so viel Vorteil durch Komprimierung.

Natürlich ist mehr als die Asset-Größe für die Leistung wichtig. Im Fall von JavaScript möchten wir möglicherweise kleinere, seiten-/templatesspezifische Dateien bevorzugen, da die anfängliche Ladezeit einer bestimmten Seite im Hinblick auf Dateigröße und Parsing-Zeit optimiert wird. Selbst *wenn* diese kleineren Assets nicht individuell komprimiert werden. Persönlich wäre das meine Neigung, wenn ich eine App bauen würde. Bei traditionellen, synchronen "Site"-ähnlichen Erlebnissen neige ich nicht so dazu, Code-Splitting zu verfolgen.

Es gibt jedoch noch mehr zu bedenken als nur JavaScript. Nehmen wir zum Beispiel SVG-Sprites. Wo diese Assets betroffen sind, scheint Bündelung sinnvoller zu sein. Insbesondere für große Sprite-Sets. Ich habe einen grundlegenden Test mit einem *sehr* großen Icon-Set mit 223 Icons durchgeführt. In einem Test habe ich eine gespritet Version des Icon-Sets geliefert. Im anderen habe ich jedes Icon als einzelne Assets geliefert. Im Test mit dem SVG-Sprite macht die Gesamtgröße des Icon-Sets nur knapp 10 KB komprimierte Daten aus. Im Test mit den ungebündelten Assets betrug die Gesamtgröße desselben Icon-Sets *115 KB* komprimierte Daten. Selbst mit Multiplexing gibt es einfach *keine Möglichkeit*, 115 KB bei einer gegebenen Verbindung schneller zu übertragen als 10 KB. Die Komprimierung reicht bei den individualisierten Icons nicht aus, um den Unterschied auszugleichen. *Technischer Hinweis: Die SVG-Bilder wurden in beiden Tests von SVGO optimiert.*

Seitenbemerkung: Ein aufmerksamer Kommentator hat darauf hingewiesen, dass die Firefox-Entwicklertools zeigen, dass im unspriteten Test etwa 38 KB Daten übertragen wurden. Das könnte beeinflussen, wie Sie optimieren. Nur etwas zum Nachdenken.

Browser, die HTTP/2 nicht unterstützen

Ja, das gibt es. Insbesondere Opera Mini scheint hier ein Nachzügler zu sein, und je nach Ihren Benutzern ist dies möglicherweise kein zu ignorierendes Benutzerssegment. Während weltweit etwa 80 % der Menschen mit Browsern surfen, die HTTP/2 unterstützen, sinkt diese Zahl in einigen Ecken der Welt. Allein in Indien nutzen laut caniuse weniger als 50 % der Nutzer einen Browser, der mit HTTP/2-Servern kommunizieren kann. Dies ist zumindest derzeit das Bild, und die Unterstützung ist auf dem Vormarsch, aber wir sind noch weit von einer allumfassenden Unterstützung des Protokolls in Browsern entfernt.

Was passiert, wenn ein Benutzer mit einem Browser, der es nicht unterstützt, mit einem HTTP/2-Server spricht? Der Server greift auf HTTP/1 zurück. Das bedeutet, Sie sind wieder bei den alten Paradigmen der Leistungsoptimierung. Also, wieder: *Machen Sie Ihre Hausaufgaben*. Überprüfen Sie Ihre Analysen und sehen Sie, woher Ihre Benutzer kommen. Besser noch, nutzen Sie die Fähigkeit von caniuse.com, Ihre Analysen zu analysieren und zu sehen, was Ihre Zielgruppe unterstützt.

Der Realitätscheck

Würde irgendein vernünftiger Entwickler sein Frontend so gestalten, dass 223 separate SVG-Bilder geladen werden? Ich hoffe nicht, aber nichts überrascht mich wirklich mehr. In allen, außer den komplexesten und funktionsreichsten Anwendungen, werden Sie Schwierigkeiten haben, so viel Ikonografie zu finden. Aber es könnte für Sie sinnvoller sein, diese Icons in einem Sprite zusammenzufassen und es im Voraus zu laden und die Vorteile einer schnelleren Darstellung bei nachfolgenden Seitenwechseln zu nutzen.

Was mich zur unausweichlichen Schlussfolgerung führt: In den Nischen und Ecken der Web-Performance-Disziplin gibt es keine einfachen Antworten, außer "recherchieren Sie". Verlassen Sie sich auf Analysen, um zu entscheiden, ob Bündelung für Ihre HTTP/2-betriebene Website eine gute Idee ist. Haben Sie viele Benutzer, die nur zu ein oder zwei Seiten gehen und dann gehen? Verschwenden Sie vielleicht keine Zeit mit dem Bündeln von Dingen. Navigieren Ihre Benutzer tief auf Ihrer Website und verbringen dort viel Zeit? Vielleicht bündeln.

Eines ist mir klar: Wenn Sie Ihre für HTTP/1 optimierte Website auf einen HTTP/2-Host verschieben und nichts an Ihrer clientseitigen Architektur ändern, wird das keine große Sache sein. Vertrauen Sie also keinen pauschalen Aussagen von Webentwicklern, die Blogbeiträge schreiben (d. h. mir). Finden Sie heraus, wie *Ihre* Benutzer sich verhalten, welche Optimierungen für *Ihre* Situation am besten geeignet sind und passen Sie *Ihren* Code entsprechend an. Viel Erfolg!


Cover of Web Performance in Action

Jeremy Wagner ist der Autor von Web Performance in Action, einem bald erscheinenden Titel von Manning Publications. Verwenden Sie den Gutscheincode sswagner, um 42 % zu sparen.

Schauen Sie ihn sich auf Twitter an: @malchata