No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Optimización del Rendimiento Web: Identificación y Solución de Cuellos de Botella

18/22
Recursos

¿Cómo medir el rendimiento de un proyecto web?

Medir el rendimiento de un proyecto es crucial para asegurar que los usuarios disfruten de la mejor experiencia posible. Esto implica garantizar que una página web cargue de manera eficiente, responda a las interacciones de usuario y ofrezca animaciones fluidas. Un mal rendimiento puede provocar tiempos de carga lentos, animaciones entrecortadas y una interacción no fluida, lo que lleva a una experiencia de usuario negativa. En esta sección, exploramos cómo identificar y resolver cuellos de botella en el rendimiento de una página web utilizando herramientas de desarrollo.

¿Cómo identificar cuellos de botella en el rendimiento?

Para abordar los problemas de rendimiento, primero debemos identificarlos correctamente. Los principales pasos para detectar cuellos de botella son:

  1. Acceder al "inspector de elementos" del navegador y utilizar la pestaña "Performance". Esta herramienta nos permite grabar la actividad de la página, mostrando tiempos de carga, llamadas de scripts y más.

  2. Reducir la velocidad del CPU a través del navegador para simular dispositivos menos potentes. Esto es vital, ya que muchos usuarios no cuentan con dispositivos de alta gama.

  3. Realizar interacciones en la página para simular una carga pesada, como hacer varios clics para generar elementos y observar el comportamiento.

  4. Grabar la actividad de la página y analizar el reporte generado, focalizándose en las líneas rojas y en los "frames per second" o FPS, que indican problemas cuando hay sobrecarga.

¿Qué nos indica el análisis del CPU?

El análisis del CPU proporciona información sobre cómo se está utilizando el poder de cálculo del dispositivo:

  • Colores en el CPU: Cada color representa un tipo diferente de tarea.
    • Amarillo: Scripts delanteros y tiempo de ejecución.
    • Púrpura: Tareas de renderizado que consumen mucho tiempo.
    • Verde: Tareas rápidas, como "Paint".
    • Azul: Animaciones y otros eventos.

Un alto consumo en el CPU, especialmente por tareas de render y scripts, sugiere que estos son los principales cuellos de botella.

¿Cómo interpretar el renderizado y los frames?

Los frames, o cuadros por segundo, son esenciales para determinar la suavidad de las animaciones:

  • Frames por segundo (FPS): Un buen rendimiento se espera en sesenta FPS. Si el valor es menor (como seis FPS observados en el ejemplo), la animación será lenta y entrecortada.

  • Main Thread Analysis: Nos muestra las tareas individuales necesarias para un renderizado completo. Las tareas que demoran más tiempo se convierten en cuellos de botella.

¿Cómo optimizar y depurar el código?

Una vez identificados los cuellos de botella, es hora de optimizar y depurar el código:

  • Identificar líneas de código que tardan más en ejecutarse, marcadas frecuentemente por advertencias triangulares rojas.

  • Utilizar breakpoints para depurar el código. Esto permite inspeccionar detalladamente las líneas problemáticas y ver su ejecución paso a paso.

  • Revisar documentación adicional para entender qué áreas pueden mejorar y qué cambios son necesarios para optimizar el rendimiento final de la animación.

Cada línea y script dentro de nuestro proyecto debe ser revisada con cuidado para determinar si es un contribuyente significativo a los problemas de rendimiento. Con la práctica y las herramientas correctas, podemos resolver estos problemas y ofrecer una experiencia de usuario fluida y eficiente.

Estas prácticas no sólo nos ayudan a mejorar la calidad de nuestros proyectos, sino que nos posicionan como profesionales sólidos en el campo del desarrollo web ¡Sigue adelante, siempre hay algo nuevo por aprender y dominar!

Aportes 42

Preguntas 4

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Sad, mi computadora sin throttling ya funcionaba como la del profe con throttling

Conclusión sobre el reto
Bueno según lo que he podido investigar (corregidme si estoy equivocado) es que el problema esta en la forma en que obtiene una nueva posición para el elemento.

Algoritmo no optimizado

var pos = m.classList.contains('down') ? m.offsetTop + distance : m.offsetTop - distance;

Aquí podemos observar que obtiene la posición del elemento con respecto al contenedor más cercano en posición relativa (en este caso body) y esto lo hace para cada iteración y cada elemento teniendo que cada vez volver a consultar esa posición para generar una nueva.

Algoritmo optimizado

