Cómo usar async y defer en WordPress para mejorar la carga de scripts Javascript

En Desarrollo, Tutoriales y Guías, Webmasters por

Hace ya algún tiempo que tenemos entre nosotros la aplicación de Google PageSpeed Insights, que nos da recomendaciones acerca de cómo optimizar nuestras páginas web para que carguen más rápido y para que ofrezcan una mejor experiencia de usuario, tanto en dispositivos móviles como de escritorio. En este artículo vamos a hablar de cómo usar async y defer en WordPress para mejorar la carga de scripts Javascript.

Cómo usar async y defer en WordPress para mejorar la carga de scripts Javascript

Es cierto que optimizar la carga de nuestra página web o blog WordPress es algo fundamental, pero también es cierto que no hay que obsesionarse con obtener una nota de 100/100 en el test Google PageSpeed Insights, en mi opinión, una nota a partir de 85 puede considerarse como correcta. El objetivo de la optimización no debe ser obtener una mejor nota en el test, recordemos que es un test automatizado y puede no darnos siempre unos resultados acertados.

Voy a dividir el artículo en dos partes, una primera parte dedicada a hablar sobre los atributos async y defer, para que tengamos una idea clara de para qué sirven, cuáles son sus diferencias y si uno es mejor que otro. En la segunda parte veremos cómo implementar async y defer en WordPress para mejorar la carga de scripts Javascript (extensión .js).

¿Qué son los atributos async y defer definidos en la etiqueta <script>?

La etiqueta <script> puede definir un recurso externo, por lo que a la hora de parsear el código HTML, el proceso se detiene para hacer la correspondiente petición HTTP al recurso externo. Esto tiene como consecuencia inmediata un incremento del tiempo de carga de la página web.

Para evitar este bloqueo durante el periodo de tiempo en el que se hace la petición HTTP al recurso externo, aparecieron los atributos async y defer que se emplean con la etiqueta <script>. La función de estos dos atributos es forzar la carga del recurso externo de forma asíncrona, es decir que no bloqueará el parseo del HTML.

A continuación dejo unos ejemplos de cómo nos vamos a encontrar la etiqueta <script> en las páginas web:

  • Etiqueta <script> síncrona (bloquea el parseo):
    <script type='text/javascript' src='https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js?ver=4.6.1'></script>
  • Etiqueta <script> asíncrona con defer (no bloquea el parseo):
    <script type='text/javascript' defer src='https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js?ver=4.6.1'></script>
  • Etiqueta <script> asíncrona con async (no bloquea el parseo):
    <script type='text/javascript' async src='https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js?ver=4.6.1'></script>
  • Etiqueta <script> asíncrona con defer y async (no bloquea el parseo):
    <script type='text/javascript' async defer src='https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js?ver=4.6.1'></script>

Diferencias entre async y defer. ¿Cuál es mejor?

Seguramente os estaréis preguntando qué diferencias existen entre async y defer o si uno de los dos atributos es mejor que el otro. Para responder a esta cuestión, primer debemos entender cómo funciona cada uno de los atributos.

El atributo defer fue introducido por Microsoft en Internet Explorer 4 y terminó por adoptarse como estándar de HTML 4. Cuando usamos defer la descarga del recurso externo se realiza durante el parseo del código HTML, pero el recurso sólo se ejecutará cuando haya terminado el parseo.

El atributo async fue introducido en el estándar HTML5 para cargar de forma asíncrona los recursos externos. En el caso de async, el recurso externo se ejecuta justo después de que se termine su descarga.

Diferencias entre async y defer, cual es mejor

También se puede dar el caso de que ambos atributos estén presentes, en este caso async tiene prioridad sobre defer. En el caso de que el navegador no sea compatible con async se empleará defer.
Por todo lo explicado anteriormente, la mejor opción es emplear ambos atributos, así nos aseguramos de mantener la compatibilidad con navegadores antiguos.

Ahora que tenemos esto claro, podemos pasar al segundo apartado para ver cómo podemos implementar async y defer en archivos Javascript de WordPress.

Cómo usar async y defer en WordPress para mejorar la carga de scripts Javascript.

Desde la versión de WordPress 4.1 dispone de un nuevo filtro que permite añadir los atributos async y defer con poco esfuerzo. Cuando se agrega un script en WordPress, se suele emplear un código similar a:

function wpdocs_theme_name_scripts() {
	wp_enqueue_script( 'script-name', get_template_directory_uri() . '/js/example.js', array(), '1.0.0', true );
	wp_enqueue_script( 'script-name2', get_template_directory_uri() . '/js/example2.js', array(), '1.0.0', true );
}
add_action( 'wp_enqueue_scripts', 'wpdocs_theme_name_scripts' );

Este código lo encontramos en el archivo functions.php del tema WordPress, pero el problema es que de este modo lo estamos agregando de forma sincrónica y bloquea el parseo. La solución es emplear el filtro script_loader_tag cuya documentación oficial podemos ver en este enlace.

Para ello debemos agregar el siguiente código al archivo functions.php:

function add_async_attribute($tag, $handle) {
   // agregar los handles de los scripts en el array
   $scripts_to_async = array('script-name', 'script-name2');
   
   foreach($scripts_to_async as $async_script) {
      if ($async_script === $handle) {
         return str_replace(' src', ' async defer src', $tag);
      }
   }
   return $tag;
}
add_filter('script_loader_tag', 'add_async_attribute', 10, 2);

A la hora de agregar los handlers debemos fijarnos en los nombres que se usan a la hora de agregar los scripts para después agregarlos en nuestra función (en el código de ejemplo anterior vemos que los handlers son script-name y script-name2).

A veces los archivos Javascript son agregados por los plugins y puede ser necesario buscar el nombre de sus handlers para agregarlos al código.

Ya sólo nos queda limpiar el cache y recargar la página para poder comprobar como ahora los scripts incorporan las etiquetas async y defer. Con este pequeño tutorial de cómo usar async y defer habremos optimizado un poco más la carga de nuestra página web o blog WordPress.