Profilage des performances des applications React

Aujourd'hui, nous allons parler de la mesure des performances de rendu des composants React à l'aide de l'API React Profiler. Nous évaluerons également les interactions avec le composant à l'aide de la nouvelle API expérimentale de suivi des interactions. De plus, nous utiliserons l'API User Timing pour prendre nos propres mesures.

Nous utiliserons l'application React Movies Queue comme plateforme d'expériences.


Application React Movies Queue

API React Profiler


L'API React Profiler est conçue pour mesurer les performances de rendu et permet d'identifier les goulots d'étranglement des performances des applications.

import React, { Fragment, unstable_Profiler as Profiler} from "react";

Le composant Profileraccepte un rappel onRendercomme propriété. Il est appelé chaque fois qu'un composant de l'arborescence profilée valide une mise à jour.

const Movies = ({ movies, addToQueue }) => (
  <Fragment>
    <Profiler id="Movies" onRender={callback}>

Essayons, à des fins de test, de mesurer le temps nécessaire au rendu des parties d'un composant Movies. Voici à quoi ça ressemble.


L'application React Movies Queue et la recherche sur les films utilisant les

outils de rappel du développeur ReactonRender acceptent des paramètres qui décrivent ce qui est rendu et le temps qu'il faut pour le rendre. Cela comprend les éléments suivants:

  • id: Propriété idde l'arborescence des composants Profilerpour laquelle la modification a été validée.
  • phase: ou mount(si l'arborescence a été montée), ou update(si l'arborescence a été restituée).
  • actualDuration: Le temps nécessaire pour rendre une mise à jour fixe.
  • baseDuration: Temps estimé pour rendre l'intégralité du sous-arbre sans mise en cache.
  • startTime: Heure à laquelle React a commencé à rendre cette mise à jour.
  • commitTime: le moment où React a validé cette mise à jour.
  • interactions: De nombreuses «interactions» pour cette mise à jour.

const callback = (id, phase, actualTime, baseTime, startTime, commitTime) => {
    console.log(`${id}'s ${phase} phase:`);
    console.log(`Actual time: ${actualTime}`);
    console.log(`Base time: ${baseTime}`);
    console.log(`Start time: ${startTime}`);
    console.log(`Commit time: ${commitTime}`);
}

Nous allons charger la page et accéder à la console Chrome Developer Tools. Là, nous devrions voir ce qui suit.


Profilage des résultats dans les outils de développement

Nous pouvons en outre ouvrir les outils de développement React, accéder au signetProfileret visualiser des informations sur l'heure de rendu des composants. Ci-dessous, une visualisation de ce temps sous la forme d'un graphique de flamme.


Utilisation des résultats de profilage dans React Developer Tools

J'aime également utiliser le mode d'affichage iciRanked, qui fournit une vue ordonnée des données. Par conséquent, les composants dont le rendu prend le plus de temps sont en haut de la liste.


Affichage des résultats de profilage en mode Classé.

De plus, vous pouvez utiliser plusieurs composants pour prendre des mesures dans différentes parties de l'applicationProfiler:

import React, { Fragment, unstable_Profiler as Profiler} from "react";

render(
  <App>
    <Profiler id="Header" onRender={callback}>
      <Header {...props} />
    </Profiler>
    <Profiler id="Movies" onRender={callback}>
      <Movies {...props} />
    </Profiler>
  </App>
);

Et comment analyser les interactions des utilisateurs avec les composants?

API de suivi des interactions


Ce serait bien de pouvoir suivre les interactions des utilisateurs avec l'interface de l'application (comme les clics sur les éléments). Cela vous permettra de trouver des réponses à des questions intéressantes comme celle-ci: "Combien de temps a-t-il fallu pour mettre à jour le DOM après avoir cliqué sur ce bouton?". Heureusement, React dispose d'un support expérimental pour analyser les interactions des utilisateurs avec l'application à l'aide de l'API Interaction Tracing du nouveau package du planificateur . Vous pouvez lire la documentation à ce sujet ici .

Des informations sur les interactions entre l'utilisateur et l'application sont fournies avec des descriptions (par exemple, «L'utilisateur a cliqué sur le bouton Ajouter au panier») et des horodatages. De plus, lors de la configuration de l'analyse des interactions, des rappels sont utilisés dans lesquels des actions correspondant à l'une ou l'autre interaction sont effectuées.

Dans notre application, il y a un bouton Add Movie To Queuesur lequel l'icône est affichée +. Il sert à ajouter des films à la file d'attente de visualisation.


Bouton d'ajout d'un film à la file d'attente de visualisation

Voici un exemple de code qui surveille les mises à jour de statut pour cette interaction utilisateur avec l'application:

import { unstable_Profiler as Profiler } from "react";
import { render } from "react-dom";
import { unstable_trace as trace } from "scheduler/tracing";

class MyComponent extends Component {
  addMovieButtonClick = event => {
    trace("Add To Movies Queue click", performance.now(), () => {
      this.setState({ itemAddedToQueue: true });
    });
  };
}

Nous pouvons enregistrer des informations sur cette interaction et connaître sa durée en contactant les outils de développement React.


Analyse de l'interaction utilisateur avec un élément d'application

En utilisant l'API Interaction Tracing, vous pouvez également collecter des informations sur le premier rendu de composant:

import { unstable_trace as trace } from "scheduler/tracing";

trace("initial render", performance.now(), () => {
   ReactDom.render(<App />, document.getElementById("app"));
});



Analyse du premier rendu du composant

L'auteur de l'API donne d'autres exemples de son utilisation. Par exemple, illustrer le profilage de tâches asynchrones.

Marionnettiste


Pour l'automatisation du test de l'interaction des utilisateurs avec les éléments d'application, l'utilisation de Puppeteer peut sembler intéressante . Il s'agit d'une bibliothèque Node.js qui donne accès à une API de haut niveau conçue pour contrôler un navigateur Chrome sans interface utilisateur à l'aide du protocole DevTools.

Lors de l'utilisation de Puppeteer, le développeur est fourni avec des méthodes d' assistance tracing.start()et tracing.stop()conçu pour collecter des indicateurs de performance DevTools. Vous trouverez ci-dessous un exemple d'utilisation de ces mécanismes pour collecter des données sur ce qui se passe lorsque vous cliquez sur le bouton qui nous intéresse.

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  const navigationPromise = page.waitForNavigation();
  await page.goto('https://react-movies-queue.glitch.me/')
  await page.setViewport({ width: 1276, height: 689 });
  await navigationPromise;

  const addMovieToQueueBtn = 'li:nth-child(3) > .card > .card__info > div > .button';
  await page.waitForSelector(addMovieToQueueBtn);

  //  ...
  await page.tracing.start({ path: 'profile.json' });
  //   
  await page.click(addMovieToQueueBtn);
  //  
  await page.tracing.stop();

  await browser.close();
})()