var pos = parseInt(m.style.top.slice(0, m.style.top.indexOf('px')));
m.classList.contains('down') ? pos += distance : pos -= distance;

Aquí para obtener la posición lee el estilo top anterior del elemento y a partir de ese genera una nueva posición.

La diferencia es que el primer algoritmo (offsetTop) consume mucho más recursos ya que debe consultar del DOM en cada iteración (es una nueva operación para cada elemento y cada iteración), mientras que con el segundo algoritmo (style.top) solamente consulta la posición anterior del estilo almacenado (no debe hacer una nueva operación).

Si estoy equivocado por favor corregidme.

Mi PC anda como una calculadora Casio

Vale, en cuanto al reto creo que logré encontrar por qué no está optimizado. Independientemente de que se está llamando a la propiedad “offsetTop” dentro de un if en varias ocaciones (Esto no es buena práctica, pues por cada vez que se llama, el navegador tiene que ir a recalcular el valor de esa propiedad, lo mejor es guardar su valor en una variable), esta propiedad parece tener un problema de performance, porque incluso, si al código optimizado, le pones esa propiedad, la animación seguirá lenta, en cambio, si obtienes el valor directamente de los estilos es cuando se logra optimizar 🤔

que curso tan genial

Creo que lo solucione, en la línea 65 (Dado que la línea que marca el Performace es la 95 que llama a la función app.update en la línea 62)

Hay un condicional que dice:
if (!app.optimize) y en la línea 32: optimize = false; al borrar el negar (!) se optimiza. profesor estoy en lo correcto?

lo que hice fue desactivar el optimizar en la linea 65
le quite el ! jajaj xd solucionado quedo
if (!app.optimize)
if (app.optimize)

Solución al reto:

En cada iteracion, dentro de los if se trae el valor que esta dentro m que es un objeto para compararlo. Seria mas rapido trabajar con un valor que no este dentro de un objeto, pos:

var pos = parseInt(m.style.top.slice(0, m.style.top.indexOf('px')));
m.classList.contains('down') ? pos += distance : pos -= distance;

m.style.top es un string que contiene el numero+px por eso es neceario guardarlo sin el px y pasarlo a un numero entero. Y se le suma o resta distance dependiendo de si esta subiendo o bajando.

Si ya no esta disponible: https://web.archive.org/web/20200721205417/https://googlechrome.github.io/devtools-samples/jank/

Con dev tools le quitan el ancabezado para que no estorbe, usando display:none

Para cuando ya no esta disponible un recurso, pueden usar https://web.archive.org/ para encontrar versiones guardadas de sitios caidos.

La solución que he encontrado es eliminar el if de la línea 65 de tal manera que se ejecute siempre el else:

var pos = parseInt(m.style.top.slice(0, m.style.top.indexOf('px')));
        m.classList.contains('down') ? pos += distance : pos -= distance;
        if (pos < 0) pos = 0;
        if (pos > maxHeight) pos = maxHeight;
        m.style.top = pos + 'px';
        if (pos === 0) {
          m.classList.remove('up');
          m.classList.add('down');
        }
        if (pos === maxHeight) {
          m.classList.remove('down');
          m.classList.add('up');
        }

Mi Intel Core 2 Duo sufrio mucho jajaja

Recuerden: Es una buena practica generar 60 fps (frame por segundo)

TIP: Revisen la función que se lanza al hacer click en el botón de optimize.

En realidad, a lo que hace referencia Idle es el tiempo muerto, donde ya la página terminó de realizar todos los pasos anteriores. Una página bien optimizada tendrá un Idle mucho más grande en relación a los otros parámetros en la pestaña de Summary. Lo he probado en varias páginas, y he visto que puede ser hasta más de un 95% mayor que el resto de los parámetros.

<h3>18. ¿Cuándo utilizar la sección de Performance?</h3>

11:46 Reto de la clase.

Enlaces de la clase:
Get Started With Analyzing Runtime Performance
Enlaces complementarios:
Tutorial ¡Aprende a optimizar tus sitios web! - Resolviendo el reto de la clase de optimización de RetaxMaster
Comentarios valiosos de la comunidad: 1

para poder solucionar el reto de la optimaizacion de condigo vamos a la línea 66 sustituimos la propiedad offsetTop debido a que esta crea una gran carga de js por cada elemento calculado en el viewport y debemos reemplazar estos por css en js osea empezar a usar cssom

