Web Performance – eine sehr kurze Einführung

Keine Kommentare

Wer sich schon einmal mit der Entwicklung von Webseiten beschäftigt hat, ist sicherlich auch über die performance-relevanten Entwicklertools seines Browsers gestolpert. Dort finden sich allerhand Zahlen und Werkzeuge, die irgendwie Anhaltspunkte über die Qualität einer Webseite, wie Performance und das daraus resultierende Nutzererlebnis, geben können.

Außerdem wissen wir alle, wie leidig es ist, schlecht funktionierende, träge Webseiten zu benutzen und dann entnervt zum Konkurrenzprodukt wechseln. Solche Erfahrungen sind schlecht für das Image eines Unternehmens und erzeugen ein Gefühl geringer Wertschätzung für die eigenen Kunden. Aber auch das Entwickeln einer Inhouse-Webapplikation, die schwerfällig und langsam ist, hat schnell unangenehme Folgen für Verantwortliche sowie Entwickler des Produkts. Sei es eine daraus resultierende schlechte Akzeptanz der IT-Abteilung oder des Projektes, oder gar dass Mitarbeiter aus Frust die Applikation im Unternehmen boykottieren.

Das Erstellen performanter Applikationen, die sich gut bedienen lassen und einen echten Mehrwert bringen, ist mir und meinen Kollegen bei codecentric und UX&I eine echte Herzensangelegenheit. Nicht zuletzt, weil wir den Frust und die zuvor genannten Probleme privat wie auch aus Kundenprojekten kennen und hier unseren Kunden und anderen Entwicklern helfen möchten, die Welt ein weniger einfacher zu machen. Deshalb soll dieser Artikel einen ersten, sehr kurzen Einstieg in das Thema Web Performance geben. Es werden unterschiedliche Zahlen und Metriken zum „Messen“ der Qualität einer Webseite und der daraus resultierenden Nutzererfahrung besprochen. Kurzum: Welche Zahlen gibt es, was ist ihre Bedeutung und wie können wir diese interpretieren?

Jeder der beschriebenen Themenbereiche bietet genügend Stoff für einen eigenen Blogartikel. Deshalb werden hier die – nach Meinung des Autors- zum Einstieg wichtigsten Teile angesprochen. Es ist also sinnvoll (und macht auch noch riesigen Spaß), sich eingehender mit Web Performance zu beschäftigen. Ich hoffe, dass viele Leser sich ebenso für das Thema begeistern können wie ich.

Von Ladephasen, Kategorien und Metriken

Der Prozess vom Laden bis zur Darstellung einer Webseite lässt sich in vier Phasen  aufteilen und kann als Karte fungieren, die darstellt, an welchem Punkt der Reise wir uns gerade befinden. Dies kann hilfreich sein, um für die jeweilige Phase die passenden Metriken zu finden und festzulegen, ob, was und wie aufwändig optimiert werden soll. Suchbegriff  Performance Budget.

Phase 1: Is it happening?

Phase 1 beschreibt den Moment, in dem erste Inhalte auf dem Bildschirm dargestellt werden. Sie gibt Auskunft darüber, ob (und wie gut) die Navigation auf die Webseite verläuft, der Server ausreichend schnell antwortet usw.

Phase 2: Is it useful?

Hier werden erste Seiteninhalte dargestellt. An dieser Stelle wollen wir darauf hin optimieren, dass unsere Nutzer möglichst schnell relevante Inhalte angezeigt bekommen, die für sie sinnvoll und wertig sind.

Phase 3: Is it usable?

In dieser Phase ist es möglich, (sinnvoll) mit der Seite zu interagieren und die erwartete Reaktion oder Antwort zu erhalten. Hier wollen wir schnelle Reaktionszeiten auf eine Nutzeraktion haben.

Phase 4: Is it delightful?

Ist eine Seite sauber, flüssig und ohne Verzögerungen Lag und Jank benutzbar? Fühlt sich unsere Anwendung gut an?

Vier Phasen - codecentric Blog

Vier Phasen und zugehörige Metriken

Metriken

Jeder Phase lassen sich verschiedene Metriken zuordnen. Die einzelnen Phasen werden größtenteils durch die sogenannten nutzerzentrischen Metriken ausgedrückt. Alle weiteren vorgestellten Metriken wirken sich jedoch ebenso auf die Gesamterfahrung aus. Die verschiedenen Metriken lassen sich wiederum in vier Kategorien einteilen und werden von unterschiedlichen Werkzeugen geliefert. Suchbegriffe: Render Tree, Layout, Paint, DOM Construction

Die Kategorien sind:

1. Meilensteinbasierte Metriken (Milestone timings)

