Etiqueta: performance

  • Agrega un evento en múltiples elementos con event delegation

    Agrega un evento en múltiples elementos con event delegation

    En este post hablaremos sobre event delegation, en JavaScript. La solución a tus problemas de performance y escalabilidad en tu proyecto actual, donde tal vez tengas una tabla de usuarios.

    Cada usuario tiene los botones de editar o eliminar. Sin embargo, estás haciendo un loop para asignarles un evento click para hacer sus respectivas funciones.

    Esto soluciona tu requerimiento, pero, si tienes más de 1000 usuarios en esa tabla, ¿será bueno en performance? y mejor aún, ¿será escalable?

    ¿Qué es event delegation?

    El event delegation es un patrón en JavaScript que sugiere registrar un evento, por ejemplo, click, en nuestro document para interceptar todas las interacciones de nuestro documento.

    Es decir, si haces click en un botón, lo estás escuchando, y si haces click fuera del botón, también lo estás escuchando.

    ¿Suena ilógico no? ¿Por qué queremos escuchar todos los clicks de todo nuestro sitio web si solo podemos asignarle el evento a los elementos a través de un loop?

    Lo mismo pensé cuando escuché sobre esto la primera vez, pero cuando piensas en el performance y escalabilidad, empieza a cobrar sentido.

    ¿Cómo funciona event delegation?

    El truco está en que dentro de la función callback de nuestro evento, hay que usar el objeto event.target.

    document.addEventListener('click', () => {
       const clickedElement = event.target;
    });

    En nuestro ejemplo, event.target es equivalente al elemento que hemos hecho click, el botón, en este caso.

    Por otra parte, si haces click afuera del botón, el evento también se ejecutará. Es ahí donde tienes que agregar las condiciones necesarias para que el evento solo responda a los botones y no a todo el contenido del sitio.

    Funciones como matches() o closest() se usan mucho cuando se está trabajando con event delegation.

    Antes de event delegation, se usaba un loop

    Retomemos el ejemplo del primer párrafo. Tenemos la tabla de 1000 usuarios, y cada uno de ellos tiene un botón para editar; digamos que al hacer click a ese botón, se abre un modal con los datos del usuario para editar.

    Lo que yo solía hacer para abrir ese modal, es agregar un evento click a cada uno de los botones con la siguiente lógica:

    1. Obtener los botones.
    2. Pasar por un loop los botones.
    3. Asignar un evento a cada uno de los botones pasados en el loop.

    Observa el siguiente demo. Utilizo un forEach para hacer un loop de los elementos y asignarles el evento; también puedes usar for y for ... in. La funcionalidad es la misma.

    Si bien el código anterior funciona. ¿Qué es lo que lo hace incorrecto?

    Problema #1: Performance

    El performance es algo que debes incluir en tus desarrollos web. Es muy medido por Google y sus Core Web Vitals, además, un buen performance asegura una mejor experiencia para el usuario.

    Si tenemos 1000 usuarios y por cada uno podría haber dos botones, editar y eliminar, eso hace que nuestro sistema tenga 2 mil botones en total. Imagina agregar otro botón más.

    Ahora, con nuestro sistema actual tendría que hacer loop y agregar los eventos a esos 2 mil botones; y eso, no es para nada saludable para el sitio y navegador web. ¿Diría que incluso podría saturar el navegador?

    Otra técnica para un buen performance es ejecutar tu código solo en donde sea necesario.

    Problema #2: Escalabilidad

    Tu cliente quiere agregar usuarios en esa misma tabla usando AJAX. Se puede, sí; sin embargo, ¿nuestros botones de editar funcionarán después de agregar al usuario?

    Seguramente no funcionará porque, previamente, has agregado los eventos a los botones existentes, no a los nuevos.

    Uno piensa, ¡ah! pues después de crear el usuario, busco los nuevos botones y les asigno el evento. Si y no. Esto solo genera complejidad y duplicidad de código. No es escalable.

    Conclusión

    Debemos acostumbrarnos al uso del event delegation, pero siempre analiza si este tipo de patrón es el adecuado para los requerimientos de tu proyecto.

    Ya no podemos usar las viejas formas en las que programábamos con JavaScript. Tenemos que actualizar nuestro código para hacer el uso de la web más satisfactoria para los usuarios.

  • Ejecuta código solo donde sea necesario en WordPress

    Ejecuta código solo donde sea necesario en WordPress

    Cuando estamos desarrollando un sitio web, ya sea con WordPress o una página web sencilla es clásico cargar todo nuestro código PHP, JavaScript y CSS a la vez en todas las páginas del sitio web.

    Como la mayoría de los sitios web están construidos en WordPress, es donde nos enfocaremos ya que muchos desarrolladores desarrollan temas y/o plugins para esta plataforma y no siempre piensan en el performance de su código.

    ¿En qué afecta cargar código innecesario?

    Bien, cuando ejecutas código PHP, JavaScript y CSS en una página estás usando CPU, memoria RAM, entre otros recursos de tu servidor y al final eso se traduce en un costo monetario para tu cliente.

    Entre más recursos ocupes, tu sitio web podría presentar estos problemas:

    • La carga de tu sitio web será muy lenta (A no ser que tu servidor sea escalable y esté bien configurado).
    • Perderás usuarios y dinero si tu sitio web es lento.
    • Para servidores en la nube no bien administrados, puede generar un costo alto.
    • Kilobytes o Megabytes cargados innecesariamente.
    • Puntajes malos en PageSpeed Insights.

    WordPress siempre cargará los archivos PHP, CSS y JavaScript del tema y plugins activos, así que entre más plugins activos tengas, más recursos usará tu servidor.

    Identifica JavaScript y CSS innecesarios

    Un código innecesario puede existir en un archivo de PHP, JavaScript y CSS, y podemos identificarlo de las siguientes formas:

    Network

    Firefox y Google Chrome (u otro navegador) tienen una opción llamada Network o Red donde puedes ver los archivos JavaScript y CSS cargados en la página que estás visitando actualmente.

    Pestaña de Network o Red mostrando los archivos JS y CSS cargados en la página actual.
    Pestaña de Network o Red mostrando los archivos JS y CSS cargados en la página actual.

    ¿Ves un archivo que no pertenece a la página actual que estás visitando? Probablemente no está siendo cargado adecuadamente.

    Coverage

    Google Chrome tiene una opción llamada Coverage la cual permite encontrar el código JavaScript y CSS usado y no usado en la página que quieras analizar.

    ¿No sabes cómo usar el Coverage? He creado un video sobre cómo utilizar el Coverage en Google Chrome:

    WebPageTest

    Este servicio para analizar el performance de tu sitio web hace algo similar que la opción Network, te mostrará los recursos cargados desde que inicia y termina tu sitio web.

    WebPageTest mostrando los recursos cargados en la página actual.
    WebPageTest mostrando los recursos cargados en la página actual.

    ¿Cómo cargar mal un recurso?

    Los archivos CSS y JavaScript comúnmente son cargados usando las funciones wp_enqueue_style() y wp_enqueue_script(); mientras que un código PHP se puede ejecutar dentro de action y filter hooks y en el dashboard de WordPress o en el frontend.

    Un ejemplo es el siguiente código, donde estamos cargando el script wp-countup-show-counter.min.js en el frontend:

    <?php
    
    add_action( 'wp_enqueue_scripts', 'rmr_load_assets' );
    
    function rmr_load_assets() {
       wp_enqueue_script(
         'wp-countup-js-plugin',
         WP_COUNTUP_JS_URL . 'assets/js/wp-countup-show-counter.min.js',
         array( 'jquery' ),
         WP_COUNTUP_JS_VERSION,
         $in_footer
       );
    }

    El problema del código es que está cargando el script en todas las páginas de tu sitio web pero tu sólo estás usando el script, digamos que, en la página /contact. ¿No tiene sentido que cargues tu script en todas las páginas, verdad?

    ¿Cómo cargar bien un recurso?

    Retomando el ejemplo anterior, queremos que el script wp-countup-show-counter.min.js solo se ejecute en la página /contact. Para eso solo tenemos que agregar una condición de guardia donde si la página actual no es /contact entonces no cargues el script:

    <?php
    
    add_action( 'wp_enqueue_scripts', 'rmr_load_assets' );
    
    function rmr_load_assets() {
      if ( ! is_page( 'contact' ) ) {
        return;
      }
    
      wp_enqueue_script(
         'wp-countup-js-plugin',
         WP_COUNTUP_JS_URL . 'assets/js/wp-countup-show-counter.min.js',
         array( 'jquery' ),
         WP_COUNTUP_JS_VERSION,
         $in_footer
      );
    }

    Pueden existir múltiples condiciones para cargar un script o estilo, en el ejemplo anterior utilizamos una página como condición pero también puedes usar:

    Desactiva código JavaScript y CSS en tu WordPress

    Ya que hayas identificado el código innecesario en tu WordPress, es hora de desactivarlos. Para eso, WordPress te provee dos funciones wp_dequeue_script() y wp_dequeue_style() para desactivar los scripts y estilos registrados.

    Esta sección merece su propio post y lo puedes leer en el siguiente enlace.

    Y ten en cuenta que lo explicado en este post lo puedes aplicar para cualquier sitio web, incluso si no está hecho en WordPress.

    Espero hayas aprendido y apliques los conocimientos que aquí he plasmado, si lo haces, podrás darle a tus sitios web más performance para que tus usuarios tengan una buena experiencia.

    Si tienes alguna duda y/o comentario puedes dejarlo en los comentarios.

  • Desactiva código JavaScript y CSS en tu WordPress

    Desactiva código JavaScript y CSS en tu WordPress

    Nuestros sitios web hechos en WordPress contienen plugins desarrollados por terceros que cargan código JavaScript y CSS desde archivos.

    Hay veces que necesitamos desactivar esos archivos para mejorar el performance de nuestro sitio web.

    Existen dos formas de usar el código JavaScript y CSS:

    1. Usando archivos .js y .css. Recomendado.
    2. Incrustándolos directo en el template de nuestro tema. No recomendado.

    Inline Scripts/Styles. No recomendado

    El código JavaScript y CSS puede incrustarse dentro de un template, por ejemplo, dentro de tu archivo header.php, footer.php, etc.

    Lo puedes hacer, sí, pero no es recomendable ya que no será escalable y se te hará muy difícil identificar el código dentro de tus templates.

    window.codeBlockPro = {"pluginUrl":"https:\/\/roelmagdaleno.com\/wp-content\/plugins\/code-block-pro\/"};