Die Inhalte dieser Website wurden mithilfe künstlicher Intelligenz (KI) oder maschineller Übersetzungstechnologie übersetzt und können Fehler enthalten.

Skip to content

30-fache Verbesserung der Front-End-Speichernutzung beim Laden des Karussells

Im zweiten Quartal 2020 haben wir die „Erfahrungen“-Seite technisch überarbeitet, indem wir sie in React umgeschrieben und die REST-API integriert haben. Während der Umsetzung stießen wir jedoch auf ein interessantes Problem.

Auf der Seite „Erlebnisse“ gibt es etwa 20 Karussells mit jeweils mindestens 60 Kacheln. Die Seite rendert also über 1.200 Erlebnisse, einschließlich relevanter Informationen wie Titel, Nutzerbewertung, Anzahl der gleichzeitigen Nutzer und Miniaturansicht. In jedem Karussell löst ein Klick auf den rechten Scroll-Button eine Anfrage aus, um den nächsten Satz an Erlebnissen zu laden, sofern weitere vorhanden sind. Die neuen Daten, die aus dieser Anfrage resultieren, werden dann an das Karussell angehängt, was bedeutet, dass mehr Knoten zum DOM hinzugefügt werden und mehr Miniaturansichten im Browser gerendert werden. Der Speicherverbrauch im Browser steigt, wenn Nutzer scrollen, um weitere Daten anzufordern, woraufhin die Benutzererfahrung langsamer wird und Verzögerungen auftreten.

Speicherprofil

Wir können die Chrome-Entwicklertools verwenden, um dieses Problem zu profilieren. Der erste Snapshot wird beim ersten Laden der Seite aufgenommen, der zweite, nachdem der Benutzer 12 Mal auf den Weiter-Button in einem Karussell geklickt hat. Wir sehen einen Anstieg der Speicherauslastung um fast 9,7 MB aufgrund von über 100 String-Knoten und der verstärkten Darstellung von Miniaturansichten.

Lösung

Wenn das Karussell scrollt, sehen Nutzer nur die Elemente aus dem Karussellfenster. Beispielsweise sind auf einem Laptop mit einer Auflösung von 1920×1080 im Vollbildmodus des Browsers jeweils nur etwa 9 Elemente sichtbar. Daher ist es unnötig, alle unsichtbaren Knoten und Miniaturansichten zusammen zu rendern oder mehr Daten, die von der Anfrage zurückgegeben werden, in das DOM zu übertragen.

Hier ist also die Idee: Nachdem wir die Rohdaten aus der API-Anfrage zum ersten Mal abgerufen haben, erstellen wir ein Array gleicher Länge, um die Darstellung im DOM vorzubereiten. Innerhalb des Darstellungs-Arrays können wir nur so viele Daten einfügen, wie zum Füllen der Anzeige und zum Scrollen zum nächsten Element erforderlich sind. Der Rest des Arrays wird erst gefüllt, wenn das Anzeigefenster nahe daran gescrollt wird. Legen wir zwei Indizes fest, um den Bereich der Rendering-Daten zu erfassen: renderingStartIndex und renderingEndIndex. Wir richten einen Cursor ein, um anzugeben, welche Startposition in der Liste sichtbar ist. Beim Scrollen müssen wir den Cursor kontinuierlich auf den Index des ersten sichtbaren Elements aktualisieren. Bevor die Scroll-Animation beendet ist, müssen wir prüfen, ob sich der nächste Cursor innerhalb des Rendering-Daten-Arrays befindet. Anhand der Größe des Karussellfensters und der Kartengröße können wir leicht feststellen, wie viele sichtbare Elemente in das Anzeigefenster passen. Dann müssen wir sicherstellen, dass die Elemente aus dem aktuellen Fenster und dem nächsten Fenster innerhalb des Bereichs des Rendering-Daten-Arrays liegen. Ist dies nicht der Fall, holen wir Elemente aus den Rohdaten, um die leere Liste zu füllen, und löschen gleichzeitig die Daten vor der Cursorposition. Dies gilt, wenn Benutzer nach rechts oder links scrollen. Wenn Benutzer nach rechts scrollen, füllen wir die Rohdaten jedes Mal auf, nachdem wir neue Daten erhalten haben, indem wir im Hintergrund weitere Daten abrufen. Die Rohdaten werden jedoch nicht in die Seitenrendering einbezogen.

So sieht es nach der Verbesserung aus:

Speicherprofil

Werfen wir noch einmal einen Blick auf die Chrome-Entwicklertools. Wie zuvor wurde der erste Snapshot zum Zeitpunkt der Initialisierung aufgenommen und der zweite nach 12-maligem Scrollen nach rechts. Nun kostet das Laden von über 100 Elementen nur noch 0,3 MB zusätzlichen Speicher, im Gegensatz zu zuvor 9,7 MB.

Was kommt als Nächstes?

Neben der Verbesserung der Karussell-Komponente für die Verarbeitung großer Datenfenster müssen wir bei der Überarbeitung einer Funktion/Seite weitere Benchmarks hinzufügen, um die Leistungsdaten zu erfassen.

Während sich der moderne Webanwendungs-Stack zunehmend in Richtung Frontend verlagert, ist die Erfassung und Verbesserung der Frontend-Telemetrie ebenso wichtig wie die traditionelle Backend-Telemetrie.

Ying Jiang ist Principal Frontend Software Engineer bei Roblox. Als erste Frontend-Entwicklerin bei Roblox arbeitet sie daran, moderne Frontend-Technologien bei Roblox einzuführen und die Entwicklungs- und Bereitstellungspipeline zu verbessern. Außerdem hat sie an Echtzeitfunktionen wie Chat, Benachrichtigungsstream und Sprachfunktionen gearbeitet.

Weder die Roblox Corporation noch dieser Blog befürworten oder unterstützen bestimmte Unternehmen oder Dienste. Es werden keine Garantien oder Zusagen hinsichtlich der Genauigkeit, Zuverlässigkeit oder Vollständigkeit der in diesem Blog enthaltenen Informationen gegeben.