Die Metriken, Ereignisse und Timings dieser Kategorie fokussieren die User Experience beim Laden einer Webseite. Sie sind also nutzerzentrische Metriken und geben beispielsweise Auskunft darüber, wieviel Zeit vergeht, bis ein erster (sinnvoller) Seiteninhalt dargestellt wird oder ab welchem Zeitpunkt eine ersten Nutzerinteraktion mit der Seite möglich ist. Die Werte können mit Hilfe von Browser-APIs oder den Entwicklerwerkzeugen des Browsers und weiteren Werkzeugen wie beispielsweise Google Lighthouse gemessen und eingesehen werden. Metriken aus dieser Kategorie — mit Annotation der zugehörigen Ladephase — sind:

Time To First Byte (TTFB) – Phase 1:

Time To First Byte ist der Zeitabstand zwischen dem Absenden einer Anfrage zum Laden/Anzeigen einer Webseite bis zum Eingang des ersten Bytes. Hierzu gehören alle notwendigen Schritte, wie beispielsweise DNS-Lookup, TCP- oder SSL-Handshake.

First Paint (FP) – Phase 1

First Paint bezeichnet den Zeitpunkt zwischen Navigation und des Zeichnens (Paint) der ersten beliebigen Pixel, die sich zu dem Inhalt des Bildschirms vor der Navigation unterscheiden. Da der Teil, der zuerst dargestellt wird vollkomen beliebig ist, wie zum Beispiel das Zeichnen einer Hintergrundfarbe, gibt FP keine Auskunft über die Benutzbarkeit.

First Contentful Paint (FCP) – Phase 1

First Contentful Paint ist der Zeitpunkt, zu dem der erste Inhalt dargestellt wird. Zum Besipiel Text, Bilder, SVG, Canvas Rendering usw. Ist das Darstellen des Inhalts beendet, so ist Phase 1 abgeschlossen. Die Darstellung von iframes ist hier nicht eingeschlossen! Diese Metrik fokussiert den ersten, verwertbaren, Inhalt einer Webseite. Ein  erster verwertbarer Inhalt ist irgendeinen Inhalt, der zwar irgendeinen Informationsgehalt hat, aber dabei nicht unbedingt für den Nutzer wichtig oder sinnvoll ist. Dennoch gibt FCP erste Anhaltspunkte zur User Experience.

First Meaningful Paint (FMP) – Phase 2

First Meaningful Paint bezeichnet die benötigte Zeit zum Darstellen des ersten primären (für die Zielgruppe sinnvollen) Inhalts einer Seite. FMP ist kein Wert, der sich standardisieren lässt, da es von Seite zu Seite verschieden ist, welche Inhalte Primärinhalte sind und welche nicht. Beim Laden des codecentric Blogs (siehe Bild oben) kann FMP beispielsweise der Zeitpunkt sein, wenn Titel und Teasertexte der sichtbaren Blogartikel angezeigt werden (Time-to-first-Blog). Bei einer Seite, die Nachrichten aggregiert, die Anzeige des ersten Feeds (Time-to-first-Feed).

Google Lighthouse und der Chrome Browser zeigen bereits einen Wert für FMP an, der natürlich nur eine Annahme darstellt, welche sich aber auf Erfahrungswerte (!) stützt. Bei Single-Page-Apps ist das oft das Anzeigen der Hero-Elemente. Werden andere Messpunkte benötigt, können verschiedene (!) Browser-APIs benutzt werden, wie beispielsweise im Artikel User Timing and Custom Metrics auf dem SpeedCurve Blog beschrieben.

DomContentLoaded (DCL) – Phase 2,3

Das DOMContentLoaded Event ist der Zeitpunkt, an dem das initiale HTML-Dokument vollständig geladen und geparsed ist. Jedoch ohne darauf zu warten, dass (alle) Stylesheets, Images, Subframes geladen sind. (Da der DOM-Content zu diesem Zeitpunkt konstruiert ist, ist dies ein sicherer Moment, um mit dem DOM zu interagieren). Siehe auch Notes on “How Browsers Work” – 3. Parsing: DOM Tree & CSSOM Tree.

Load (L) – Phase 2,3

Das load Event ist der Zeitpunkt, an dem die ganze Seite mit all den dazugehörigen Ressourcen,Stylesheets, Images, Subframes, Scripts usw. geladen ist.

Time to Interactive (TTI) – Phase 3

Time to Interactive ist der Zeitpunkt, ab dem eine Seite interaktiv ist. Das ist dann der Fall, wenn der letzte Long Task abgearbeitet ist, der Main Thread für fünf Sekunden im Idle-Zustand ist und für fünf Sekunden keine Netzwerkinteraktion stattgefunden hat. Außerdem bedeutet es, dass ein Großteil der Event Handler bereits registriert sind und die Seite innerhalb von 50ms auf eine Nutzerinteraktion antwortet. Siehe auch Google Developers – Time to Interactive.

