Infracción La tarea de JavaScript de ejecución prolongada tomó xx ms

Resuelto procatmer asked hace 7 años • 15 respuestas

Recientemente, recibí este tipo de advertencia y esta es la primera vez que la recibo:

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

Estoy trabajando en un proyecto grupal y no tengo idea de dónde viene esto. Esto nunca pasó antes. De repente, apareció cuando alguien más se involucró en el proyecto. ¿Cómo encuentro qué archivo/función causa esta advertencia? He estado buscando la respuesta, pero sobre todo la solución sobre cómo solucionarlo. No puedo resolverlo si ni siquiera puedo encontrar la fuente del problema.

En este caso, la advertencia aparece sólo en Chrome. Intenté usar Edge, pero no recibí ninguna advertencia similar y aún no lo he probado en Firefox.

Incluso recibo el error de jquery.min.js:

[Violation] Handler took 231ms of runtime (50ms allowed)            jquery.min.js:2
procatmer avatar Dec 19 '16 15:12 procatmer
Aceptado

Actualización : Chrome 58+ ocultó estos y otros mensajes de depuración de forma predeterminada. Para mostrarlos, haga clic en la flecha junto a "Información" y seleccione "Detallado".

Chrome 57 activó "ocultar infracciones" de forma predeterminada. Para volver a activarlas, debe habilitar los filtros y desmarcar la casilla "ocultar infracciones".

De repente aparece cuando alguien más involucrado en el proyecto.

Creo que es más probable que hayas actualizado a Chrome 56. Esta advertencia es una característica nueva maravillosa; en mi opinión, desactívala solo si estás desesperado y tu evaluador te quitará notas. Los problemas subyacentes están presentes en los otros navegadores, pero los navegadores simplemente no le dicen que hay un problema. El ticket de Chromium está aquí , pero en realidad no hay ninguna discusión interesante al respecto.

Estos mensajes son advertencias en lugar de errores porque en realidad no causarán problemas importantes. Puede provocar que los fotogramas se caigan o provocar una experiencia menos fluida.

Sin embargo, vale la pena investigarlos y corregirlos para mejorar la calidad de su aplicación. La forma de hacerlo es prestando atención a las circunstancias en las que aparecen los mensajes y realizando pruebas de rendimiento para determinar dónde está ocurriendo el problema. La forma más sencilla de iniciar las pruebas de rendimiento es insertar un código como este:

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 desea avanzar más, también puede utilizar el generador de perfiles de Chrome o utilizar una biblioteca de evaluación comparativa como esta .

Una vez que haya encontrado algún código que esté tardando mucho tiempo (50 ms es el umbral de Chrome), tiene un par de opciones:

  1. Elimine parte o toda esa tarea que pueda ser innecesaria
  2. Descubra cómo hacer la misma tarea más rápido
  3. Divida el código en varios pasos asincrónicos

(1) y (2) pueden ser difíciles o imposibles, pero a veces son muy fáciles y deberían ser sus primeros intentos. Si es necesario, siempre debería ser posible hacerlo (3). Para hacer esto usarás algo como:

setTimeout(functionToRunVerySoonButNotNow);

o

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

Puede leer más sobre la naturaleza asincrónica de JavaScript aquí .

voltrevo avatar Feb 20 '2017 23:02 voltrevo

Estas son sólo advertencias, como todos mencionaron. Sin embargo, si desea resolverlos (lo que debería hacer), primero debe identificar qué está causando la advertencia. No hay ningún motivo por el cual pueda recibir una advertencia de reflujo forzado. Alguien ha creado una lista de algunas opciones posibles. Puede seguir la discusión para obtener más información.
Aquí está la esencia de las posibles razones:

¿Qué fuerza el diseño/reflujo?

Todas las propiedades o métodos siguientes, cuando se solicitan/llaman en JavaScript, harán que el navegador calcule sincrónicamente el estilo y el diseño*. Esto también se denomina reflujo o alteración del diseño y es un cuello de botella común en el rendimiento.

Elemento

Métricas de caja
  • elem.offsetLeft, elem.offsetTop, elem.offsetWidth, elem.offsetHeight,elem.offsetParent
  • elem.clientLeft, elem.clientTop, elem.clientWidth,elem.clientHeight
  • elem.getClientRects(),elem.getBoundingClientRect()
Desplazarse cosas
  • elem.scrollBy(),elem.scrollTo()
  • elem.scrollIntoView(),elem.scrollIntoViewIfNeeded()
  • elem.scrollWidth,elem.scrollHeight
  • elem.scrollLeft, elem.scrollTopademás, poniéndolos
Enfocar
  • elem.focus() puede desencadenar un diseño doble forzado ( fuente )
También…
  • elem.computedRole,elem.computedName
  • elem.innerText( fuente )

getComputedStyle

window.getComputedStyle()normalmente forzará el recálculo de estilo ( fuente )

window.getComputedStyle()También forzará el diseño si se cumple alguna de las siguientes condiciones:

  1. El elemento está en un árbol de sombra.
  2. Hay consultas de medios (relacionadas con la ventana gráfica). Específicamente, uno de los siguientes: ( fuente ) * min-width, min-height, max-width, max-height, width, height * aspect-ratio, min-aspect-ratio,max-aspect-ratio
    • device-pixel-ratio, resolution,orientation
  3. La propiedad solicitada es una de las siguientes: ( fuente )
    • height, width * top, right, bottom, left * margin[ -top, -right, -bottom, -left, o taquigrafía ] solo si el margen es fijo. * padding[ -top, -right, -bottom, -lefto taquigrafía ] solo si el relleno es fijo. * transform, transform-origin, perspective-origin * translate, rotate, scale * webkit-filter, backdrop-filter * motion-path, motion-offset, motion-rotation * x, y, rx,ry

ventana

  • window.scrollX,window.scrollY
  • window.innerHeight,window.innerWidth
  • window.getMatchedCSSRules()solo fuerzas estilo

Formularios

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

Mouse events

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

document

  • doc.scrollingElement only forces style

Range

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

SVG

contenteditable

  • Lots & lots of stuff, …including copying an image to clipboard (source)

Check more here.

Also, here's Chromium source code from the original issue and a discussion about a performance API for the warnings.


Edit: There's also an article on how to minimize layout reflow on PageSpeed Insight by Google. It explains what browser reflow is:

Reflow is the name of the web browser process for re-calculating the positions and geometries of elements in the document, for the purpose of re-rendering part or all of the document. Because reflow is a user-blocking operation in the browser, it is useful for developers to understand how to improve reflow time and also to understand the effects of various document properties (DOM depth, CSS rule efficiency, different types of style changes) on reflow time. Sometimes reflowing a single element in the document may require reflowing its parent elements and also any elements which follow it.

In addition, it explains how to minimize it:

  1. Reduce unnecessary DOM depth. Changes at one level in the DOM tree can cause changes at every level of the tree - all the way up to the root, and all the way down into the children of the modified node. This leads to more time being spent performing reflow.
  2. Minimize CSS rules, and remove unused CSS rules.
  3. If you make complex rendering changes such as animations, do so out of the flow. Use position-absolute or position-fixed to accomplish this.
  4. Avoid unnecessary complex CSS selectors - descendant selectors in particular - which require more CPU power to do selector matching.
0xC0DED00D avatar Jun 26 '2017 09:06 0xC0DED00D