Hoe en waarom we Performance Insights hebben gebouwd

In Chrome 102 ziet u een nieuw experimenteel paneel, Performance Insights , in uw DevTools. In dit bericht bespreken we niet alleen waarom we aan een nieuw panel hebben gewerkt, maar ook de technische uitdagingen waarmee we te maken kregen en de beslissingen die we onderweg hebben genomen.

ALT_TEXT_HIER

Waarom nog een paneel bouwen?

(Als u het nog niet heeft gezien: we hebben een video geplaatst over waarom u het Performance Insights-paneel bouwt en hoe u hiermee bruikbare inzichten kunt krijgen over de prestaties van uw website.)

Het bestaande Prestatiepaneel is een geweldige hulpbron als u alle gegevens voor uw website op één plek wilt zien, maar we vonden dat dit een beetje overweldigend zou kunnen zijn. Als je geen performance-expert bent, is het moeilijk om precies te weten waar je op moet letten en welke delen van de opname relevant zijn.

Ga naar het Insights-paneel, waar u nog steeds een tijdlijn van uw trace kunt bekijken en de gegevens kunt inspecteren, maar ook een handige lijst kunt krijgen van wat DevTools beschouwt als de belangrijkste ‘inzichten’ die de moeite waard zijn om in te duiken. Insights identificeert problemen zoals verzoeken om weergaveblokkering, lay-outverschuivingen en lange taken om er maar een paar te noemen, die allemaal een negatieve invloed kunnen hebben op de laadprestaties van uw website en met name op de Core Web Vital (CWV) -scores van uw site. Naast het signaleren van problemen biedt Performance Insights u bruikbare suggesties om uw CWV-scores te verbeteren, en biedt het links naar verdere bronnen en documentatie.

Feedbacklink in het paneel

Dit panel is experimenteel en we willen jouw feedback! Laat het ons weten als u bugs tegenkomt of als u functieverzoeken heeft waarvan u denkt dat deze u kunnen helpen bij het werken aan de prestaties van uw site.

Hoe we prestatie-inzichten hebben opgebouwd

Net als de rest van DevTools hebben we Performance Insights in TypeScript gebouwd en webcomponenten , ondersteund door lit-html , gebruikt om de gebruikersinterface te bouwen. Waar Performance Insights verschilt, is dat de primaire UI-interface een HTML- canvas is en dat de tijdlijn op dit canvas wordt getekend. Een groot deel van de complexiteit komt voort uit het beheren van dit canvas: niet alleen het tekenen van de juiste details op de juiste plaats, maar ook het beheren van muisgebeurtenissen (bijvoorbeeld: waar heeft de gebruiker op het canvas geklikt? Heeft hij op een gebeurtenis geklikt die we hebben getekend? ) en ervoor te zorgen dat we het canvas effectief opnieuw weergeven.

Meerdere tracks op één canvas

Voor een bepaalde website zijn er meerdere ‘tracks’ die we willen weergeven, die elk een andere categorie gegevens vertegenwoordigen. Het Insights-paneel toont bijvoorbeeld standaard drie tracks:

En naarmate we functies op het paneel blijven plaatsen, verwachten we dat er meer nummers zullen worden toegevoegd.

Onze aanvankelijke gedachte was dat elk van deze sporen hun eigen <canvas> zou weergeven, zodat de hoofdweergave zou bestaan ​​uit meerdere verticaal gestapelde canvaselementen. Dit zou de weergave op trackniveau vereenvoudigen, omdat elke track afzonderlijk kan worden weergegeven en er geen gevaar bestaat dat een track buiten zijn grenzen wordt weergegeven. Helaas heeft deze aanpak twee belangrijke problemen:

canvas zijn duur om te (her) renderen; het hebben van meerdere doeken is duurder dan één doek, zelfs als dat doek groter is. Het renderen van overlays die over meerdere sporen gaan (bijvoorbeeld verticale lijnen om gebeurtenissen zoals FCP-tijd te markeren) wordt complex: we moeten op meerdere doeken renderen en ervoor zorgen dat ze allemaal samen worden weergegeven en goed uitgelijnd zijn.

Door één canvas voor de hele gebruikersinterface te gebruiken, moesten we uitzoeken hoe we ervoor konden zorgen dat elke track op de juiste coördinaten wordt weergegeven en niet overloopt in een andere track. Als een bepaalde track bijvoorbeeld 100 px hoog is, kunnen we niet toestaan ​​dat deze iets weergeeft dat 120 px hoog is en dit laat overvloeien in de track die eronder ligt. Om dit op te lossen kunnen we clip gebruiken. Voordat we elke track renderen, tekenen we een rechthoek die het zichtbare trackvenster voorstelt. Dit zorgt ervoor dat alle paden die buiten deze grenzen worden getekend, door het canvas worden afgesneden.