Diese Metrik steht in Abhängigkeit zu dem verwendeten JavaScript. Liegt hier also ein hoher Wert vor, sollte der JavaScript-Code überprüft werden.

First Input Delay (FID) – Phase 3

First Input Delay ist der Zeitabstand von der ersten Nutzerinteraktion mit der Webseite bis zu dem Zeitpunkt, an dem der Browser in der Lage ist, die Interaktion entsprechend zu verarbeiten und zu „antworten“. Eine Nutzeraktion ist jede Interaktion mit der Seite, bei der auf eine, durch einen Nutzer initierte, Aktion eine Antwort erwartet wird, wie beispielsweise ein Button-Click usw. Kurz gesagt, beschreibt diese Metrik, wieviel Zeit eine Webseite benötigt, um auf eine Nutzerinteraktion zu antworten.

Im Gegensatz zur Metrik TTI, welche ohne Nutzer berechnet werden kann, benötigt es echte Nutzerinteraktionen, um ein FID zu berechnen. TTI und FID stehen nicht in direkter Abhängigkeit zueinander. Es ist möglich, dass die TTI einer Webseite hoch ist, aber die darauffolgenden FID-Werte gering sind. Andersherum kann die TTI einer Seite kurz sein, aber die darauffolgenden FID-Werte sind hoch. Hier gilt es herauszufinden, wie weit diese beiden Werte optimiert werden sollen. Daumenregel ist, sie sinnvoll gering —so gering wie nötig zu halten— beispielsweise geringer als die Konkurrenzseite etc.

Warum eigentlich so gering wie nötig und nicht so schnell wie möglich? Weil wir sonst in den Bereich der Microoptimierungen gelangen. Hier wird irgendwann der Zugewinn an Geschwindigkeit nicht mehr wahrgenommen, dafür kann aber der Entwicklungsaufwand sehr groß werden. Kosten/Nutzen stimmen dann einfach nicht mehr. Siehe auch Smashing Magazine – Why Perceived Performance Matters, Part 1: The Perception Of Time und tobias.is – Web Performance Budgets are more than mere thresholds

Long Tasks API – Phase 4

Mit dem Long Tasks API lassen sich Tasks finden, deren Ausführung den Main Thread länger als 50ms beschäftigen bzw. blockieren. Ein blockierter Main Thread hat zur Folge, dass die Seite schlecht bis überhaupt nicht auf Interaktionen des Nutzers reagiert. Dem 50ms-Fenster liegt das RAIL-Model zugrunde. Dort wird beschrieben, dass eine Seite in einem Zeitfenster von 100ms antworten soll, damit die Benutzung als gut und flüssig wahrgenommen wird (Is it delightful?). Um das Budget von 100ms einhalten zu können, sollten (Nutzer-)Events innerhalb von 50ms abgearbeitet werden, da noch weitere Aufgaben auf dem Main Thread erledigt werden müssen, um Nutzereingaben zu verarbeiten.

2. Speed Index

Der Speed Index ist eine Messgröße, die von dem Werkzeug WebPageTest errechnet wird. Er beschreibt die durchschnittliche Lade-Performance einer Webseite in Millisekunden. Also wie schnell dem Nutzer Seiteninhalte angezeigt werden. Je niedriger die Zahl desto besser. Außerdem berücksichtigt Speed Index nur unmittelbar sichtbare Inhalte (above the fold) und steht deshalb in Abhängigkeit zu der Viewport-Größe.

Der Speed-Index-Wert konzentriert sich auf das, was ein Nutzer sehen kann und nicht auf die Performance des Browsers. Somit ist er eine ideale Messgröße, um Vergleiche zwischen Webseiten, verschiedenen Viewports oder die Auswirkung der Implementierung eines Features etc. anzustellen. Da die Messung mit sehr geringem Aufwand möglich ist, sollte der Speed Index schon frühzeitig in die Qualitätssicherung mit aufgenommen werden.

3. Quantitative Metriken (Quantity based metrics)

Quantitative Metriken beschreiben die Browser Experience einer Webseite. Sie werden durch das Gewicht einer Webseite (Page Weight), die Anzahl gesendeter HTTP-Requests usw. ausgedrückt. Weitere Beispiele sind: die Größe des ausgelieferten JavaScripts inklusive des verwendeten Frameworks und 3rd-Party Scripts, wie beispielsweise Analytics, die Anzahl oder Gesamtgröße der ausgelieferten Bilder usw.

Was haben diese Werte denn mit der User Experience zu tun? Ich will schließlich meine Nutzer glücklich machen und nicht deren Browser!

