Surveillance de toute la mémoire utilisée par une page Web: performance.measureMemory ()

L'auteur de l'article, dont nous publions la traduction aujourd'hui, explique comment surveiller la mémoire allouée aux pages Web. Une attention particuliÚre à la mémoire des pages travaillant en production permet de maintenir la productivité des projets Web à un niveau élevé.



Les navigateurs contrĂŽlent automatiquement la mĂ©moire allouĂ©e aux pages Web. Lorsqu'une page crĂ©e un objet, le navigateur, en utilisant ses mĂ©canismes internes, alloue de la mĂ©moire pour stocker cet objet. Étant donnĂ© que la mĂ©moire n'est pas une ressource infinie, le navigateur effectue pĂ©riodiquement la collecte des ordures, au cours de laquelle les objets inutiles sont dĂ©tectĂ©s et la mĂ©moire qu'ils occupent est effacĂ©e. Le processus de dĂ©tection de tels objets n'est cependant pas idĂ©al. Il a Ă©tĂ© prouvĂ©que l'identification absolument exacte et complĂšte de ces objets est une tĂąche insoluble. En consĂ©quence, les navigateurs remplacent l'idĂ©e de trouver des «objets inutiles» par l'idĂ©e de trouver des «objets inaccessibles». Si une page Web ne peut pas accĂ©der Ă  l'objet via ses variables et champs d'autres objets qui lui sont accessibles, cela signifie que le navigateur peut effacer en toute sĂ©curitĂ© la mĂ©moire occupĂ©e par un tel objet. La diffĂ©rence entre «inutile» et «inaccessible» entraĂźne des fuites de mĂ©moire, comme illustrĂ© dans l'exemple suivant:

const object = { a: new Array(1000), b: new Array(2000) };
setInterval(() => console.log(object.a), 1000);

Il existe un grand tableau inutile ici b, mais le navigateur ne libÚre pas la mémoire qu'il occupe en raison du fait qu'il est accessible via la propriété d'objet object.bdans le rappel. Par conséquent, la mémoire occupée par ce tableau fuit.

Les fuites de mémoire sont fréquentes dans le développement Web. Ils apparaissent trÚs facilement dans les programmes lorsque, par exemple, les développeurs oublient de se désinscrire de l'écouteur d'événements, lorsqu'ils capturent accidentellement des objets dans un élément iframe, lorsqu'ils oublient de fermer le travailleur, lorsqu'ils collectent des objets dans des tableaux. Si une page Web présente des fuites de mémoire, cela conduit au fait qu'au fil du temps, la consommation de mémoire de la page augmente. Une telle page semble lente et lente pour les utilisateurs.

La premiÚre étape pour résoudre ce problÚme consiste à prendre des mesures. La nouvelle API performance.measureMemory () permet aux développeurs de mesurer l'utilisation de la mémoire par les pages Web en production et, par conséquent, de détecter les fuites de mémoire qui glissent à travers les tests locaux.

En quoi la nouvelle API performance.measureMemory () est-elle différente de l'ancienne performance.memory?


Si vous ĂȘtes familiarisĂ© avec l'API non standard existante performance.memory, alors vous pourriez ĂȘtre intĂ©ressĂ© par la question de savoir comment la nouvelle API diffĂšre de l'ancienne. La principale diffĂ©rence est que l'ancienne API renvoie la taille du tas JavaScript et la nouvelle Ă©value l'utilisation de la mĂ©moire de la page Web entiĂšre. Cette distinction est importante lorsque Chrome organise le partage de segments de mĂ©moire entre plusieurs pages Web (ou plusieurs instances de la mĂȘme page). Dans de tels cas, les rĂ©sultats renvoyĂ©s par l'ancienne API peuvent ĂȘtre dĂ©formĂ©s. Étant donnĂ© que l'ancienne API est dĂ©finie en termes spĂ©cifiques Ă  l'implĂ©mentation, comme un tas, la normalisation est une entreprise dĂ©sespĂ©rĂ©e.

Une autre différence est que dans Chrome, la nouvelle API prend des mesures de mémoire lors de la collecte des ordures. Cela réduit le «bruit» dans les résultats de mesure, mais peut prendre un certain temps pour obtenir les résultats. Veuillez noter que les créateurs d'autres navigateurs peuvent décider d'implémenter la nouvelle API sans se lier à la récupération de place.

