resumen - Infracción La tarea de JavaScript de larga ejecución tomó xx ms
resumen javascript pdf (12)
Busque en la consola de Chrome debajo de la pestaña Red y encuentre los scripts que tardan más en cargarse.
En mi caso, había un conjunto de scripts adicionales de Angular que había incluido pero que aún no había usado en la aplicación:
<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>
Estos fueron los únicos archivos JavaScript que tardaron más en cargarse que el tiempo que especificó el error "Tarea de ejecución larga".
Todos estos archivos se ejecutan en mis otros sitios web sin generar errores, pero recibí este error de "Tarea de ejecución prolongada" en una nueva aplicación web que apenas tenía funcionalidad. El error se detuvo inmediatamente al eliminarlo.
Mi mejor conjetura es que estos complementos angulares buscaban recursivamente en secciones cada vez más profundas del DOM para sus etiquetas de inicio; al no encontrar ninguna, tuvieron que atravesar todo el DOM antes de salir, lo que llevó más tiempo de lo que Chrome esperaba, por lo tanto, la advertencia.
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 principalmente sobre la solución sobre cómo resolverla. No puedo resolverlo si ni siquiera puedo encontrar la fuente del problema.
En este caso, la advertencia solo aparece en Chrome. Intenté usar Edge, pero no recibí ninguna advertencia similar, y todavía 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
El reflujo forzado a menudo ocurre cuando tiene una función llamada varias veces antes del final de la ejecución.
Por ejemplo, puede tener el problema en un teléfono inteligente, pero no en un navegador clásico.
Sugiero usar un
setTimeout
para resolver el problema.
Esto no es muy importante, pero repito, el problema surge cuando se llama a una función varias veces, y no cuando la función tarda más de 50 ms. Creo que te equivocas en tus respuestas.
- Desactive las llamadas 1 por 1 y vuelva a cargar el código para ver si aún produce el error.
-
Si un segundo script causa el error, use
setTimeOut
función de la duración de la infracción.
En mi caso, descubrí que esto en realidad fue causado por un código de una extensión. Para mí, la extensión fue AdBlock.
Para identificar la fuente del problema, ejecute su aplicación y regístrela en la pestaña Rendimiento de Chrome.
Allí puede verificar varias funciones que tardaron mucho en ejecutarse. En mi caso, el que se correlacionó con las advertencias en la consola era de un archivo que fue cargado por la extensión AdBlock, pero esto podría ser algo más en su caso.
Verifique estos archivos e intente identificar si este es el código de alguna extensión o el suyo. (Si es tuyo, entonces has encontrado la fuente de tu problema).
Encontré la raíz de este mensaje en mi código, que buscaba y ocultaba o mostraba nodos (sin conexión). Este fue mi código:
search.addEventListener(''keyup'', function() {
for (const node of nodes)
if (node.innerText.toLowerCase().includes(this.value.toLowerCase()))
node.classList.remove(''hidden'');
else
node.classList.add(''hidden'');
});
La pestaña de rendimiento (generador de perfiles) muestra que el evento tarda unos 60 ms:
Ahora:
search.addEventListener(''keyup'', function() {
const nodesToHide = [];
const nodesToShow = [];
for (const node of nodes)
if (node.innerText.toLowerCase().includes(this.value.toLowerCase()))
nodesToShow.push(node);
else
nodesToHide.push(node);
nodesToHide.forEach(node => node.classList.add(''hidden''));
nodesToShow.forEach(node => node.classList.remove(''hidden''));
});
La pestaña de rendimiento (generador de perfiles) ahora muestra que el evento dura aproximadamente 1 ms:
Y siento que la búsqueda funciona más rápido ahora (229 nodos).
Encontré una solución en el código fuente de Apache Cordova. Se implementan así:
var resolvedPromise = typeof Promise == ''undefined'' ? null : Promise.resolve();
var nextTick = resolvedPromise ? function(fn) { resolvedPromise.then(fn); } : function(fn) { setTimeout(fn); };
Implementación simple, pero de manera inteligente.
Sobre Android 4.4, use
Promise
.
Para navegadores antiguos, use
setTimeout()
Uso:
nextTick(function() {
// your code
});
Después de insertar este código de truco, todos los mensajes de advertencia desaparecen.
Estas son solo advertencias como todos mencionaron.
Sin embargo, si está interesado en resolverlos (lo cual debería), primero debe identificar qué está causando la advertencia.
No hay una sola razón por la cual pueda obtener una advertencia de reflujo de fuerza.
Alguien ha creado una
list
para algunas opciones posibles.
Puedes seguir la discusión para más información.
Aquí está la esencia de las posibles razones:
Lo que fuerza el diseño / reflujo
Todas las propiedades o métodos a continuación, cuando se solicitan / llaman en JavaScript, activarán el navegador para calcular sincrónicamente el estilo y el diseño *. Esto también se conoce como reflujo o distribución de diseño , y es un cuello de botella de rendimiento común.
Elemento
Métricas de cajaCosas de desplazamiento
elem.offsetLeft
,elem.offsetTop
,elem.offsetWidth
,elem.offsetHeight
,elem.offsetParent
elem.clientLeft
,elem.clientTop
,elem.clientWidth
,elem.clientHeight
elem.getClientRects()
,elem.getBoundingClientRect()
Atención
elem.scrollBy()
,elem.scrollTo()
elem.scrollIntoView()
,elem.scrollIntoViewIfNeeded()
elem.scrollWidth
,elem.scrollHeight
elem.scrollLeft
,elem.scrollTop
también, configurándolosTambién…
elem.focus()
puede desencadenar un diseño doblemente forzado ( source )
elem.computedRole
,elem.computedName
elem.innerText
( source )getComputedStyle
window.getComputedStyle()
generalmente forzará el recalc de estilo ( source )
window.getComputedStyle()
forzará el diseño, también, si alguno de los siguientes es cierto:
- El elemento está en un árbol de sombra.
- Hay consultas de medios (relacionadas con la ventana gráfica). Específicamente, uno de los siguientes: ( source ) *
min-width
min-height
,max-width
max-height
,width
,height
*aspect-ratio
min-aspect-ratio
,aspect-ratio
min-aspect-ratio
max-aspect-ratio
device-pixel-ratio
,resolution
,orientation
- La propiedad solicitada es una de las siguientes: ( source )
height
,width
*top
,right
,bottom
,left
*margin
[-right
,-bottom
,-left
,-left
o shorthand ] solo si el margen es fijo. *padding
[-right
,-right
,-bottom
,-left
o shorthand ] 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 fuerza el estiloFormas
inputElem.focus()
inputElem.select()
,textareaElem.select()
( source )Eventos de mouse
mouseEvt.layerX
,mouseEvt.layerY
,mouseEvt.offsetX
,mouseEvt.offsetY
( source )documento
doc.scrollingElement
solo fuerza el estiloDistancia
range.getClientRects()
,range.getBoundingClientRect()
SVG
- Bastante; no han hecho una lista exhaustiva, pero la Lista de Disparo de Diseño 2011 de Tony Gentilcore señaló algunas.
contento
- Montones y montones de cosas, ... incluyendo copiar una imagen al portapapeles ( source )
Consulta más list .
Además, aquí está el código fuente de Chromium del here y una discusión sobre una API de rendimiento para las advertencias.
Editar: También hay un artículo sobre cómo minimizar el reflujo de diseño en PageSpeed Insight de Google . Explica qué es el reflujo del navegador:
Reflow es el nombre del proceso del navegador web para volver a calcular las posiciones y geometrías de los elementos en el documento, con el fin de volver a representar parte o la totalidad del documento. Debido a que el reflujo es una operación de bloqueo del usuario en el navegador, es útil para los desarrolladores comprender cómo mejorar el tiempo de reflujo y también comprender los efectos de varias propiedades del documento (profundidad del DOM, eficiencia de la regla CSS, diferentes tipos de cambios de estilo) en el reflujo hora. A veces, el reflujo de un solo elemento en el documento puede requerir el reflujo de sus elementos principales y también de los elementos que lo siguen.
Además, explica cómo minimizarlo:
- Reduce la profundidad innecesaria del DOM. Los cambios en un nivel en el árbol DOM pueden causar cambios en cada nivel del árbol, hasta la raíz y hasta los elementos secundarios del nodo modificado. Esto lleva a pasar más tiempo realizando reflujo.
- Minimice las reglas CSS y elimine las reglas CSS no utilizadas.
- Si realiza cambios de representación complejos, como animaciones, hágalo fuera del flujo. Use position-absolute o position-fixed para lograr esto.
- Evite los selectores CSS complejos innecesarios, en particular los selectores descendientes, que requieren más potencia de la CPU para hacer coincidir los selectores.
Este es un error de violación de Google Chrome que se muestra cuando el nivel de registro
Verbose
está habilitado.
Ejemplo de mensaje de error:
Explicación:
Reflow es el nombre del proceso del navegador web para volver a calcular las posiciones y geometrías de los elementos en el documento, con el fin de volver a representar parte o la totalidad del documento. Debido a que el reflujo es una operación de bloqueo del usuario en el navegador, es útil para los desarrolladores comprender cómo mejorar el tiempo de reflujo y también comprender los efectos de varias propiedades del documento (profundidad del DOM, eficiencia de la regla CSS, diferentes tipos de cambios de estilo) en el reflujo hora. A veces, el reflujo de un solo elemento en el documento puede requerir el reflujo de sus elementos principales y también de los elementos que lo siguen.
Artículo original: Minimizando el reflujo del navegador por Lindsey Simon, UX Developer, publicado en developers.google.com.
Y este es el enlace que Google Chrome le brinda en el perfilador de rendimiento, en los perfiles de diseño (las regiones malva), para obtener más información sobre la advertencia.
Esto no es un error, simplemente un mensaje.
Para ejecutar este mensaje, cambie
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
(ejemplo)
a
<!DOCTYPE html>
(la fuente de Firefox espera esto)
El mensaje se mostró en Google Chrome 74 y Opera 60.
Después de cambiarlo estaba claro, 0 detallado.
Un enfoque de solución
Esto se agregó en Chrome 56 beta, a pesar de que no está en este registro de cambios del Blog de Chromium:
Chrome 56 Beta: advertencia de "No seguro", Web Bluetooth y
position: sticky
CSS
position: sticky
Puede ocultar esto en la barra de filtro de la consola con la casilla de verificación Ocultar infracciones .
Si está utilizando Chrome Canary (o Beta), simplemente marque la opción ''Ocultar infracciones''.
Un par de ideas:
-
Elimine la mitad de su código (quizás comentando).
-
¿El problema sigue ahí? ¡Genial, has reducido las posibilidades! Repetir.
-
¿El problema no está ahí? Ok, mira la mitad que comentaste!
-
-
¿Está utilizando algún sistema de control de versiones (por ejemplo, Git)? Si es así,
git checkout
algunos de tus commits más recientes. ¿Cuándo se introdujo el problema? Mire la confirmación para ver exactamente qué código cambió cuando llegó el problema por primera vez.
Actualización : Chrome 58+ ocultó estos y otros mensajes de depuración de forma predeterminada. Para mostrarlos, haga clic en la flecha al lado de ''Información'' y seleccione ''Detallado''.
Chrome 57 activó ''ocultar violaciones'' de forma predeterminada. Para volver a activarlos, debe habilitar los filtros y desmarcar la casilla ''ocultar violaciones''.
de repente aparece cuando alguien más involucrado en el proyecto
Creo que es más probable que haya actualizado a Chrome 56. Esta advertencia es una nueva característica maravillosa, en mi opinión, desactívela solo si está desesperado y su asesor le quitará las marcas. Los problemas subyacentes están en los otros navegadores, pero los navegadores simplemente no le dicen que hay un problema. El boleto de Chromium está here pero en realidad no hay ninguna discusión interesante al respecto.
Estos mensajes son advertencias en lugar de errores porque realmente no va a causar problemas importantes. Puede hacer que los cuadros se caigan o causar una experiencia menos fluida.
Sin embargo, vale la pena investigar y corregir para mejorar la calidad de su aplicación. La forma de hacerlo es prestando atención a las circunstancias en que aparecen los mensajes y realizando pruebas de rendimiento para limitar dónde se produce el problema. La forma más sencilla de comenzar 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 usar 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 tarde mucho tiempo (50 ms es el umbral de Chrome), tiene un par de opciones:
- Elimina parte / toda esa tarea que puede ser innecesaria
- Descubre cómo hacer la misma tarea más rápido
- Divide el código en múltiples pasos asincrónicos
(1) y (2) pueden ser difíciles o imposibles, pero a veces es realmente fácil y deberían ser tus primeros intentos. Si es necesario, siempre debería ser posible hacer (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 here .