Ja es ist richtig: Diese Werte sagen nicht viel über die Nutzererfahrung selbst aus. Jedoch bieten sie einen guten Startpunkt während der Konzeptionsphase und helfen dabei, viele der gängigen Fehlerquellen aufzudecken.
Wer hat nicht schon erlebt, dass Webseiten hohe Ladezeiten haben, weil zu viele oder zu große Bilder, welche im schlimmsten Falle noch nicht einmal für das Web optimiert wurden, verwendet werden? Gerade auf einem mobilen Endgerät macht sich das in hohen Ladezeiten und schnell verbrauchtem Datenvolumen bemerkbar. Oder was ist, wenn wie vorher schon erwähnt, die Zeit bis eine erste Interaktion mit der Seite möglich ist, zu hoch ist? Oder wir lange warten müssen, bis eine erste Interaktion mit der Seite möglich ist? – Wir werden entnervt zum Konkurrenzprodukt wechseln.

Ganz besonders die Größe des verwendeten JavaScripts spielt in diesem Falle eine große Rolle. Der Browser muss das Script herunterladen, parsen, kompilieren und schlussendlich verarbeiten können. Nutzer mit der neuesten Hardware (wie es bei uns Entwicklern der Fall ist) werden das Problem ggf. weniger zu spüren bekommen. Nutzer mit einem Low-End Smartphone werden evtl. eine sehr schlechte Erfahrung haben oder gar ganz ausgeschlossen werden.

Deshalb sollten wir unseren JavaScript Payload stets kritisch hinterfragen. Benötigen wir wirklich alle Bibliotheken, die wir eingebunden haben? Hilft uns Redux wirklich weiter? Benötigen wir überhaupt ein (SPA) Framework/Bibliothek (wie Angular oder React), oder ist eine statische Seite passender? Im Zweifelsfall steht das Nutzererlebnis immer im Vordergrund. Gehen unsere Kunden zur Konkurrenz, verdienen wir kein Geld und selbst die tollsten Technologien bringen uns dann auch nicht mehr weiter.

Wir sehen also, dass diese Werte doch etwas mit der Nutzerfahrung und Verwendbarkeit einer Webseite zu tun haben. Deshalb sollte gleich zu Beginn eine Obergrenze festgelegt werden und diese nur nach reifer Überlegung nach oben korrigiert werden. Quantitative Metriken sind einfach zu verstehen, zu messen und zu überwachen und sollten deshalb schon zu Beginn des Projektes implementiert werden.

4. Regelbasierte Metriken (Rule based metrics)

Dies sind errechnete Werte ( Scores), welche durch Drittanbieter-Werkzeuge erzeugt werden. Diese Werkzeuge sind beispielsweise Google Lighthouse, WebPageTest oder YSlow.

Die durch diese Werkzeuge generierten Werte treffen ebenfalls nur bedingt Aussagen über die User Experience einer Webseite. Sie geben aber eine Übersicht über das Einhalten der gängigen Best Practices. Sie lassen sich sehr gut in den Build-Prozess einbauen und dienen so als zusätzliche Sicherheit in Bezug auf die allgemeine Umsetzungsqualität einer Webseite.


Performance Panel in Google Chrome

Performance Panel in den Chrome Developer Tools

Lighthouse im Audits Tab in Google Chrome

Google-Lighthouse-Integration im Audits-Panel in den Chrome Developer Tools

 

Fazit

Wir haben über die Probleme, die durch eine schlechte Performance einer Webseite entstehen, gesprochen und haben die vier Phasen des Ladens einer Webseite kennengelernt. Diese sollen uns dabei helfen, die verschiedenen Metriken, Werte und Pain Points im Ladeprozess zuzuordnen und stets zu wissen, für was gerade optimiert werden soll. Die vier Phasen werden durch die folgenden Fragen ausgedrückt: Is it happening? Is it useful? Is it usable? Is it delightful?. Weiterhin haben wir die Metriken in Kategorien eingeteilt und besprochen, wodurch wir nun in der Lage sind, diese zu verstehen und zu interpretieren. Es ist uns nun möglich, sinnvolle Entscheidungen zur Optimierung unserer Webseite zu treffen und unseren Code diesbezüglich kritisch zu hinterfragen.

Wie könnte es weitergehen?
Sind wir in der Situation, dass wir optimieren wollen oder müssen, bietet es sich an, sich als nächstes, neben den technischen Aspekten, mit konzeptionellen Themen wie Performance Budgets zu beschäftigen.

Marco Schäfer

Ist stets darauf aus, Neues zu entdecken und zu lernen. Große Begeisterung für Software-Entwicklung und -Architektur besonders in den Bereichen Web- & Cloud Technologien, Frontend-Entwicklung und JavaScript. Mag sein MacBook und das Ausprobieren neuer Tools. Ausdauersportler und Hundebesitzer. Liebt ausgedehnte Waldspaziergänge mit seinem Hund.

Kommentieren

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.