Façons recommandées d'utiliser la nouvelle API


L'utilisation de la mémoire par les pages Web dépend de l'occurrence d'événements, des actions de l'utilisateur, de la récupération de place. C'est pourquoi l'API est performance.measureMemory()conçue pour étudier le niveau d'utilisation de la mémoire en production. Les résultats de l'appel de cette API dans un environnement de test sont moins utiles. Voici des exemples d'options pour l'utiliser:

  • - .
  • A/B- , .
  • .
  • , . .


Actuellement, l'API en question n'est prise en charge que dans Chrome 83, selon le schĂ©ma Origin Trial. Les rĂ©sultats renvoyĂ©s par l'API dĂ©pendent fortement de l'implĂ©mentation, car diffĂ©rents navigateurs utilisent diffĂ©rentes maniĂšres de reprĂ©senter les objets en mĂ©moire et diffĂ©rentes façons d'Ă©valuer le niveau d'utilisation de la mĂ©moire. Les navigateurs peuvent exclure certaines zones de mĂ©moire de la comptabilitĂ© si la comptabilitĂ© complĂšte de toute la mĂ©moire utilisĂ©e est une tĂąche dĂ©raisonnablement difficile ou impossible. Par consĂ©quent, nous pouvons dire que les rĂ©sultats produits par cette API dans diffĂ©rents navigateurs ne sont pas comparables. Il est logique de comparer uniquement les rĂ©sultats obtenus dans le mĂȘme navigateur.

Avancement des travaux en cours


ÉtapeĂ©tat
1. Création d'explications d'API
Terminé
2. Création d'un projet de spécification
Effectué
3. Rassembler les commentaires et finaliser le projet
Effectué
4. Tests d'essai d'origine
Effectué
5. Lancement
Pas commencé

Utilisation de performance.measureMemory ()


▍ Activer la prise en charge de l'essai d'origine


L'API performance.measureMemory()est disponible dans Chrome 83 selon le schéma d'essai d'origine. Cette phase devrait se terminer avec la sortie de Chrome 84. L'

essai d'origine permet aux dĂ©veloppeurs de profiter des nouvelles fonctionnalitĂ©s de Chrome et de partager leurs commentaires sur la commoditĂ©, la convivialitĂ© et l'efficacitĂ© de ces fonctionnalitĂ©s avec la communautĂ© Web. Des dĂ©tails sur ce programme peuvent ĂȘtre trouvĂ©s ici . Vous pouvez vous abonner au programme sur la page d' inscription.

▍Inscription au programme Origin Trial


  1. Demandez un jeton pour l'opportunité qui vous intéresse.
  2. Ajoutez le jeton aux pages du projet pilote. Il y a 2 façons de procéder:

    • Ajoutez une <meta>balise origin-trialau titre de chaque page. Par exemple, il pourrait ressembler Ă  ceci: <meta http-equiv="origin-trial" content="TOKEN_GOES_HERE">.
    • Si vous avez accĂšs aux paramĂštres du serveur, il peut ajouter un jeton Ă  l'aide d'un en-tĂȘte HTTP Origin-Trial. En consĂ©quence, l' en- tĂȘte de rĂ©ponse devrait apparaĂźtre quelque chose comme ce qui suit: Origin-Trial: TOKEN_GOES_HERE.

▍Activer une nouvelle fonctionnalitĂ© via les drapeaux Chrome


Afin d'expérimenter performance.measureMemory(), pendant la distribution avec le jeton Origin Trial, vous devez activer le drapeau #experimental-web-platform-featuresdans chrome://flags.

▍VĂ©rification de l'utilisation de l'API


Un appel de fonction performance.measureMemory()peut Ă©chouer, avec une SecurityError levĂ©e . Cela peut se produire si l'environnement ne rĂ©pond pas aux exigences de sĂ©curitĂ© pour les fuites d'informations. Lors du test Origin Trial dans Chrome, cette API nĂ©cessite l'inclusion de l' isolement du site . Lorsque l'API est prĂȘte pour une utilisation normale, elle s'appuiera sur la propriĂ©tĂ© crossOriginIsolated . Une page Web peut fonctionner dans ce mode en dĂ©finissant les en-tĂȘtes COOP et COEP .