canvasContext.beginPath();
canvasContext.rect(
    trackVisibleWindow.x, trackVisibleWindow.y, trackVisibleWindow.width, trackVisibleWindow.height);
canvasContext.clip();

We wilden ook niet dat elke track zijn verticale positie hoefde te kennen: elke track zou zichzelf moeten weergeven alsof deze op (0, 0) zou worden weergegeven, en we hebben een component op een hoger niveau (die we TrackManager noemen) om de algehele weergave te beheren. spoorpositie. Dit kan gedaan worden met translate , dat het canvas vertaalt met een bepaalde (x, y) positie. Bijvoorbeeld:

canvasContext.translate(0, 10); // Translate by 10px in the y direction
canvasContext.rect(0, 0, 10, 10); // draw a rectangle at (0, 0) that’s 10px high and wide

Ondanks de rect code-instelling 0, 0 als positie, zal de toegepaste algehele vertaling ervoor zorgen dat de rechthoek wordt weergegeven op 0, 10 . Dit stelt ons in staat om op trackbasis te werken alsof we renderen op (0, 0), en onze trackmanager te laten vertalen terwijl hij elke track rendert om ervoor te zorgen dat elke track correct wordt weergegeven onder de vorige.

Canvassen buiten het scherm voor tracks en hoogtepunten

Het renderen van canvas is relatief duur en we willen ervoor zorgen dat het Insights-paneel soepel en responsief blijft terwijl u ermee werkt. Soms ontkom je er niet aan dat je het hele canvas opnieuw moet renderen: als je bijvoorbeeld het zoomniveau wijzigt, moeten we opnieuw beginnen en alles opnieuw renderen. Het opnieuw renderen van canvas is bijzonder duur omdat je niet zomaar een klein deel ervan opnieuw kunt renderen; je moet het hele canvas afvegen en opnieuw tekenen. Dit is anders dan bij het opnieuw renderen van DOM, waarbij tools het minimaal vereiste werk kunnen berekenen en niet alles kunnen verwijderen en opnieuw kunnen beginnen.

Eén gebied waarop we visuele problemen tegenkwamen, was de nadruk. Wanneer u de muisaanwijzer op statistieken in het venster plaatst, markeren we deze op de tijdlijn. Als u de muisaanwijzer op een inzicht voor een bepaalde gebeurtenis plaatst, tekenen we een blauwe rand rond die gebeurtenis.

Deze functie werd voor het eerst geïmplementeerd door een muisbeweging over een element te detecteren dat een markering activeert, en die markering vervolgens rechtstreeks op het hoofdcanvas te tekenen. Ons probleem komt wanneer we de markering moeten verwijderen: de enige optie is om alles opnieuw te tekenen! Het is onmogelijk om zomaar het gebied waar het hoogtepunt was opnieuw te tekenen (niet zonder enorme architectonische veranderingen), maar het hele canvas opnieuw tekenen alleen omdat we een blauwe rand rond één item willen verwijderen, voelde als overdreven. Het bleef ook visueel achter als u uw muis snel over verschillende items bewoog om snel achter elkaar meerdere hoogtepunten te activeren.

Om dit op te lossen hebben we onze gebruikersinterface opgesplitst in twee canvassen buiten het scherm : het 'hoofd'-canvas, waar tracks naartoe worden weergegeven, en het 'highlights'-canvas, waar hoogtepunten worden getekend. Vervolgens renderen we door deze canvassen te kopiëren naar het enkele canvas dat voor de gebruiker op het scherm zichtbaar is. We kunnen de methode drawImage gebruiken op een canvascontext, die een ander canvas als bron kan nemen.

Als u dit doet, betekent dit dat het verwijderen van een markering er niet voor zorgt dat het hoofdcanvas opnieuw wordt getekend: in plaats daarvan kunnen we het canvas op het scherm leegmaken en vervolgens het hoofdcanvas naar het zichtbare canvas kopiëren . Het kopiëren van een canvas is goedkoop, het is de tekening die duur is; Dus door hoogtepunten naar een apart canvas te verplaatsen, vermijden we die kosten bij het in- en uitschakelen van hoogtepunten.

Uitgebreid geteste trace-parsering

