292 votes

Violation Une tâche JavaScript longuement exécutée a pris xx ms

Récemment, j'ai reçu ce genre d'avertissement, et c'est la première fois que je le reçois :

[Violation] Long running JavaScript task took 234ms
[Violation] Forced reflow while executing JavaScript took 45ms

Je travaille sur un projet de groupe et je n'ai aucune idée de l'origine de ce problème. Soudain, il apparaît lorsque quelqu'un d'autre participe au projet. Comment puis-je trouver quel fichier/fonction provoque cet avertissement ? J'ai cherché la réponse, mais surtout la solution pour le résoudre. Je ne peux pas le résoudre si je ne peux même pas trouver la source du problème.

Remarques : dans ce cas, l'avertissement n'apparaît que sur chrome. J'ai essayé d'utiliser Edge, je n'ai pas eu d'avertissement similaire. Je ne l'ai pas encore testé sur mozilla.

Mise à jour : Je reçois même l'erreur de jquery.min.js en disant :

[Violation] Handler took 231ms of runtime (50ms allowed)            jquery.min.js:2

252voto

Mozza314 Points 689

Mise à jour : Chrome 58+ a masqué ces messages de débogage et d'autres par défaut. Pour les afficher, cliquez sur la flèche située à côté de "Info" et sélectionnez "Verbose".

Mise à jour 2 : Chrome 57 a activé la fonction "masquer les violations" par défaut. Pour les réactiver, vous devez activer les filtres et décocher la case "masquer les violations".

il apparaît soudainement lorsque quelqu'un d'autre impliqué dans le projet

Je pense qu'il est plus probable que vous ayez mis à jour vers Chrome 56. Cet avertissement est une nouvelle fonctionnalité (à mon avis) merveilleuse - ne le désactivez que si vous êtes désespéré et votre évaluateur vous enlèvera des points. Les problèmes sous-jacents sont présents dans les autres navigateurs, mais ces derniers ne vous en informent pas. Le ticket Chromium est ici mais il n'y a pas vraiment de discussion intéressante à son sujet : https://bugs.chromium.org/p/chromium/issues/detail?id=662497

Ces messages sont des avertissements et non des erreurs, car ils ne posent pas vraiment de problèmes majeurs. Il se peut que des images soient perdues ou que l'expérience soit moins fluide.

Ils méritent cependant d'être examinés et corrigés pour améliorer la qualité de votre application. Pour ce faire, il convient de prêter attention aux circonstances dans lesquelles les messages apparaissent et de procéder à des tests de performance pour déterminer où le problème se produit. La façon la plus simple de commencer à tester les performances est d'insérer un code comme celui-ci :

function someMethodIThinkMightBeSlow() {
    const startTime = performance.now();

    // Do the normal stuff for this function

    const duration = performance.now() - startTime;
    console.log(`someMethodIThinkMightBeSlow took ${duration}ms`);
}

Si vous voulez aller plus loin, vous pouvez également utiliser le profileur de Chrome : https://developers.google.com/web/tools/chrome-devtools/rendering-tools/

Vous pouvez aussi utiliser une bibliothèque d'évaluation comparative comme celle-ci : https://benchmarkjs.com/

Une fois que vous avez trouvé un code qui prend beaucoup de temps (50 ms est le seuil fixé par Chrome), vous avez plusieurs options :

  1. Supprimez une partie ou la totalité de cette tâche qui n'est peut-être pas nécessaire.
  2. Trouver comment effectuer la même tâche plus rapidement
  3. Diviser le code en plusieurs étapes asynchrones

(1) et (2) peuvent être difficiles ou impossibles. Mais parfois vraiment faciles et devraient être vos premières tentatives. Si nécessaire, il devrait toujours être possible de faire (3). Pour ce faire, vous utiliserez quelque chose comme

setTimeout(functionToRunVerySoonButNotNow);

ou

// This one is not available natively in IE, but there are polyfills available.
Promise.resolve().then(functionToRunVerySoonButNotNow);

