In Chrome 102 zul je een nieuw experimenteel paneel, Performance Insights , in je DevTools zien. In dit bericht bespreken we niet alleen waarom we aan een nieuw paneel hebben gewerkt, maar ook de technische uitdagingen waarmee we te maken kregen en de beslissingen die we gaandeweg hebben genomen.
Waarom nog een paneel bouwen?
(Als u het nog niet gezien hebt, hebben we een video geplaatst over het waarom van het bouwen van het Performance Insights-paneel en hoe u hiermee bruikbare inzichten in de prestaties van uw website kunt krijgen.)
Het bestaande Performance Panel is een geweldige bron als je alle gegevens van je website op één plek wilt zien, maar we vonden dat het wat overweldigend kon zijn. Als je geen performance-expert bent, is het lastig 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 krijgt met wat DevTools beschouwt als de belangrijkste 'Insights' die de moeite waard zijn om te onderzoeken. Insights identificeert problemen zoals render blocking requests, layout shifts en lange taken, om er maar een paar te noemen. Deze kunnen allemaal een negatieve invloed 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 ook bruikbare suggesties om uw CWV-scores te verbeteren en links naar verdere bronnen en documentatie.
Dit paneel is experimenteel en we stellen uw feedback op prijs! Laat het ons weten als u bugs tegenkomt of functieverzoeken heeft waarvan u denkt dat ze u kunnen helpen bij het verbeteren van de prestaties van uw site.
Hoe we Performance Insights hebben gebouwd
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. Performance Insights onderscheidt zich doordat de primaire gebruikersinterface een HTML- canvas
is en de tijdlijn op dit canvas wordt getekend. Een groot deel van de complexiteit komt voort uit het beheer 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 wij hebben getekend?) en ervoor zorgen dat we het canvas effectief opnieuw renderen.
Meerdere sporen op één canvas
Voor een bepaalde website zijn er meerdere 'tracks' die we willen weergeven, elk met een andere categorie gegevens. Zo toont het Insights-paneel standaard drie tracks:
En naarmate we meer features aan het panel toevoegen, verwachten we dat er meer tracks worden toegevoegd.
Ons eerste idee was om elk van deze tracks een eigen <canvas>
te laten renderen, zodat de hoofdweergave zou bestaan uit meerdere canvaselementen die verticaal gestapeld zijn. Dit zou het renderen op trackniveau vereenvoudigen, omdat elke track afzonderlijk gerenderd kan worden en er geen gevaar bestaat dat een track buiten zijn grenzen rendert. Helaas brengt deze aanpak twee grote problemen met zich mee:
canvas
-elementen zijn duur om te (her)renderen; meerdere canvassen zijn duurder dan één canvas, zelfs als dat canvas groter is. Het renderen van overlays die over meerdere sporen lopen (bijvoorbeeld verticale lijnen om gebeurtenissen zoals FCP-tijd te markeren) wordt complex: we moeten op meerdere canvassen renderen en ervoor zorgen dat ze allemaal samen worden gerenderd en correct zijn uitgelijnd.
Omdat we één canvas
voor de hele gebruikersinterface gebruikten, moesten we uitzoeken hoe we ervoor konden zorgen dat elk spoor op de juiste coördinaten wordt gerenderd en niet overloopt in een ander spoor. Als een bepaald spoor bijvoorbeeld 100 pixels hoog is, kunnen we niet toestaan dat het een spoor van 120 pixels hoog rendert en dat het overloopt in het spoor eronder. Om dit op te lossen, kunnen we clip
gebruiken. Voordat we elk spoor renderen, tekenen we een rechthoek die het zichtbare spoorvenster weergeeft. Dit zorgt ervoor dat paden die buiten deze grenzen worden getekend, door het canvas worden bijgesneden.
canvasContext.beginPath();
canvasContext.rect(
trackVisibleWindow.x, trackVisibleWindow.y, trackVisibleWindow.width, trackVisibleWindow.height);
canvasContext.clip();
We wilden ook niet dat elk spoor zijn verticale positie hoefde te kennen: elk spoor zou zichzelf moeten renderen alsof het op (0, 0) wordt gerenderd, en we hebben een component op een hoger niveau (die we TrackManager
noemen) om de algehele spoorpositie te beheren. Dit kan worden gedaan met translate
, dat het canvas met een gegeven (x, y) positie verplaatst. 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 die 0, 0
als positie instelt, zorgt de toegepaste algehele translatie ervoor dat de rechthoek wordt gerenderd 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 tijdens het renderen van elke track om ervoor te zorgen dat elke track correct onder de vorige wordt gerenderd.
Off-screen canvassen voor tracks en highlights
Het renderen van een canvas is relatief duur en we willen ervoor zorgen dat het Insights-paneel soepel en responsief blijft terwijl u ermee werkt. Soms ontkomt u er niet aan om het hele canvas opnieuw te renderen: als u bijvoorbeeld het zoomniveau wijzigt, moeten we opnieuw beginnen en alles opnieuw renderen. Het opnieuw renderen van een canvas is bijzonder duur omdat u niet zomaar een klein deel ervan opnieuw kunt renderen; u moet het hele canvas wissen en opnieuw tekenen. Dit in tegenstelling tot DOM-rendering, waarbij tools het minimale benodigde werk kunnen berekenen in plaats van alles te verwijderen en opnieuw te beginnen.
Eén aspect waar we visuele problemen tegenkwamen, was de markering. Wanneer je met de muis over statistieken in het venster beweegt, markeren we ze op de tijdlijn. En als je met de muis over een inzicht voor een bepaalde gebeurtenis beweegt, tekenen we een blauwe rand om 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 direct op het hoofdcanvas te tekenen. Ons probleem doet zich voor wanneer we de markering moeten verwijderen: de enige optie is om alles opnieuw te tekenen! Het is onmogelijk om alleen het gebied waar de markering stond opnieuw te tekenen (niet zonder enorme architectonische aanpassingen), maar het hele canvas opnieuw tekenen alleen omdat we een blauwe rand rond één item willen verwijderen, voelde als overdreven. Het beeld liep ook achter als je de muis snel over verschillende items bewoog om meerdere markeringen snel achter elkaar te activeren.
Om dit te verhelpen, splitsen we onze gebruikersinterface op in twee off-screen canvassen: het "hoofdcanvas", waar de sporen naartoe renderen, en het "highlights"-canvas, waar de highlights worden getekend. Vervolgens renderen we door deze canvassen te kopiëren naar het canvas dat voor de gebruiker zichtbaar is op het scherm. We kunnen de drawImage
methode gebruiken in een canvascontext, die een ander canvas als bron kan gebruiken.
Dit betekent dat het verwijderen van een markering er niet toe leidt dat het hoofdcanvas opnieuw wordt getekend: in plaats daarvan kunnen we het canvas op het scherm wissen en het hoofdcanvas vervolgens naar het zichtbare canvas kopiëren . Het kopiëren van een canvas is goedkoop, maar de tekening zelf is duur; door markeringen naar een apart canvas te verplaatsen, vermijden we die kosten bij het in- en uitschakelen van markeringen.
Uitgebreid geteste sporenanalyse
Een van de voordelen van het helemaal opnieuw bouwen van een nieuwe feature is dat je kunt reflecteren op de technische keuzes die eerder zijn gemaakt en verbeteringen kunt aanbrengen. Een van de dingen die we wilden verbeteren, was het expliciet opsplitsen van onze code in twee, bijna volledig afzonderlijke delen:
Parseer het tracebestand en haal de benodigde gegevens eruit. Render een set tracks.
Door het parsen (deel 1) gescheiden te houden van het UI-werk (deel 2), konden we een solide parsingsysteem bouwen; elke trace wordt door een reeks handlers geleid die verantwoordelijk zijn voor verschillende aandachtspunten: een LayoutShiftHandler
berekent alle informatie die we nodig hebben voor Layout Shifts en een NetworkRequestsHandler
pakt uitsluitend het ophalen van netwerkaanvragen aan. Deze expliciete parsingstap, waarbij verschillende handlers verantwoordelijk zijn voor verschillende delen van de trace, is ook nuttig gebleken: het parsen van traces kan erg ingewikkeld worden en het helpt om je op één aandachtspunt tegelijk te kunnen concentreren.
We hebben onze trace-parsing ook uitgebreid kunnen testen door opnames te maken in DevTools, deze op te slaan en vervolgens te laden als onderdeel van onze testsuite. Dit is geweldig, omdat we met echte traces kunnen testen en geen enorme hoeveelheden nep-tracegegevens hoeven op te bouwen die mogelijk verouderd raken.
Screenshottesten voor canvas-gebruikersinterface
Om bij het onderwerp testen te blijven: we testen onze frontendcomponenten meestal door ze in de browser te renderen en te controleren of ze zich naar behoren gedragen. We kunnen klikgebeurtenissen versturen om updates te activeren en bevestigen dat de DOM die de componenten genereren correct is. Deze aanpak werkt goed voor ons, maar schiet tekort bij het bekijken van een canvas; er is geen manier om een canvas te inspecteren en te bepalen wat er getekend is! Onze gebruikelijke aanpak, waarbij we eerst renderen en dan query's uitvoeren, is dus niet geschikt.
Om een testdekking te krijgen, zijn we overgegaan op screenshottesten. Elke test start een canvas, rendert de track die we willen testen en maakt vervolgens een screenshot van het canvaselement. Deze screenshot wordt vervolgens opgeslagen in onze codebase en toekomstige tests vergelijken de opgeslagen screenshot met de screenshot die ze genereren. Als de screenshots verschillen, mislukt de test. We bieden ook een vlag om de test uit te voeren en een screenshotupdate te forceren wanneer we de rendering opzettelijk 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 specifiekere beweringen. Aanvankelijk maakten we ons schuldig aan overmatig gebruik ervan om ervoor te zorgen dat elk afzonderlijk 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 screenshots mislukten en moesten worden bijgewerkt. We hebben ons gebruik van screenshots nu teruggeschroefd en gebruiken ze puur voor canvascomponenten, en deze balans heeft tot nu toe goed voor ons uitgepakt.
Conclusie
Het bouwen van het nieuwe Performance Insights-paneel was een zeer plezierige en leerzame ervaring voor het team. We hebben veel geleerd over trace-bestanden, het werken met canvas en nog veel meer. We hopen dat u het nieuwe paneel met plezier gebruikt en we kijken uit naar uw feedback.
Zie Prestatie-inzichten: krijg bruikbare inzichten in de prestaties van uw website voor meer informatie over het paneel Prestatie-inzichten.
Download de previewkanalen
Overweeg Chrome Canary , Dev of Beta als uw standaard ontwikkelbrowser te gebruiken. Deze previewkanalen geven u toegang tot de nieuwste DevTools-functies, laten u geavanceerde webplatform-API's testen en helpen u problemen op uw site te ontdekken voordat uw gebruikers dat doen!
Neem contact op met het Chrome DevTools-team
Gebruik de volgende opties om nieuwe functies, updates of iets anders met betrekking tot DevTools te bespreken.
- Geef uw feedback en verzoeken voor nieuwe functies door aan crbug.com .
- Meld een DevTools-probleem met Meer opties > Help > Meld een DevTools-probleem in DevTools.
- Tweet naar @ChromeDevTools .
- Laat een reactie achter in de YouTube-video's 'Wat is er nieuw in DevTools' of in de YouTube-video's 'DevTools Tips' .