Een van de voordelen van het helemaal opnieuw bouwen van een nieuwe functie is dat u kunt reflecteren op de eerder gemaakte technische keuzes en verbeteringen kunt aanbrengen. Een van de dingen die we wilden verbeteren was het expliciet opsplitsen van onze code in twee, bijna volledig verschillende delen:

Parseer het traceringsbestand en haal de benodigde gegevens eruit. Geef een reeks sporen weer.

Door het parseren (deel 1) gescheiden te houden van het UI-werk (deel 2) konden we een solide parseersysteem bouwen; elke tracering wordt door een reeks Handlers geleid die verantwoordelijk zijn voor verschillende problemen: een LayoutShiftHandler berekent alle informatie die we nodig hebben voor Layout Shifts en een NetworkRequestsHandler pakt uitsluitend het ophalen van netwerkverzoeken aan. Het hebben van deze expliciete parseerstap, waarbij we verschillende handlers hebben die verantwoordelijk zijn voor verschillende delen van de trace, is ook nuttig geweest: het parseren van traces kan erg ingewikkeld worden, en het helpt om je op één zorg tegelijk te kunnen concentreren.

We hebben onze traceringsparsering ook uitgebreid kunnen testen door opnames te maken in DevTools, deze op te slaan en ze vervolgens in te laden als onderdeel van ons testpakket. Dit is geweldig omdat we kunnen testen met echte sporen en geen enorme hoeveelheden valse traceergegevens kunnen opbouwen die verouderd zouden kunnen raken.

Screenshot testen voor canvas-UI

Als we bij het onderwerp testen blijven, testen we meestal onze frontend-componenten door ze in de browser weer te geven en ervoor te zorgen dat ze zich gedragen zoals verwacht; we kunnen klikgebeurtenissen verzenden om updates te activeren en beweren dat de DOM die de componenten genereren correct is. Deze aanpak werkt goed voor ons, maar valt tegen als we overwegen om op canvas te renderen; Er is geen manier om een ​​canvas te inspecteren en te bepalen wat daar getekend is! Onze gebruikelijke benadering van weergeven en vervolgens bevragen is dus niet geschikt.

Om ons in staat te stellen enige testdekking te krijgen, zijn we overgegaan tot het testen van screenshots. Elke test activeert een canvas, geeft de track weer die we willen testen en maakt vervolgens een screenshot van het canvaselement. Deze schermafbeelding wordt vervolgens opgeslagen in onze codebase, en toekomstige testruns zullen de opgeslagen schermafbeelding vergelijken met de schermafbeelding die ze genereren. Als de screenshots verschillend zijn, mislukt de test. We bieden ook een vlag om de test uit te voeren en een screenshot-update af te dwingen wanneer we de weergave doelbewust hebben gewijzigd en de test moet worden bijgewerkt.

Screenshottests zijn niet perfect en een beetje bot; je kunt alleen testen of de hele component wordt weergegeven zoals verwacht, in plaats van meer specifieke beweringen, en aanvankelijk maakten we ons schuldig aan overmatig gebruik ervan om ervoor te zorgen dat elke afzonderlijke component (HTML of canvas) correct werd weergegeven. Dit vertraagde onze testsuite drastisch en leidde tot problemen waarbij kleine, bijna irrelevante aanpassingen aan de gebruikersinterface (zoals subtiele kleurveranderingen of het toevoegen van wat marge tussen items) ervoor zorgden dat meerdere schermafbeeldingen mislukten en moesten worden bijgewerkt. We hebben ons gebruik van schermafbeeldingen nu teruggeschroefd en gebruiken ze puur voor op canvas gebaseerde componenten, en deze balans heeft tot nu toe goed voor ons gewerkt.

Conclusie

Het bouwen van het nieuwe Performance Insights-panel was een zeer plezierige, leerzame ervaring voor het team. We hebben veel geleerd over traceerbestanden, werken met canvas en nog veel meer. We hopen dat u het nieuwe panel met veel plezier zult gebruiken en kunnen niet wachten om uw feedback te horen.

Zie Prestatie-inzichten: krijg bruikbare inzichten in de prestaties van uw website voor meer informatie over het paneel Prestatie-inzichten.

Download de voorbeeldkanalen

Overweeg om Chrome Canary , Dev of Beta te gebruiken als uw standaard ontwikkelingsbrowser. Met deze voorbeeldkanalen krijgt u toegang tot de nieuwste DevTools-functies, kunt u geavanceerde webplatform-API's testen en kunt u problemen op uw site opsporen voordat uw gebruikers dat doen!

Neem contact op met het Chrome DevTools-team

Gebruik de volgende opties om de nieuwe functies, updates of iets anders gerelateerd aan DevTools te bespreken.