De content op deze site is vertaald met behulp van kunstmatige intelligentie (AI) of machinevertalingstechnologie en kan fouten bevatten.

Skip to content

Het geheugengebruik van de front-end bij het laden van de carrousel met een factor 30 verbeteren

In het tweede kwartaal van 2020 hebben we de ervaringenpagina technisch herzien, waarbij we deze herschreven naar React en gebruik maakten van de REST API. Maar tijdens de implementatie stuitten we op een interessant probleem.

Er staan ongeveer 20 carrousels op de pagina met ervaringen, elk met minstens 60 tegels. De pagina geeft dus meer dan 1.200 ervaringen weer, inclusief relevante informatie zoals de titel, gebruikersbeoordeling, gelijktijdige gebruikers en miniatuurafbeelding. In elke carrousel wordt er, als je op de scrollknop aan de rechterkant klikt, een verzoek verzonden om de volgende batch ervaringen te laden als er nog meer zijn. Vervolgens worden de nieuwe gegevens die uit het verzoek voortkomen toegevoegd aan de carrousel, wat betekent dat er meer knooppunten aan de DOM worden toegevoegd en er meer miniatuurafbeeldingen in de browser worden weergegeven. Het geheugengebruik in de browser neemt toe naarmate gebruikers scrollen om meer gegevens op te vragen, waarna de gebruikerservaring vertraagt en er vertraging optreedt.

Geheugenprofiel

We kunnen de Chrome Developer Tools gebruiken om dit probleem te profileren. De eerste snapshot wordt genomen wanneer de pagina voor het eerst wordt geladen, en de tweede wordt genomen nadat de gebruiker 12 keer op de volgende scroll in één carrousel heeft geklikt. We zien een toename van bijna 9,7 MB in geheugengebruik door meer dan 100 string-knooppunten en het renderen van meer thumbnails.

Oplossing

Wanneer de carrousel scrolt, zien gebruikers alleen de items uit het carrouselvenster. Bijvoorbeeld, op een laptop met een resolutie van 1920×1080, in de browser op volledig scherm, zullen er telkens slechts ~9 zichtbare items zijn. Daarom is het niet nodig om alle onzichtbare knooppunten en miniaturen samen weer te geven of om meer gegevens die door het verzoek worden geretourneerd naar de DOM over te brengen.

Dit is dus het idee: nadat we de ruwe gegevens voor de eerste keer hebben opgehaald via het API-verzoek, bouwen we een array van dezelfde lengte op ter voorbereiding op het weergeven in de DOM. Binnen de weergave-array kunnen we alleen voldoende gegevens invullen om het scherm te vullen en door te scrollen naar het volgende. De rest van de array wordt pas gevuld wanneer het weergavevenster er dichtbij is gescrolld. Laten we twee indexen toekennen om het bereik van de weergavegegevens vast te leggen: renderingStartIndex en renderingEndIndex. We stellen een cursor in om aan te geven welke startpositie in de lijst zichtbaar is. Tijdens het scrollen moeten we de cursor voortdurend bijwerken naar de index van het eerste zichtbare item. Voordat de scrollanimatie is voltooid, moeten we controleren of de volgende cursor zich binnen de weergavegegevensarray bevindt. Afhankelijk van de grootte van het carrouselvenster en de kaartgrootte kunnen we gemakkelijk bepalen hoeveel zichtbare items in het weergavevenster passen. Vervolgens moeten we ervoor zorgen dat de items uit het huidige venster en het volgende venster binnen het bereik van de array met weergavegegevens vallen. Zo niet, dan halen we items uit de ruwe gegevens om de lege lijst te vullen, terwijl we tegelijkertijd de gegevens vóór de cursorpositie wissen. Dit geldt wanneer gebruikers naar rechts of links scrollen. Wanneer gebruikers naar rechts scrollen, vullen we de ruwe gegevens telkens aan nadat we nieuwe gegevens hebben ontvangen, door op de achtergrond meer gegevens op te halen. De ruwe gegevens worden echter niet gebruikt bij het weergeven van de pagina.

Zo ziet het eruit na de verbetering:

Geheugenprofiel

Laten we nog eens naar de Chrome Developer Tools kijken. Net als eerder is de eerste snapshot genomen op het moment van initialisatie en de tweede nadat er 12 keer naar rechts is gescrolld. Het laden van meer dan 100 items kost nu slechts 0,3 MB extra geheugen, in tegenstelling tot 9,7 MB eerder.

Wat nu?

Naast het verbeteren van de carrouselcomponent om grote gegevensvensters te verwerken, moeten we bij het herstructureren van een functie/pagina meer benchmarks toevoegen om de prestatiegegevens vast te leggen.

Hoewel de moderne webapplicatiestack steeds meer naar de front-end verschuift, is het vastleggen en verbeteren van de front-end-telemetrie net zo belangrijk als traditionele back-end-telemetrie.

Ying Jiang is Principal Frontend Software Engineer bij Roblox. Als eerste Frontend Engineer bij Roblox werkt ze aan de introductie van moderne frontend-technologiestacks bij Roblox en aan het verbeteren van de ontwikkelings- en implementatiepijplijn. Ze heeft ook gewerkt aan realtimefuncties zoals chat, meldingen en spraak.

Roblox Corporation noch deze blog onderschrijft of ondersteunt enig bedrijf of enige dienst. Ook worden er geen garanties of beloften gegeven met betrekking tot de nauwkeurigheid, betrouwbaarheid of volledigheid van de informatie in deze blog.