Es raro encontrar un sitio web que no utilice JavaScript. En esta publicación, analizaremos las técnicas de optimización de JavaScript en términos de velocidad de representación del sitio web, así como el rendimiento en sí.
Hoy día la velocidad del sitio web juega un papel fundamental en el posicionamiento web, ya que el impacto de respuesta que se tenga frente a una búsqueda específica de algún usuario representa una de las claves que google impone en sus criterios de posicionamiento.
JavaScript afecta el árbol de renderizado generado. Esto significa que un JavaScript no optimizado puede ralentizar la página y deteriorar significativamente la calidad de la experiencia del usuario, de allí la importancia de la optimización de JavaScript.
“Resulta que buscar una fallo en todo puede llevar a la perfección.”
Contenidos
Extraer scripts JavaScript en archivos separados
Hay muchas ventajas en extraer sus scripts en archivos.js separados. Un solo cambio de la secuencia de comandos en un archivo transfiere los cambios automáticamente a todas las páginas donde existe el archivo. Reduce el tamaño del código HTML que se envía al navegador.
Hay un inconveniente de guardar el script en un archivo externo, para que el navegador lo use, tiene que hacer otra solicitud HTTP y descargarlo como recurso.
No se puede analizar el código hasta que el archivo.js se haya descargado por completo. La representación completa de la página está bloqueada. Si el script no afecta a CSSOM, puede separarlo en un archivo externo y agregar el atributo async, entonces no bloquea la representación.
async
El atributo async le dice al navegador que la secuencia de comandos no afecta el DOM o CSSOM y solo se puede procesar después de que se haya cargado y renderizado toda la página. El atributo async funciona solo para scripts colocados en un archivo separado, por eso es tan importante extraer el script en un archivo externo.
Un ejemplo de dichos scripts que no afectan ni al DOM ni al CSSOM y que pueden separarse fácilmente en archivos separados (o en un solo archivo) utilizando el atributo async son los scripts de herramientas analíticas. La secuencia de comandos que se encuentra, ya sea en el encabezado o en el pie de página, se puede pegar en un archivo externo y el enlace debe colocarse en la página.
<script src=”scripts.js” async> </script>
Debe recordarse que un intento de incluir de esta manera un script JavaScript que cambie la presentación gráfica de la página y manipule los objetos DOM puede causar irregularidades, por ejemplo, un aumento en el índice CLS. Además, no agregue async a los archivos de la biblioteca, porque los scripts que dependen de ellos pueden dejar de funcionar. En las siguientes secciones se describe cómo conciliar async y la secuencia de agregar código dependiente.
Bloqueo de JavaScript
Un JavaScript de bloqueo es un script que debe ejecutarse antes de construir un árbol CSSOM. El script JS bloquea la representación independientemente de si está adjunta como una etiqueta con el atributo src:
<script src=”scripts.js”></script>
…O como un script online.
Script HTML – onlíne
La secuencia de comandos onlíne es un poco mejor en términos de rendimiento porque no envía una solicitud HTTP adicional, no tiene que esperarla. Sin embargo, dicho script también bloquea la representación y no se puede utilizar el atributo async.
<script> function(){ /* algún script */ } </script>
defer
¿Qué pasa con el aplazamiento? El atributo defer funciona exactamente como un script de bloqueo agregado antes de la etiqueta de cierre del cuerpo.
Funciona porque incluso si se adjunta una etiqueta <script> con el atributo src al encabezado, actuará como si se hubiera agregado al pie de página. El atributo defer puede hacer que los scripts colocados más arriba, por ejemplo, en la etiqueta del cuerpo, dependiendo del script al que se haya agregado el aplazamiento, dejen de funcionar.
El defer atributo es un atributo booleano.
Cuando está presente, especifica que el script se ejecuta cuando la página ha terminado de analizarse.
Nota: El atributo defer es solo para scripts externos (solo debe utilizar si el atributo src está presente).
Nota: Hay varias formas de ejecutar un script externo:
- Si async está presente: el script se ejecuta de forma asincrónica con el resto de la página (el script se ejecutará mientras la página continúa el análisis)
- Si async no está presente y defer está presente: el script se ejecuta cuando la página ha terminado de analizarse
- Si ninguno de los dos async o defer está presente: el código se obtiene y se ejecuta INMEDIATAMENTE, antes de que el navegador continúe analizando la página.
Programación asincrónica
Teniendo en cuenta la información anterior, existe una gran tentación de agregar async a todos los scripts y luego “priorizar” el orden de su ejecución de tal manera que las dependencias no se rompan, ¿es posible? Sí, pero luego nos adentramos en lo que se llama programación asincrónica.
¿Cómo conciliar scripts dependientes asíncronos y retrasados?
Basta con retrasar la ejecución de los scripts dependientes hasta que se carguen las bibliotecas cargadas de forma asincrónica. Una de las técnicas más simples es utilizar el método setTimeout (); sin embargo, puede ser poco confiable y el principio de funcionamiento rompe el principio académico de la programación asincrónica, que dice: “No se debe hacer suposiciones sobre el tiempo de un proceso dado“.
Suponiendo que cargamos jQuery y cualquier script que dependa de él, el siguiente mecanismo funcionará para nosotros:
<script src = “jquery.min.js” async> </script><script>setTimeout(function(){ /* algo de código jQuery */}, 5000);</script>
Asumir que jQuery se cargará en 5 segundos es muy poco profesional. Es mejor hacer algo como esto:
<script> var loadLoop = setInterval(function(){ if (window.jQuery) { clearInterval(loadLoop); / * Algún código depende de jQuery * / } }, 100); </script>
Según el consultor SEO, este problema se puede resolver aún mejor con un mecanismo de promesa propietario (promise) o la biblioteca require.js
Biblioteca Require.js
La biblioteca optimizará la carga de las bibliotecas necesarias y también se utiliza en aplicaciones grandes. Solo puede cargar archivos que se necesitan en un momento dado y mantener las dependencias. Aquí hay un ejemplo donde cargamos jQuery y Bootstrap.
Solo cargamos el archivo require.js con el atributo async en la página.
<script data-main=”scripts/main” src=”scripts/require.js” async> </script>
Todo el código JavaScript con dependencias se puede encontrar en scripts /main.js. En este ejemplo, el código dependiente no se ejecuta hasta que se cargan jQuery y su biblioteca Bootstrap dependiente (y se carga la página).
requirejs.config ({ paths: { jquery: “lib/jquery”, bootstrap: “lib/bootstrap.min” }, shim: { bootstrap: { deps: [‘jquery’] } } }); require ([“jquery”, “bootstrap”], function($) { jQuery(document).ready(function() { /* Algunos códigos dependen de jquery.js y bootstrap.js */ }); });
Optimización de archivos JavaScript
Como suele ser el caso con los recursos de texto estático, debido a que la mayoría de las veces los archivos con scripts JavaScript lo son, también podemos usar las técnicas ya aprendidas para comprimirlos y almacenarlos en caché.
Minificación (minimización) de scripts JavaScript
Cualquier recurso de texto se puede minimizar eliminando caracteres redundantes como espacios, tabulaciones, nuevas líneas o incluso bloques enteros de comentarios. El código JavaScript se puede minimizar incluso más que el código HTML o CSS. Tenemos más posibilidades a este respecto debido a las numerosas técnicas de acortamiento de sintaxis. Los nombres de funciones y variables se pueden convertir en equivalentes de una sola letra, lo que no cambiará el significado de las funcionalidades programadas.
Una vez descargado, el archivo.js que contiene el código JavaScript se puede guardar en la caché del navegador, generalmente en el disco local. La próxima vez que una subpágina acceda a este archivo, no tendrá que volver a descargar este archivo ni realizar costosas solicitudes de descarga y HTTP.
El servidor puede enviar un encabezado Cache-Control o Expires, que le dice al navegador que copie el archivo y use la versión sin cambios del archivo durante un período de tiempo específico.
Servidor rápido y CDN
Es una buena práctica consiste en colocar archivos estáticos en un subdominio separado e integrarlos con la red CDN. Los diferentes servidores tienen diferentes “tiempos de respuesta” en el servicio de archivos estáticos, es decir, TTFB, y diferentes anchos de banda y la calidad de la conexión a Internet. Aunque se trata de pequeños archivos de varias docenas o varios cientos de kbytes, puede notar la diferencia cuando cargamos scripts desde un servidor rápido y correctamente optimizado.
Compresión
Los archivos JavaScript son texto y, como sabemos, el texto se puede comprimir utilizando algoritmos de compresión de datos estándar. La compresión realizada en el lado del servidor con módulos como Brotli, GZIP o deflate, es invisible para los usuarios y le permite ahorrar hasta un 80% de transferencia. El módulo Brotli desarrollado por Google, o los módulos deflate o GZIP tradicionales deben instalarse y habilitarse de forma predeterminada en cualquier servidor que sirva archivos JavaScript, así como otros recursos de texto (CSS, XML).
Eliminar el código JavaScript no utilizado
A veces hay scripts JavaScript adjuntos a las páginas que no tienen ninguna función. Pueden ser bibliotecas que se han utilizado en otra subpágina o funcionalidades que se han retirado en actualizaciones posteriores.
Coverage puede analizar JavaScript, exactamente el mismo que usamos para eliminar declaraciones CSS no utilizadas.
Los scripts no utilizados se pueden eliminar por completo o solo se pueden cortar los bloques que no se utilizan en ninguna subpágina.
Optimización del rendimiento del código JavaScript
El código fuente del programa se puede optimizar en términos de rendimiento, es decir, la cantidad de cálculos que debe realizar el procesador. Estas acciones no solo pueden acelerar la carga de la página, sino también ahorrar energía en los dispositivos del cliente. En esta parte, voy a recopilar algunas buenas prácticas y consejos sobre cómo optimizar el código JavaScript de forma universal.
Memorización
La memorización es una técnica de optimización de código universal que registra el resultado de una función o respuesta costosa para argumentos dados.
Caché de solicitudes a servicios externos
Podemos almacenar el contenido de un archivo JSON o XML en una variable temporal si nos referimos a él repetidamente y sabemos que no se cambiará con frecuencia.
Estrangulamiento
Presenté la técnica de estrangulamiento al programar el mecanismo de carga diferida. Consiste en reducir la intensidad de los factores desencadenantes. Con construcciones simples con declaraciones condicionales y setTimeout, puede hacer que el detector de eventos ignore algunos eventos y la funcionalidad seguirá funcionando.
var eventTimeout; var eventThrottler = function () { if ( !eventTimeout ) { eventTimeout = setTimeout(function() { eventTimeout = null; lazyLoad(); }, 1000); }};
Con setTimeout, verificamos el punto de cada segundo y no constantemente.
Usar variables locales y no globales
El uso de variables locales es más eficiente porque reducimos el espacio de nombres. Todas las variables globales forman parte del objeto de ventana, en el que la búsqueda de variables puede llevar un tiempo relativamente largo.
Resumen de Optimización JavaScript
Según programadores web y seos con alto conocimiento, se asegura que vale la pena aprovechar la optimización de la página en términos de JavaScript, porque funcionalidades idénticas implementadas de diferentes formas pueden ralentizar significativamente la página o no afectar su tiempo de carga. Tenemos un amplio abanico de posibilidades, pues así lo afirma Ángel pitarque.
Es muy buen artículo. Estoy teniendo mogollón de problemas con el archivo jquery.min.js
Si lo cargo con delay la velocidad me aumenta, pero no me carga los menús bien en mobile. Hay alguna forma de solucionar eso?
Un cordial saludo