Voici un exemple de code:

if (performance.measureMemory) {
  let result;
  try {
    result = await performance.measureMemory();
  } catch (error) {
    if (error instanceof DOMException &&
        error.name === "SecurityError") {
      console.log("The context is not secure.");
    } else {
      throw error;
    }
  }
  console.log(result);
}

▍Test local


Chrome prend une mesure de mémoire lors de la collecte des ordures. Cela signifie que l'accÚs à l'API ne résout pas instantanément la promesse. Pour obtenir le résultat, vous devez attendre la prochaine session de récupération de place. L'API démarre de force la récupération de place aprÚs un certain délai, qui est actuellement défini sur 20 secondes. Si vous exécutez Chrome avec un indicateur de ligne de commande --enable-blink-features='ForceEagerMeasureMemory', le délai sera réduit à zéro, ce qui est utile pour le débogage local et les tests locaux.

Exemple


Il est recommandĂ© d'utiliser la nouvelle API en dĂ©finissant un moniteur de mĂ©moire global qui mesure le niveau d'utilisation de la mĂ©moire de la page entiĂšre et envoie les rĂ©sultats au serveur, oĂč ils peuvent ĂȘtre agrĂ©gĂ©s et analysĂ©s. La façon la plus simple de travailler avec cette API est de prendre des mesures pĂ©riodiques. Par exemple, ils peuvent s'exĂ©cuter toutes les Mminutes. Cependant, cela introduit des distorsions dans les donnĂ©es, car des pics d'utilisation de la mĂ©moire peuvent survenir entre les mesures. L'exemple suivant montre comment, Ă  l' aide du processus de Poisson , effectuer des mesures sans erreurs systĂ©matiques. Cette approche garantit que les sessions de mesure peuvent, avec une probabilitĂ© Ă©gale, avoir lieu Ă  tout moment ( voici une dĂ©monstration de cette approche,voici le code source).

Tout d'abord, dĂ©clarez une fonction qui planifie le prochain dĂ©marrage d'une session pour mesurer la quantitĂ© de mĂ©moire consommĂ©e Ă  l'aide d'une fonction setTimeout()avec un intervalle dĂ©fini de maniĂšre alĂ©atoire. Cette fonction doit ĂȘtre appelĂ©e aprĂšs le chargement de la page dans la fenĂȘtre du navigateur.

function scheduleMeasurement() {
  if (!performance.measureMemory) {
    console.log("performance.measureMemory() is not available.");
    return;
  }
  const interval = measurementInterval();
  console.log("Scheduling memory measurement in " +
      Math.round(interval / 1000) + " seconds.");
  setTimeout(performMeasurement, interval);
}

//       .
window.onload = function () {
  scheduleMeasurement();
}

La fonction measurementInterval()trouve un intervalle alĂ©atoire, exprimĂ© en millisecondes, dĂ©fini de telle sorte qu'une mesure soit effectuĂ©e environ toutes les cinq minutes. Si vous ĂȘtes intĂ©ressĂ© par les concepts mathĂ©matiques sur lesquels cette fonction est basĂ©e, lisez la distribution exponentielle .

function measurementInterval() {
  const MEAN_INTERVAL_IN_MS = 5 * 60 * 1000;
  return -Math.log(Math.random()) * MEAN_INTERVAL_IN_MS;
}

Par conséquent, la fonction asynchrone performMeasurement()appelle notre API, enregistre le résultat et planifie la prochaine mesure.

async function performMeasurement() {
  // 1.  performance.measureMemory().
  let result;
  try {
    result = await performance.measureMemory();
  } catch (error) {
    if (error instanceof DOMException &&
        error.name === "SecurityError") {
      console.log("The context is not secure.");
      return;
    }
    //    .
    throw error;
  }
  // 2.  .
  console.log("Memory usage:", result);
  // 3.   .
  scheduleMeasurement();
}

Les résultats des mesures peuvent ressembler à ceci:

