Kennen Sie das? Sie wollen eine Webseite auf dem Smartphone öffnen, und nachdem Sie sich gefragt haben, ob Ihre Internetverbindung vielleicht einen Hänger hat, tut sich nach gefühlten Minuten endlich etwas auf dem Bildschirm.
Um das im eigenen Portal zu vermeiden, sollte man sich regelmäßig mit dem Thema Performance-Optimierung auseinandersetzen.
Im Sommer 2021 führte Google die Nutzerfreundlichkeit von Seiten als Teil der Ranking-Systeme bei der mobilen Suche ein. Die Performance der Website ist dabei eine der wichtigsten Kennzahlen. Es geht hier um die generelle Ladegeschwindigkeit einer Webseite bis man als Besucher etwas von dem Inhalt der Webseite sehen kann. Vor allem mobile ist die Geschwindigkeit in der Bewertung einer Webseite sehr wichtig und hat auch Auswirkungen auf die Positionierung in den Google Suchergebnissen.
Ein praktisches Werkzeug um die Performance einer Webseite einfach im Browser zu testen, ist z.B. Lighthouse im Chrome-Browser. Lighthouse ist nicht nur ein sehr nützliches Tool, um die Webseite während der Gestaltungsphase immer wieder zu überprüfen. Es ist auch sehr hilfreich dabei, im laufenden Betrieb immer wieder zu kontrollieren, ob sich im Laufe der Zeit Performance-Probleme aufgetan haben, die man lösen sollte.
Google Lighthouse analysiert die Bereiche PWA, Performance, Accessibility, Best Practices und SEO. Uns interessieren hier aber vor allem die Werte im Bereich "Performance".
Dabei werden 6 Unterkategorien betrachtet. Diese Kennzahlen messen u.a. die Ladezeit, die Reaktionsgeschwindigkeit und die Stabilität der Darstellung von Webseiten beim Laden.
Interessant sind hier vor allem die unter dem Punkt "Diagnose" mit einem roten Warndreieck gekennzeichneten Punkte. Diese sollte man versuchen zu optimieren, wenn man seine Performance-Werte verbessern will.
Die Lighthouse-Tests sollen direkt vor bzw. nach einer Optimierung der Webseite ausgeführt werden. Pro Änderung ist ein eigener Test erforderlich und dies ist auf dem lokalen PC am einfachsten durchzuführen.
Mehr Informationen zu den Performancewerten in Lighthouse
Will man die Entwicklung der Performance über einen längeren Zeitraum beobachten, dann ist eine Lighthouse-Diagnose im Browser nicht zielführend, da diese immer nur eine Momentaufnahme zeigt. Die Ermittlung der Messwerte für den Seitenaufbau sollte auf einem Server im Rechenzentrum regelmäßig erfolgen, damit die Optimierungen der Portale über einen längeren Zeitraum geprüft und überwacht werden können. Damit werden auch Verschlechterungen der Portaleinrichtung rückwirkend erkannt und können leichter behoben werden.
Wir haben zur regelmäßigen Messung einen eigenen Server mit Lighthouse aufgesetzt. Pro Portal werden je die Startseite und eine Artikelseite im Abstand von 15 Minuten abgerufen, so dass Sie nach der Optimierung nach spätestens 15 Minuten das Ergebnis abrufen und prüfen können.
Will man diese Werte verbessern und die Performance der Webseite optimieren, ist es wichtig wenigstens grob zu verstehen, wie ein Browser funktioniert, um beurteilen zu können, wo und warum Performance-Engpässe auftreten.
Dazu müssen wir wissen, was der Critical Rendering Path (der Ladeweg, den der Browser durchlaufen muss, um den sichtbaren Bereich darzustellen) ist, wie er mit dem DOM (Document Object Model) und dem CSSOM (CSS Object Model) arbeitet und was es mit dem Render Tree, Layout und Paint auf sich hat.
Gibt ein Nutzer eine URL im Browser ein, wird eine Anfrage an den Server geschickt und daraufhin empfängt der Browser die Datei der Seite. Diese besteht aus Text. Um diesen Text nun in das DOM zu konvertieren, sind folgende Schritte notwendig:
Diesen Vorgang bezeichnet man als "Parsing".
Während der Browser das DOM unserer kleinen Seite erstellt hat, hat er einen Link-Tag im Head des Dokuments gefunden, der ein externes Stylesheet referenziert. Da der Browser "weiss", dass der diese Datein brauchen wird, um die Seite zu rendern, sendet er sofort eine Anfrage nach dieser Datei an den Server.
Wie schon beim HTML, müssen die erhaltenen CSS-Regeln jetzt in etwas umgewandelt werden, das der Browser verstehen kann. Daher werden die CSS Bytes nun in Zeichen, dann in Token und Objekte umgewandelt, die dann wieder in einer Baumstruktur, dem "CSS Object Model" (CSSOM), miteinander verbunden werden.
Wichtig: Die Generierung des CSSOM blockiert das Rendering der Seite - aus gutem Grund. Würde der Browser einfach die Seite weiter rendern und in Pixel umwandeln ohne auf das CSSOM zu warten, sähe der Nutzer zunächst eine sehr hässlich ungestylte Webseite, während das CSS geparsed wird. Später würde dann alles auf der Seite noch einmal herumspringen, sobald das CSS angewandt wird. Diesen Effekt kann man manchmal beobachten, wenn auf einer Webseite eine CSS-Datei blockiert ist.
Damit der Besucher der Webseite auch etwas sehen kann, muss der Browser das Layout jedes sichtbaren Elements auf der Webseite berechnen und es auf dem Bildschirm "zeichnen".
Hierfür benutzt der Browser den sogenannten "Render Tree". Bevor dieser nicht erstellt ist, wird nichts auf dem Bildschirm angezeigt. Deshalb brauchen wir auch sowohl das DOM wie auch das CSSOM.
Aus diesen beiden wird der Render-Tree erstellt. Er enthält nur die Elementen, die später auf dem Bildschirm sichtbar sind. Elemente die z.B. ein "display: none" haben, sind daher im Render Tree nicht vorhanden.
Fast geschafft. Nachdem wir unseren Render-Tree gebaut haben, kann der Browser endlich damit beginnen, die einzelnen Elemente auf den Bildschirm zu zeichnen.
Zunächst berechnet der Browser, wie groß jedes Objekt auf der Seite sein wird und wo auf der Seite es dargestellt wird. Diesen Prozess nennt man "Layout".
Nachdem wir nun die grobe Geometrie der Seite haben, müssen wir aber noch berücksichtigen, dass sich Objekte auch überlappen können. Hierfür kreiert der Browser "Layer" (Ebenen), ähnlich wie Layer z.B. in Photoshop. In jedem dieser Layer versieht der Browser nun die einzelnen Pixel die auf dem Bildschirm erscheinen sollen mit den sichtbaren Eigenschaften der Elemente, also Rahmen, Hintergrundfarben, Schatten, Texte. etc. Dieser Prozess nennt sich "Rasterization". Den gesamten Prozess nennt man "Paint".
Nun haben wir zwar schon einmal unsere verschiedenen Layer (Ebenen), die in einer bestimmten Reihenfolge auf dem Bildschirm gezeichnet werden sollen, aber immer noch keinen einzigen sichtbaren Pixel auf unserem Bildschirm. Erst müssen diese Layer an die CPU unseres Computers geschickt werden. Diesen Schritt nennt man "Compositing".
Und wir haben es endlich geschafft, unsere Webseite erscheint auf dem Bildschirm.
Wollen wir im Detail prüfen, wieviel Zeit beim Rendern unserer Webseite jeweils für Skripting, Rendering, Paint usw. benötigt wird, empfiehlt sich der Tab Performance/Leistung (je nach Sprache) im Chrome-Developertool.
Der einfachste Weg ein solches Leistungsprofil zu erstellen ist, auf das Reload-Icon im Tab zu klicken. So starten wir in diesem Tab eine Aufzeichnung und erhalten dann das Ergebnis der Analyse, sobald die CPU und die Netzwerkaktivitäten auf der Seite beendet sind.
So ein Leistungsprofil im Chrome wirkt leider auf den ersten Blick recht kompliziert, weil hier eine Unmenge von Daten bereitgestellt wird. Aber es lohnt sich, sich einmal ein wenig mit dieser Funktion zu beschäftigen, da man so die verschiedenen Aktivitäten auf der Seite mit den eventuell auftretenden Performanceproblemen in Zusammenhang bringen kann. Einige interessante Informationsquellen sind:
Die Möglichkeit der Datenauswertung im Leistungstab der Developer Tools ist aber natürlich noch viel umfangreicher. Wer sich einmal ganz tief in die Materie eingraben will, dem sei die ausführliche Dokumentation bei Google selbst empfohlen.
Aus der Art und Weise, wie der Browser aus einer HTML-Datei eine Webseite auf den Bildschirm "zaubert", ergeben sich einige Best-Practice-Tipps, auf die man nach unserer Erfahrung für einen schnellen Seitenaufbau, vor allem im kritischen Bereich "above the fold" achten sollte. Zwar können wir nicht alle Faktoren beeinflussen, die sich auf die Geschwindigkeit auswirken, wie z.B. die Internetgeschwindigkeit des Besuchers oder lokal bedingte Netzwerküberlastungen, aber wir können Probleme identifizieren und erhalten so einen Überblick, welche Faktoren genau die Verbindungsgeschwindigkeit reduzieren.
Die Ressourcen zu beseitigen, die das Rendering blockieren, ist ein wichtiger Punkt für den schnellen Seitenaufbau.
Der Browser parsed das HTML immer von oben nach unten. Sobald er auf eine extern eingebundene Datei trifft, sei dies ein Skript, eine CSS-Datei, ein Bild oder ein anderes Element das nicht im HTML eingebettet ist, beginnt der Browser damit, diese Datei im Hintergrund downzuloaden.
Hierbei gibt es allerdings Ausnahmen, Ressourcen die das Parsing und/oder Rendering der Seite blockieren.
Anders als Javascript, welches das Parsing der Seite blockieren kann, blockiert CSS "nur" das Rendern. Aber wie wir ja schon gesehen haben, beginnt der Browser nicht mit dem Rendern der Seite, bevor das CSSOM erstellt ist. Viele eingebundene oder sehr große CSS-Dateien können somit durchaus dazu führen, dass die Seite vor allem im sichtbaren Bereich, den wir so schnell wie möglich darstellen wollen, zu langsam aufbaut.
Die CSS-Anweisungen für den sichtbare Bereich, auf unserem Bild hier "Above the Fold", sollten also so schnell wie möglich verfügbar sein, während die CSS-Anweisungen für den Bereich "Below the Fold", also den Bereich den der User zunächst einmal nicht auf dem Bildschirm sieht, ohne zu Scrollen, können nachgelagert verarbeitet werden.
Eine Methode, um den sichtbaren Bereich so schnell wie möglich darzustellen, ist der der Einsatz des "Critical CSS", dem Auslagern kritischer CSS-Stylings, die direkt am Seitenanfang benötigt werden.
Je nach Auflösung des Bildschirms und auch des Browserfensters, ist der sichtbare Teil natürlich immer etwas anders. Bei Smartphones ist dieser Ausschnitt meist kleiner. Ebenfalls ändert sich dieser sichtbare Seitenbereich oftmal beim Drehen des Smartphones. Zum sichtbaren Teil gehören aber in der Regel Elemente wie Header und Logo, die obere primäre Navigation, die Layout-Struktur, Navigationen über dem Content, die Überschrift H1.
Im fCMS erfolgt die Aufteilung des CSS in das kritische und unkritische CSS automatisch über das Tool "Critical" auf dem Server:
Das fCMS unterstützt das mit dem Modul Stylesheet-Optimierung.
Um auch hier eine Optimierung der Ladegeschwindigkeiten zu erzielen, wird die Datei im Browser bis zur nächsten Änderung des CSS gecached.
Mittels der sogenannten Ressourcenhinweise können Entwickler Browser dazu auffordern, vorab mit dem Laden einer Ressource zu beginnen, die in naher Zukunft benötigt wird. Das gibt Webentwicklern mehr Kontrolle darüber, in welcher Reihenfolge eine Webseite und die verschiedenen Ressourcen darauf geladen werden. Dadurch kann der Page Speed optimiert und infolgedessen auch die User Experience einer Seite verbessert werden.
Ein interessanter Punkt ist “Preconnect”. Dazu muss man wissen, dass der Browser eine Ressource nicht einfach herunterladen kann. Zuvor muss der Browser einen DNS-Lookup durchführen und die sichere TLS-Verbindung aushandeln. Das braucht Zeit. Für die wichtigsten Ressourcen kann man diese Schritte im voraus durchführen, indem man link rel = “preconnect” verwendet. Allerdings wird Preconnect nicht von allen Browsern unterstützt so z.B. von Firefox.
Prefetching bezeichnet das Laden einer Ressource, bevor der Nutzer diese anfordert. Webentwickler können damit angeben, welche Ressourcen mit hoher Wahrscheinlichkeit als nächstes benötigt werden. Diese werden dann vorab geladen und im Cache des Browsers gespeichert, was zur Optimierung des Page Speeds und der User Experience beitragen kann.
Prefetching konzentriert sich auf Ressourcen, die in naher Zukunft – zum Beispiel auf der nächsten Seite – benötigt werden. Bei richtiger Anwendung kann Prefetching die User Experience auf einer Website verbessern, jedoch verbraucht es auch Rechenleistung und sollte daher sparsam eingesetzt werden, da sonst der gegenteilige Effekt auftreten kann. Denn während Prefetching die Ladegeschwindigkeit der nächsten Seite beschleunigen kann, könnte es den Ladevorgang der aktuellen Seite tatsächlich verlangsamen.
Prefetching kann Webentwicklern also dabei helfen, die Seitenleistung zu optimieren, jedoch erfordert es auch Ressourcen. Verschwendete Prefetch-Anfragen erhöhen folglich die Ladezeit für die aktuelle Seite. Zu den Ressourcen, die Prefetching beansprucht, gehören:
Preload hingegen wird für Ressourcen auf der aktuellen Seite verwendet, wobei diese Ressourcen gegenüber anderen bevorzugt werden. Vom Browser werden Preload-Ressourcen demnach gegenüber Prefetch-Ressourcen priorisiert behandelt.
Preloading kann also die Ladezeit von Webseiten verbessern. Für gewöhnlich wird Preloading für kritische Ressourcen verwendet, welche die Ladegeschwindigkeit einer Seite verlangsamen, wenn sie später als andere Ressourcen gefunden werden.
Gängige Ressourcen für Preloading sind
Allerdings ist auch beim Preloading Vorsicht geboten, da bei übermäßiger oder falscher Anwendung der gegenteilige Effekt eintreten kann und sich die Performance der Website verschlechtert.
Häufige Fehler beim Preloading sind
Um die Verlangsamung des Seitenaufbaus durch unnötige Preloads zu vermeiden, sollten Sie jeden Preload einzeln ergänzen und schrittweise in Lighthouse testen.
Das gilt für alle Optimierungen, die Sie im Portal vornehmen.
Beim Aufruf einer Webseite lädt der Browser alle benötigten Ressourcen, um diese Seite wie gewünscht darzustellen. Dabei werden alle Objekte aufgerufen, auch wenn diese nicht im sichtbaren Bereich, sondern „below the fold“ liegen. Das kostet unter anderem auch unnötige Ladezeit.
Bilder, die nicht im Viewport – im sichtbaren Bereich der Website – liegen, müssen nicht geladen werden. Sowohl der Request als auch die Datenmenge können initial eingespart werden. Erst, wenn sie durch Scrollen in den Viewport kommen, müssen sie nachgeladen werden. Auch das fCMS unterstützt natürlich Lazyloading.
Das hört sich natürlich gut an, aber wie immer gibt es auch hier etwas zu beachten, da ein übereifriger Einsatz die Performancewerte der Seite sogar negativ beeinflussen kann.
Speziell geht es hier um den Wert "LCP" im Lighthouse Score. Wir erinnern uns an den Beginn unseres Vortrags, hier hatten wir erläutert, dass der Largest Contentful Paint beschreibt, wann das größte Element gezeichnet wurde. Das deutet an wann der wichtigste Content auf der Seite angezeigt wird. Wie unsere Erfahrung mit Performancetests gezeigt hat, können sich hier bereits Verzögerungen im Millisekundenbereich beim Laden der Bilder im sichtbaren Bereich negativ auf den LCP-Wert auswirken.
Es sollte daher darauf geachtet werden, dass alle Bilder im sichtbaren Bereich für die Desktop und die mobile Ansicht der Seiten vom Lazyloading ausgenommen werden. Dies ist im fCMS ebenfalls problemlos möglich, indem man den betroffenen Image-Tags im Template ganz einfach die Anweisung "nolazy" mitgibt.
Beispiel im Template im fCMS Content-Management-System: {:bildelement|imgtag('hero-detail', 'nolazy'):}
Bilder sollten in einem web-optimierten Format, etwa WebP oder AVIF, ausgespielt werden. Diese neueren Formate bieten den Vorteil einer wesentlich stärkeren Komprimierung bei geringerem Qualitätsverlust. Das fCMS bietet diese Möglichkeits bereits und generiert standardmäßig zusätzlich zu den Bildurls auf .jpg und .png auch Bildurls auf .webp. Die .jpg/.png-Tags dienen als Fallback, falls der Browser das .webp-Format nicht unterstützt.
Bei der Einbindung von externem Content, Widgets und Elementen ist das unserer Erfahrung nach ein häufiger Fehler, hier werden Bilder oft nur im jpeg-Format ausgegeben. Sie sollten in Ihrem Portal also darauf achten, dass auch diese die Bilder im webp-Format ausgespielt werden.
Bilder sollten möglichst genau in der Größe ausgespielt werden, in der sie auch angezeigt werden. Gerade auf mobilen Geräten können zu große Bilder den Seitenaufbau bremsen. Es sollten daher immer die passenden Bildskalierungen im fCMS für die verschiedenen Viewportbreiten des Portals eingerichtet werden.
Auch dies ist bei externen Applikationen leider ein typischer Fehler. Hier haben die Bilder meist eine Einheitsgröße und werden lediglich per CSS auf 100% herunterskaliert.
Nicht immer hat man es allerdings selbst in der Hand, Performance-Engpässe zu beheben. Dies wird besonders deutlich am Fall der Einbindung externer Cookie-Consent-Tools, wie z.B. Usercentrics.
Seit der Einführung der DSGVO muss grundsätzlich bei jeder Datenerhebung von Nutzern ein Einverständnis erfolgen und eine Webseite, die Daten von ihren Nutzern tracken möchte, steht ohne rechtlich sicheres Cookie Consent schon mit einem Bein in der Abmahnfalle.
Wenn Sie Ihre User über Google Analytics tracken oder ein Youtube Video einbinden, geht es daher heute nicht mehr um die reine technische Machbarkeit oder die vermeintlich beste funktionelle Lösung, das gesamte Feature muss auch nach Urheberrecht, Wettbewerbsrecht und Datenschutzrecht auf sicheren Füßen stehen. Daher ist es schwer, in der heutigen Zeit ganz auf solche Tools zu verzichten.
Allerdings steht hinter dem Usercentrics-Feature steht eine große JavaScript-Bibliothek, diebei jedem neuen Aufruf der Webseite mit geladen wird. Da die Bibliothek von Usercentrics geladen wird und nicht lokal auf dem eigenen Webserver vorhanden ist, sorgt dies für längere Ladezeiten.
So meldet auch Lighthouse regelmäßig, dass die in Portalen für das Consent-Tool von usercentrics eingebundenen Dateien bundle.js, uc-block.bundle.js das Rendering der Seite erheblich blockieren.
Nach unserer Erfahrung schafft es allerdings keine umfassende Cookie-Consent-Lösung bislang, die Performance nicht negativ zu beeinflussen. Die Auswirkungen sind mitunter erheblich und führen dazu, dass die Website nach Aktivierung einer Cookie-Consent-Lösung schlechter von Google geranked werden kann. Bisweilen dauert allein die Ausführung des uc-block.bundle.js und bundle.js Funktionen gut 2,5 Sekunden. Darüber hinaus sind die Cache-Richtlinien (1 Stunde) aller Scripts von Usercentrics nicht optimiert, was von Lighthouse ebenfalls bemängelt wird.
Nichts vermag die Performance-Werte allerdings so effektiv zu beinträchtigen, wie die Einbindung von externer Werbung im Portal. Die Performance-Werte vor und nach der Aktivierung der Werbung in den Portalen weichen regelmäßig ganz erheblich ab. Je nachdem, welche Werbung gerade aktiv ist, kann es mitunter auch zu extremen Ladezeiten bis hin zu Hängern auf der Seite kommen.
Spannenderweise gilt dies natürlich auch für über Google Ads/Doubleclick eingebundene Anzeigen. Hier kommt noch ein besonderes Schmankerl dazu: jede einzelne über Doubleclick eingebundene Webseite lädt die Javascript-Dateien 'amp4ads-v0.js' (54 KB) und 'amp-analytics-01.js' (40 KB). Und das auch wenn die Seite überhaupt keine AMP-Seite ist. Man könnte sagen, dies ist zumindest ein sehr suboptimales Vorgehen seitens Google, zumal man hier als Webseitenbetreiber keinerlei Möglichkeiten hat, einzugreifen.
Wie man auf unserem Screenshot der Lighthouse-Analyse eines Artikels auf einem Kundenportal sieht, beinträchtigt die Einbindung der Werbung die Gesamtleistung ganz erheblich. Es haben sich sowohl Time to Interactive wie auch Speed Index und Blocking Time signifikant verschlechert. Für jedes andere Feature im Portal wäre das eigentlich inakzeptabel.
Leider geht es in der Regel nicht ganz ohne Werbung auf einem Portal und natürlich ist es praktisch und bequem, die Auslieferung der Werbung Drittanbietern zu überlassen. Allerdings sollte regelmäßig geprüft werden, wie stark die Werbeeinbindung die Leistung des Portals beeinträchtig. Eventuell kann man schrittweise doch zumindest einige Werbeflächen lokal selbst vermarkten und somit nicht nur die Seitengeschwindigkeit verbessern sondern auch den lokalen Bezug des Portals stärken.
Natürlich ist es verführerisch, dem Leser gleich alle tollen Inhalte, die das Portal zu bieten hat, auf einen Blick präsentieren zu wollen. Allerdings tut man seinem Leser damit nicht immer unbedingt einen Gefallen, vor allem wenn sich die vielen Features negativ auf die Geschwindigkeit der Seite auswirken.
Unserer Erfahrung nach sind das die schlimmsten, vermeidbaren Performance-Killer:
Der Performance-Killer Nummer 1 ist und bleibt aber nach wie vor die Einbindung von externem Javascript. Sehr oft begegnen uns bei Performance-Tests Drittapplikationen, die über Javascript fröhlich weiter Skripte, CSS-Dateien, Fonts und ähnliches nachladen, oft sogar mehrfach. Lighthouse bemängelt bei jedem unserer Test, dass Code von Drittanbietern das Rendering der Seite blockiert. Das gibt Abzug bei den Performance-Punkten... von der schlechten Nutzererfahrung ganz abgesehen.
Ebenfalls bemängelt wird der Einsatz von "document.write" bei externen Skripten, die Bereitstellung von veraltetem Javascript in modernen Browsern oder die fehlenden Cache-Zeiten der Dateien.
Es sollte also bei jeglicher Einbindung von externen Skripten sehr gut überlegt werden, ob die Vorteile des Einsatzes die zahlreichen Nachteile wirklich überwiegen.
Auf dem Screenshot einer Performance-Analyse einer mit externen Dateien überladenen Artikeldetailansicht sehen Sie den massiven Unterschied zwischen den Werten mit und ohne von extern eingebundenem Javascript. Bitte beachten Sie insbesondere die Time to interaktiv und den Largest Contentful Paint, also die Zeit, bis beim Leser nach dem Klick auf einen Link der Inhalt der Seite sichtbar wird.
Bei der Einbindung der Widgets und Lösungen Dritter können Sie als Kunde Anreize schaffen und Druck ausüben, dass Ihnen performante Lösungen zur Verfügung gestellt werden. Auch entscheiden Sie über den Umfang des Seiteninhalts und den Umfang der Widgets und externer Lösungen.
Wir empfehlen Ihnen, diesen Vorteil beim nächsten Relaunch oder Facelift Ihres Portals zu nutzen und auch schon heute grundsätzlich jede extern eingebundene Datei auf den Prüfstand zu stellen.