/*
• El método slice() devuelve una copia de una parte del array dentro de un nuevo array 
empezando por inicio hasta fin

• El método indexOf() retorna el primer índice en el que se puede encontrar un elemento dado en el array

recordemos también  que las pantallas  cargan desde arriba hacia abajo

⬇️ 0px, origen
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
|                                                                |
|                                                                |
|                                                                |
|                                                                |
|                                                                |
|                                                                |
|                                                                |
|                            maxHeight    ⬇️        |
|_ _ _ _ _ __ _ _ _ _ _ _ _ _ _ _ _ _ _ _|    
                                                                      
*/

var posicionElement = parseInt(m.style.top.slice(0 ,m.style.top.indexOf('px')));

m.classList.contains('down') ? posicionElement  += distance : posicionElement -= distance ;

if(posicionElement < 0)
{
  posicionElement = 0;
}
if(posicionElement  > maxHeight)
{
  posicionElement = maxHeight;
}

m.style.top = posicionElement + 'px';

if (posicionElement === 0)
{
  m.classList.remove('up');
  m.classList.add('down');
}
if (posicionElement === maxHeight)
{
  m.classList.remove('down');
  m.classList.add('up');
}

desde aquí pueden descargar el repo para hacer las pruebas offline

https://github.com/GoogleChrome/devtools-samples

A seguir aprendiendo.

Excelente Clase, mucho por aprender

Leyendo los comentarios, el código y los dos artículos recomendados se realiza este cambio. y listo flujo arreglado.

//En la zona del JS

  app.optimize = true;
  app.count = minimum;
  app.enableApp = true;
// en la parte del css
body {
  height: 100vh;
  width: 100px;
}