// ,    :
{
  bytes: 60_000_000,
  breakdown: [
    {
      bytes: 40_000_000,
      attribution: ["https://foo.com"],
      userAgentSpecificTypes: ["Window", "JS"]
    },
    {
      bytes: 20_000_000,
      attribution: ["https://foo.com/iframe"],
      userAgentSpecificTypes: ["Window", "JS"]
    }
  ]
}

Une estimation du niveau global d'utilisation de la mĂ©moire s'affiche dans le champ bytes. Pour dĂ©river cette estimation, les sĂ©parateurs des chiffres sont utilisĂ©s. Ces valeurs dĂ©pendent fortement de l'implĂ©mentation. S'ils sont reçus pour diffĂ©rents navigateurs, vous ne pouvez pas les comparer. La façon dont ils sont obtenus peut varier mĂȘme dans diffĂ©rentes versions du mĂȘme navigateur. Pendant la durĂ©e du programme Origin Trial, les valeurs de retour incluent des indicateurs d'utilisation de la mĂ©moire JavaScript par la fenĂȘtre principale, des indicateurs d'utilisation de la mĂ©moire des Ă©lĂ©ments iframedu mĂȘme site et des indicateurs de fenĂȘtres associĂ©es. Lorsque l'API est prĂȘte, cette valeur reprĂ©sentera des informations sur la mĂ©moire consommĂ©e par JavaScript, le DOM, tous les Ă©lĂ©ments iframeassociĂ©s aux fenĂȘtres et aux travailleurs Web.

listebreakdowndonne des informations plus dĂ©taillĂ©es sur la mĂ©moire utilisĂ©e. Chaque entrĂ©e dĂ©crit un morceau de mĂ©moire et associe ce fragment Ă  un ensemble de fenĂȘtres, d'Ă©lĂ©ments iframeou de travailleurs identifiĂ©s par une URL. Le champ userAgentSpecificTypesrĂ©pertorie les types de mĂ©moire dĂ©terminĂ©s par les fonctionnalitĂ©s d'implĂ©mentation.

Il est important de considérer ces listes de maniÚre générale et de ne pas essayer, en s'appuyant sur les fonctionnalités d'un certain navigateur, d'analyser tout en fonction de celles-ci. Par exemple, certains navigateurs peuvent renvoyer une liste breakdownvide ou des champs vides attribution. D'autres navigateurs peuvent renvoyer attributionplusieurs URL dans un élément , indiquant qu'ils ne peuvent pas identifier à laquelle de ces URL appartient la mémoire.

Retour d'information


Le groupe de la communauté des performances Web et l'équipe de développement Chrome seront ravis de savoir ce que vous en pensez performance.measureMemory()et d'en savoir plus sur votre expérience d'utilisation de cette API.

Partagez vos idées sur le périphérique API avec nous


Y a-t-il quelque chose dans cette API qui ne fonctionne pas comme prĂ©vu? Peut-ĂȘtre qu'il manque quelque chose dont vous avez besoin pour mettre en Ɠuvre votre idĂ©e? Ouvrez une nouvelle tĂąche dans le suivi de projet ou commentez une tĂąche existante.

Signaler un problùme de mise en Ɠuvre


Vous avez trouvĂ© un bug dans votre implĂ©mentation Chrome? Ou peut-ĂȘtre que la mise en Ɠuvre est diffĂ©rente de la spĂ©cification? Enregistrez l'erreur ici: new.crbug.com . Essayez d'inclure autant de dĂ©tails que possible dans votre message, incluez des instructions simples sur la façon de reproduire l'erreur et indiquez que le problĂšme est liĂ© Ă  Blink>PerformanceAPIs. Glitch est un trĂšs bon moyen de dĂ©montrer les erreurs .

Soutenez-nous


performance.measureMemory()Envisagez-vous d'utiliser ? Si c'est comme ça, dis nous en plus Ă  propos. Ces histoires aident l'Ă©quipe de dĂ©veloppement Chrome Ă  Ă©tablir des prioritĂ©s. Ces histoires montrent aux crĂ©ateurs d'autres navigateurs l'importance de prendre en charge de nouvelles fonctionnalitĂ©s. Si vous le souhaitez, envoyez un tweet Ă  @ChromiumDev et dites-nous oĂč et comment vous utilisez la nouvelle API.

Chers lecteurs! As-tu essayé performance.measureMemory()?


All Articles