Maintenant, après avoir chargé le fichier profile.jsondans la Performancebarre d'outils du développeur, nous pouvons voir quels appels de fonction ont été déclenchés en cliquant sur le bouton.


Analyse des conséquences d'un clic sur le bouton

Si vous êtes intéressé par le sujet de l'analyse des performances des composants - jetez un œil à ce matériel.

API de synchronisation utilisateur


L'API de synchronisation utilisateur permet au développeur de créer des mesures de performances personnalisées à l'aide d'horodatages très précis. La méthode window.performance.mark()crée un horodatage auquel le nom est attribué. La méthode window.performance.measure()vous permet de connaître le temps écoulé entre deux mesures.

//     
performance.mark('Movies:updateStart');
//  

//     
performance.mark('Movies:updateEnd');

//        
performance.measure('moviesRender', 'Movies:updateStart', 'Movies:updateEnd');

Lors du profilage d'une application React à l'aide de l'onglet PerformanceChrome Developer Tools, vous pouvez trouver une section Timingremplie de mesures temporaires concernant les composants React. React, lors du rendu, peut publier ces informations à l'aide de l'API User Timing.


Onglet Performances des outils de développement Chrome

Notez que les API User Timings sont supprimées des assemblages React DEV, en les remplaçant par l'API React Profiler, qui fournit des horodatages plus précis. À l'avenir, la prise en charge de cette API sera peut-être rétablie en le faisant pour les navigateurs prenant en charge la spécification User Timing Level 3. 

Sur Internet, vous pouvez trouver des sites React qui utilisent l'API User Timing pour définir leurs propres mesures. Cela inclut, par exemple, laTime to first post title visiblemétriqueRedditet la métrique SpotifyTime to playback ready.




Métriques spéciales utilisées sur les sites React Les métriques créées par l'API User Timing sont facilement affichées dans le panneau Phare desoutils de développement Chrome.


Mesures dans le panneau Phare

Par exemple, les dernières versions de Next.js incluent des mesures et des mécanismes personnalisés pour mesurer de nombreux événements différents. Y compris les éléments suivants:

  • Next.js-hydration: temps nécessaire pour mettre le balisage pré-rendu en état de fonctionnement.
  • Next.js-nav-to-render: Le temps entre le début de la navigation et le début du rendu.

Toutes ces mesures sont affichées dans la zone Timings.


Analyse des métriques Next.js

Outils de développement et phare


Je vous rappelle que Lighthouse et la Performancebarre d'outils des développeurs Chrome peuvent être utilisés pour analyser en profondeur le processus de chargement et les performances des applications React. Vous trouverez ici des mesures qui affectent particulièrement la perception des pages par les utilisateurs.


Analyse des performances de la page

Ceux qui travaillent avec React pourraient aimer le fait qu'ils auront de nouvelles mesures à leur disposition - comme la mesure du temps de blocage total (TBT), qui donne des informations sur la durée pendant laquelle la page est en mode non interactif jusqu'à ce qu'elle peut fonctionner de manière fiable en mode interactif ( Time to Interactive ). Voici les indicateurs TBT («avant» et «après») pour une application qui utilise le mode concurrentiel expérimental, dont l'utilisation aide l'application à s'adapter aux caractéristiques de l'environnement dans lequel elle s'exécute.


Modifier TBT

Ces outils sont utiles pour analyser les goulots d'étranglement des performances des applications, telles que les tâches qui prennent beaucoup de temps à terminer, ce qui retarde la transition en ligne de l'application. Par exemple, cela peut se rapporter à une analyse de la vitesse de réaction de l'application aux pressions de boutons.


De plus, l'analyse de l'application

Lighthouse donne aux développeurs React de nombreux conseils spécifiques sur de nombreux problèmes. Voici le résultat de l'analyse dans Lighthouse 6.0 . Ici, la section Supprimer le code JavaScript inutilisés'ouvre, qui indique le code JavaScript inutilisé chargé dans l'application, qui peut être importé à l'aideReact.lazy().


Analyser une application dans Lighthouse

Les applications sont toujours utiles pour tester sur du matériel, qui est très probablement à la disposition de ses utilisateurs finaux. Je me fie souvent au Webpagetest et aux données RUM et CrUX dans ces domaines, ce qui me permet d'obtenir des informations plus complètes sur les performances des applications.

Chers lecteurs! Comment recherchez-vous les performances de vos applications React?


All Articles