Analizando el reto, encontré que una parte importante del rendimiento está relacionada con el uso de `.offsetTop` y `style.top` para animar elementos. Aunque `.offsetTop` permite obtener la posición vertical de un elemento, su uso frecuente dentro de un ciclo de animación (`requestAnimationFrame`) puede ser muy costoso: * **Fuerza reflow**: Cada lectura y escritura puede hacer que el navegador recalcule posiciones. * **Afectan el layout**: Cambiar `style.top` altera el flujo del documento. * **Repaint frecuente**: Se repinta el elemento en cada frame. Como alternativa optimizada, existe la posibilidad de usar `transform: translateY(...)`, que permite mover elementos visualmente sin afectar el layout general del documento. * **No causa reflow**: No afecta el layout general del DOM. * **Evita repaints innecesarios**: Solo se transforma visualmente. * **GPU acceleration**: Las transformaciones se procesan en la GPU. * **Más suave y eficiente**: Ideal para animaciones con `requestAnimationFrame`.
El script que no esta optimizado para calcular la posición actual del elemento que va a mover usa m.offsetTop lo que fuerza a Js a calcular la posición de cada elemento cuando lo va a mover. La solución optimizada cuando va a actulizar la posición para moverlos, toma la posición del elemento de sus propiedades CSS lo que hace que sea un valor fijo el cual solo se debe leer para obtener su valor. ![](https://static.platzi.com/media/user_upload/image-1951fda2-8567-4265-8bfe-9c78eab2c890.jpg)

Soy el único que no entendió como se solucionaba el reto 🙄🤨 no lo creo… PLEH
Solo entiendo que para que esté optimizado debe cambiarse el

var pos = m.classList.contains('down') ?
            m.offsetTop + distance : m.offsetTop - distance;

por:

var pos = parseInt(m.style.top.slice(0, m.style.top.indexOf('px')));
        m.classList.contains('down') ? pos += distance : pos -= distance;

y el m.offsetTop por el “pos”:
pero no sé porque! 😥, lo único que conozco de javascript lo he aprendido del curso básico de javascript y este… 😦 soy yo o la complejidad del desafío 🤔

Reto resuelto. Te fijaste en los dos bloques de código en la función de app.update?
.
Estas son:

.
Ambas son casi iguales, a excepción de esta línea:
.
.

.
la variable “pos” está definida por el bloque que niega a app.optimize en base a m.offsetTop +/- distance, con la validación si m (el elemento que se mueve) tiene la clase ‘down’.
.
La propiedad offsetTop se refiere a la posición en el eje block en px que separa al elemento con su contenedor padre, según la w3schools.
.
Ahora bien, si vemos la definición de la variable pos en el bloque del else, se basa en el valor obtenido por un random number multiplicado por height, que es top:
.

.
Y en el bloque del else propiamente, a ‘pos’ se le define como el valor de top definido al principio y no se toma el offsetTop para el cálculo del largo del eje block consultado en el DOM.
.
Ahora después de que leiste todo esto sin saber exactamente para qué servía o cual era el fin…
Resulta que para redefinir la altura, con offsetTop la función debe hacerle una consulta al DOM para conocer ese valor, por ello debe esperar a que complete (cosa que se acumula en el Call Stack), y así luego modificar la magnitud del atributo .top de cada elemento que se mueve. Cosa que no sucede para el segundo bloque donde se toma directamente el top definido más arriba.
.
Ahora que ya sabes por qué sucede, puede entender por qué hay que dejar el valor del atributo .optimize en verdadero y no en falso, así las distancias se calcularán sin consultas al DOM adicionales, te preparas unos pastelitos, te arropas en tu camita y duermes, pues… Una siestecilla (el acento español es opcional)

Buena clase la verdad, ni sabia esto de las velocidades que se pueden emplear en el codigo de JS. Ahora acabo de cumplir el reto del profe el cual era quitar el signo de negacion del JS linea 65 y ahora me corre sin ningun problema.

0.68 ms (mili segundos) o 68 µs (micro segundos) 🤓

Creo que se refiere a que hay Menos frames por segundo, yo lo entiendo como que entre más frames ( cuadros ) por segundo hay en un clíp el movimiento debería ser más fluido no ? 🤔 pero tal vés será mas tipo cámara lenta ( pero fluido ) jajaajaj

1° Hice click en el link que aparece en MAIN, casilla morada con una esquina triangular roja, me llevo a la línea de código que era parte del optimizador.

2° Encontré que el código de “if(!app.optimize)” es lo que lee cuando NO esta optimizado y el “else” es el código optimizado.
3° Compare las líneas de código (las cuales ya describieron su función muchos).
4° Puse como comentarios algunas líneas de código del “If” que eran distintas a las del “else” .
5° Finalmente copie y pegue las líneas del “else” que optimizaban el código, en el “if” y funcionó.

Bastante interesante esta clase

Es claro que la optimización del código está en cambiar la forma en la que se obtiene la posición top de la imáge, pero no me queda claro por qué una es mejor que otra:


var pos = parseInt(m.style.top.slice(0, m.style.top.indexOf('px')));

// mejor qué


var pos = m.classList.contains('down') ?
            m.offsetTop + distance : m.offsetTop - distance;

Caution: This tutorial is based on Chrome 59. If you use another version of Chrome, the UI and features of DevTools may be different. Check chrome://help to see what version of Chrome you’re running.

ya decía pq no me corre igual. o simplemente mi pc apesta, reto no completado, ya me reventare la cabeza con proyectos

Muy util para juegos basados en java o web

Excelente clase sobre performance, me doy que es muy necesario tenerlo en cuenta en los desarrollos para realizar código mas óptimo y con mayor rendimiento

Qué brillante herramienta!

Me sale todo lo que a él pero no me sale el link a javascript ¿cómo le hago para que salga?

Supo un par de cajitas y arranca la refrigeración de mi laptop a todo lo que da jajaja
Pobre, no hace falta que le ponga mas bajo el rendimiento.

Cómo tomar un screenshot del performance de tu proyecto

Primero ubicas en la barra de color verde el segmento
use el selector de elementos Ctrl+Shift+C en DevTools y haga haz en la mini captura de pantalla en la parte inferior de la ventana principal de DevTools . Entonces DevTools te mostrará el elemento <img> en el árbol de elementos, click derecho en sus datos: image/png y lo abres en el panel de aplicaciones, guardas y listo.

👌

podrias guardar el proyecto web en un repositorio
me refiero a este : https://googlechrome.github.io/devtools-samples/jank/

Para el desafío busqué en los Event Listeners Breakpoints que solicitaran una animación y siguiendo paso a paso llegamos a la parte donde cambia el código si está o no habilitada la opción de optimizar

Hay que aceptar que estoy en ese punto de la curva del (Desconocimiento: No sabes lo que no sabes) estoy muy motivado viendo las clases tratando de entender, ya vi el básico de JavaScript, pero estoy ahi tratando de leer en chino el codigo, no me voy a desmotivar pero me parece que estoy bastante lejos, reviso el inspector y no entiendo como enlazar el html y el css con Js, habra cursos mas basicos para eso ?

Comente la parte del if que le bajaba el rendimiento y eso fue todo

Para Resolverlo elimine el if para que siempre este optimizado