Vous pouvez en savoir plus sur la nature asynchrone de javascript ici :

http://blog.carbonfive.com/2013/10/27/the-javascript-event-loop-explained/

76voto

noob Points 3962

Ce ne sont que des avertissements, comme tout le monde l'a mentionné. Cependant, si vous tenez à les résoudre (ce qui devrait être le cas), vous devez d'abord identifier la cause de l'avertissement. Il n'y a pas une seule raison pour laquelle vous pouvez recevoir un avertissement de refusion forcée.
Quelqu'un a créé un liste pour quelques options possibles. Vous pouvez suivre la discussion pour plus d'informations.
Voici l'essentiel des raisons possibles -

Ce qui force la mise en page / la refonte

Toutes les propriétés ou méthodes ci-dessous, lorsqu'elles sont demandées/appelées en JavaScript, déclencheront le navigateur pour calculer de manière synchrone le style et la mise en page*. Ceci est également appelé reflow ou mise en page raclée , et constitue un goulot d'étranglement commun en matière de performances.

Élément

Métrique des boîtes

  • elem.offsetLeft , elem.offsetTop , elem.offsetWidth , elem.offsetHeight , elem.offsetParent
  • elem.clientLeft , elem.clientTop , elem.clientWidth , elem.clientHeight
  • elem.getClientRects() , elem.getBoundingClientRect()

Trucs de défilement

  • elem.scrollBy() , elem.scrollTo()
  • elem.scrollIntoView() , elem.scrollIntoViewIfNeeded()
  • elem.scrollWidth , elem.scrollHeight
  • elem.scrollLeft , elem.scrollTop aussi, les mettre

Focus

  • elem.focus() peut déclencher un double mise en page forcée ( source )

Aussi

  • elem.computedRole , elem.computedName
  • elem.innerText ( source )

getComputedStyle

window.getComputedStyle() forcera généralement le recalcul du style ( source )

