Wie vermeidet man Layout-Verschiebungen (Layout Shifts), wenn Trichter-Grafiken asynchron mit Daten befüllt werden?
Layout-Verschiebungen (Cumulative Layout Shift, kurz CLS) entstehen, wenn der Browser den Platzbedarf eines Elements erst erkennt, nachdem die Daten geladen wurden. Bei Trichter-Grafiken (Funnel Charts) ist dies besonders kritisch, da sie oft großflächig sind.
Hier sind die besten Strategien, um Layout-Shifts bei asynchronen Trichter-Grafiken zu vermeiden:
1. Platz reservieren (Container Sizing)
Die wichtigste Regel: Der Browser muss bereits beim Laden des HTML-Gerüsts wissen, wie viel Platz die Grafik einnehmen wird, bevor die Daten eintreffen.
- Feste Höhe/Breite: Wenn die Grafik eine bekannte Größe hat, gib dem Container-Element im CSS eine feste Höhe (z. B.
height: 400px;). - Aspect Ratio (Seitenverhältnis): Nutze die moderne CSS-Eigenschaft
aspect-ratio, damit der Container bei responsiven Designs proportional mitwächst, aber seinen Platz beibehält..funnel-container { width: 100%; aspect-ratio: 16 / 9; /* Reserviert den Platz im richtigen Verhältnis */ background-color: #f0f0f0; /* Optional: Dezenter Hintergrund */ }
2. Skeleton Screens (Platzhalter)
Statt eines leeren weißen Raums oder eines Lade-Spinners, der das Layout beim Verschwinden zusammenstaucht, solltest du einen Skeleton Screen verwenden.
- Zeige eine graue, vereinfachte Silhouette eines Trichters an.
- Dies signalisiert dem Nutzer: „Hier kommt gleich eine Grafik“.
- Sobald die Daten geladen sind, wird die Grafik über den Skeleton gelegt oder dieser ersetzt (ohne die äußeren Maße des Containers zu verändern).
3. Min-Height definieren
Falls die Grafik je nach Datenmenge unterschiedlich hoch sein kann, definiere zumindest eine min-height. So verhinderst du, dass der Content unter der Grafik beim Start des Ladevorgangs ganz oben klebt und dann massiv nach unten springt.
.chart-wrapper {
min-height: 300px;
display: flex;
align-items: center;
justify-content: center;
}
4. Umgang mit "No Data" oder Fehlern
Ein häufiger Layout-Shift passiert, wenn der API-Call fehlschlägt oder keine Daten liefert und der reservierte Container plötzlich auf 0px Höhe zusammenfällt.
- Lösung: Behalte die Dimensionen des Containers bei, auch wenn eine Fehlermeldung oder ein "Keine Daten verfügbar"-Text angezeigt wird.
5. Schrifthelleigkeit und Canvas-Rendering
Trichter-Grafiken werden oft in <canvas> oder <svg> gerendert. Wenn die Grafik Bibliotheken wie D3.js, Chart.js oder Highcharts verwendet:
- Initialisierung: Initialisiere das Chart-Objekt sofort, auch wenn noch keine Daten da sind (mit leeren Arrays). Die Bibliothek zeichnet dann oft schon die Achsen oder einen leeren Rahmen, was den Platz fixiert.
- Webfont-Loading: Wenn die Grafik spezielle Schriftarten nutzt, sorge dafür, dass diese mit
font-display: swapgeladen werden oder vorab geladen (preload) werden, damit sich die Textbreiten innerhalb der Grafik nicht nachträglich ändern.
6. Progressive Loading (für komplexe Trichter)
Wenn der Trichter aus vielen Sektionen besteht, die nacheinander berechnet werden:
- Berechne das Layout clientseitig erst, wenn alle notwendigen Daten für die Geometrie vorhanden sind.
- Vermeide es, den Trichter "wachsen" zu lassen (zuerst Stufe 1, dann Stufe 2), da dies den restlichen Text auf der Seite ständig nach unten schiebt.
Zusammenfassung der Best Practices:
- CSS:
aspect-ratiooderheightauf dem Wrapper setzen. - HTML: Den Chart-Container im Markup hart codieren, nicht erst per JavaScript einfügen.
- UX: Skeleton Screens verwenden, um die visuelle Last zu mindern.
- Fallback: Auch im Fehlerfall die Container-Größe beibehalten.
Ein Beispiel für den Aufbau:
<div class="chart-section">
<h2>Konversions-Trichter</h2>
<!-- Dieser Container behält immer die gleiche Größe -->
<div id="funnel-placeholder" style="width: 100%; aspect-ratio: 2/1; background: #fafafa;">
<!-- Hier wird die Grafik asynchron hineingerendert -->
</div>
<p>Weitere Details unter der Grafik...</p>
</div>