window.getComputedStyle() forcera également la mise en page, si l'un des éléments suivants suivants est vrai :

  1. L'élément se trouve dans un arbre fantôme
  2. Il existe des requêtes médias (liées à l'affichage). Plus précisément, l'une des suivantes : ( source ) * min-width , min-height , max-width , max-height , width , height * aspect-ratio , min-aspect-ratio , max-aspect-ratio
    • device-pixel-ratio , resolution , orientation
  3. Le bien demandé est l'un des suivants : ( source )
    • height , width * top , right , bottom , left * margin [ -top , -right , -bottom , -left ou sténographie ] uniquement si la marge est fixe. * padding [ -top , -right , -bottom , -left , ou sténographie ] seulement si le rembourrage est fixe. * transform , transform-origin , perspective-origin * translate , rotate , scale * webkit-filter , backdrop-filter * motion-path , motion-offset , motion-rotation * x , y , rx , ry

fenêtre

  • window.scrollX , window.scrollY
  • window.innerHeight , window.innerWidth
  • window.getMatchedCSSRules() ne force que le style

Formulaires

  • inputElem.focus()
  • inputElem.select() , textareaElem.select() ( source )

Événements liés à la souris

  • mouseEvt.layerX , mouseEvt.layerY , mouseEvt.offsetX , mouseEvt.offsetY ( source )

document

  • doc.scrollingElement ne force que le style

Gamme

  • range.getClientRects() , range.getBoundingClientRect()

SVG

contentable

  • Beaucoup de choses, y compris la copie d'une image dans le presse-papiers ( source )

Vérifier plus ici .

Mise à jour :

robocat des commentaires

Pour en savoir plus : le code source de Chromium, issu de l'initiative émission initiale et a discussion sur une API de performance pour les avertissements.

Mise à jour 2 :
Il y a un article sur la façon de minimiser le reflux de la mise en page sur PageSpeed Insight de Google . Il explique ce qu'est le reflux du navigateur -

Reflow est le nom du processus du navigateur web pour recalculer les positions et les géométries des éléments du document, dans le but d'améliorer la qualité du document. positions et les géométries des éléments dans le document, dans le but de de refaire le rendu d'une partie ou de la totalité du document. Comme le reflux est une opération bloquante pour l'utilisateur dans le navigateur, il est utile pour les développeurs de de comprendre comment améliorer le temps de réaffichage et de comprendre les les effets de diverses propriétés du document (profondeur du DOM, efficacité des règles CSS efficacité, différents types de changements de style) sur le temps de reflux. Parfois, le reflux d'un seul élément dans le document peut nécessiter de refondre ses éléments parents ainsi que tous les éléments qui le suivent.

Et comment la minimiser -

  1. Réduire la profondeur inutile du DOM. Des changements à un niveau de l'arbre DOM peuvent provoquer des changements à tous les niveaux de l'arbre - jusqu'à la Racine, et jusqu'aux enfants du nœud modifié. Cela entraîne une augmentation du temps consacré à la refonte.
  2. Minimisez les règles CSS et supprimez les règles CSS inutilisées.
  3. Si vous effectuez des modifications complexes du rendu, telles que des animations, faites-le en dehors du flux. Pour ce faire, utilisez position-absolue ou position-fixe. cela.
  4. Évitez les sélecteurs CSS complexes inutiles, en particulier les sélecteurs descendants, qui requièrent davantage de puissance CPU pour la mise en correspondance des sélecteurs. qui requièrent davantage de puissance CPU pour la mise en correspondance des sélecteurs.

30voto

therobinkim Points 1645

Quelques idées :

  • Supprimez la moitié de votre code (peut-être en le commentant).

    • Le problème est toujours là ? Super, vous avez réduit les possibilités ! Répétez.

    • Le problème n'existe-t-il pas ? Ok, regarde la moitié que tu as commentée !

  • Utilisez-vous un système de contrôle de version (par exemple, Git) ? Si c'est le cas, git checkout certains de vos commits les plus récents. Quand le problème a-t-il été introduit ? Regardez le commit pour voir exactement quel code a changé lorsque le problème est apparu.

9voto

Matt Leonowicz Points 457

Dans mon cas, j'ai découvert que cela était en fait causé par un code provenant d'une extension (Adblock dans mon cas).

Afin d'identifier la source du problème, exécutez votre application et enregistrez-la dans le fichier Onglet Performance en Chrome.

Vous pouvez y vérifier diverses fonctions qui ont pris beaucoup de temps à s'exécuter. Dans mon cas, celle qui a provoqué des avertissements dans la console provenait d'un fichier chargé par l'extension Adblock, mais cela pourrait être autre chose dans votre cas.

Vérifiez ces fichiers et essayez d'identifier si c'est le code d'une extension ou le vôtre.

6voto

Jordan Reddick Points 336

Regardez dans la console Chrome sous l'onglet Réseau et trouvez les scripts qui prennent le plus de temps à charger.

Dans mon cas, il y avait un ensemble de scripts complémentaires Angular que j'avais inclus mais pas encore utilisés dans l'application :

<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.8/angular-ui-router.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-utils/0.1.1/angular-ui-utils.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.9/angular-animate.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.9/angular-aria.min.js"></script>

Ce sont les seuls fichiers JavaScript qui ont pris plus de temps à charger que le temps spécifié par l'erreur "Long Running Task".

Tous ces fichiers s'exécutent sur mes autres sites Web sans générer d'erreurs, mais je recevais cette erreur "Long Running Task" sur une nouvelle application Web qui n'avait pratiquement aucune fonctionnalité. L'erreur s'est arrêtée immédiatement après la suppression.

Je pense que ces modules complémentaires Angular recherchaient récursivement des balises de début dans des sections de plus en plus profondes du DOM. N'en trouvant aucune, ils devaient parcourir l'ensemble du DOM avant de sortir, ce qui prenait plus de temps que ce que Chrome attendait, d'où l'avertissement.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X