JavaScript
Introducción
JavaScript ha avanzado mucho desde su origen humilde hasta ser considerado el tercer pilar de la web junto con CSS y HTML. Hoy en día, JavaScript ha comenzado a invadir un amplio espectro del stack técnico. JavaScript ya no se encuentra limitado al lado del cliente y se ha convertido en una elección cada vez más popular para crear herramientas de construcción y scripting del lado del servidor. JavaScript también se ha adentrado en la capa de CDN gracias a soluciones de edge computing.
Los desarrolladores amamos usar JavaScript. De acuerdo con el capítulo de marcado, el elemento script
es el 6to elemento de HTML más popular en uso (por delante de elementos tales como p
e i
entre muchos otros). Utilizamos más de 14 veces más bytes de JavaScript de los que usamos de HTML, los bloques para construir la web, y 6 veces más bytes que los que usamos de CSS.
Pero nada es gratis y esto aplica especialmente para JavaScript. Todo ese código tiene un costo. Veamos con más detalle cuánto código usamos, cómo lo usamos y cuáles son los efectos secundarios de este.
¿Cuánto JavaScript usamos?
Mencionamos que la etiqueta script
es el 6to elemento de HTML más usado. Entremos más en detalle para ver cuánto JavaScript está contenido ahí.
Un sitio ubicado en la mediana (percentil 50) envía 444 KB de JavaScript al ser cargado en un dispositivo de escritorio y un poco menos que eso (411 KB) a un dispositivo móvil.
Es un poco decepcionante no ver una mayor diferencia. Si bien es peligroso hacer muchas suposiciones sobre la red o el poder de procesamiento basados en si el dispositivo es un teléfono o una computadora de escritorio (o algo intermedio), debemos recalcar que las pruebas en móviles del HTTP Archive son hechas emulando un Moto G4 en una red 3G. En otras palabras, si existiese algún trabajo para adaptarse a condiciones no ideales y transmitir menos código estas pruebas deberían demostrarlo.
La tendencia parece estar a favor de usar más JavaScript, no menos. Comparando con los resultados del año pasado, vemos un incremento de 13.4% en la mediana de JavaScript al probar en un dispositivo de escritorio y un incremento de 14.4% en la cantidad de JavaScript enviado a un dispositivo móvil.
Cliente | 2019 | 2020 | Cambio |
---|---|---|---|
Escritorio | 391 | 444 | 13.4% |
Móvil | 359 | 411 | 14.4% |
Al menos parte de este tamaño parece ser innecesario. Si vemos un desglose de cuanto JavaScript no es usado al cargar una página, podemos ver que una página ubicada en la mediana transmite 152 KB de JavaScript que no es usado. Este número sube a 334 KB en el percentil 75 y a 567 KB en el percentil 90.
Los números sin procesar pueden o no saltar a tu vista dependiendo de que tan aficionado seas a optimizar el desempeño, pero al verlo como un porcentaje del total de JavaScript usado en cada página, se vuelve un poco más fácil ver que tanto código extra se está enviando.
Esos 153 KB equivalen a alrededor de 37% del tamaño total del código que le enviamos a los dispositivos móviles. Esto definitivamente puede mejorar.
module
y nomodule
Un mecanismo que tenemos que tiene el potencial de reducir la cantidad de código que enviamos es utilizar el patrón module
/nomodule
. Con este patrón, creamos dos bundles: uno para navegadores modernos y otro para navegadores legacy. Al bundle para navegadores modernos se le asigna type=module
y al bundle para navegadores legacy se le asigna type=nomodule
.
Esta estrategia nos permite crear bundles más pequeños utilizando sintaxis moderna optimizada para los browsers que son compatibles, mientras tanto, también proveemos polyfills cargados condicionalmente y una sintaxis diferente para los que no son compatibles.
La compatibilidad con module
y nomodule
va en aumento pero aún es una estrategia relativamente nueva. Como resultado, la adopción aún es baja. Sólo 3.6% de las páginas móviles usa al menos un script con type=module
y sólo 0.7% de las páginas móviles usa al menos un script con type=nomodule
para ser compatible con navegadores legacy.
Conteo de peticiones
Otra manera de ver cuánto JavaScript usamos es explorar cuantas peticiones de JavaScript son hechas por página. Reducir el número de peticiones era fundamental para tener un buen desempeño usando HTTP/1.1, sin embargo, con HTTP/2 aplica lo contrario: dividir el código en JavaScript en archivos individuales y más pequeños resulta en un mejor desempeño en general.
En la mediana, las páginas hacen 20 peticiones de JavaScript. Esto es un incremento menor con respecto al año pasado cuando una página en la mediana hacía 19 peticiones de JavaScript.
¿De dónde viene el incremento?
Una tendencia que posiblemente contribuye al incremento en la cantidad de JavaScript usado en nuestras páginas es la cantidad cada vez mayor de scripts de terceros que son añadidos a las páginas para ayudar con cosas desde pruebas A/B en el lado del cliente y análiticos hasta commerciales y personalización.
Veamos esto más a detalle para ver cuantos scripts de terceros estamos enviando.
Justo hasta la mediana, los sitios envían aproximadamente la misma cantidad de scripts propios que de terceros. En la mediana, 9 scripts por página son propios y 10 son de terceros. Desde ese punto, la diferencia crece un poco: mientras más scripts envía un sitio en total, es mayor la probabilidad de que la mayoría de esos scripts sean de terceros.
Si bien la cantidad de peticiones de JavaScript es similar en la mediana, el tamaño real de esos scripts está cargado hacia los scripts de terceros. Un sitio en la mediana envía 267 KB de JavaScript de terceros a dispositivos de escritorio, comparado a 147 KB de scripts propios. La situación es similar en móviles, donde un sitio en la mediana envía 255 KB de scripts de terceros contra 134 KB de scripts propios.
¿Cómo cargamos JavaScript?
La manera en la que cargamos JavaScript tiene un impacto significativo en la experiencia en general.
JavaScript bloquea al analizador sintáctico por defecto. En otras palabras, cuando el navegador encuentra un elemento script
, debe pausar el análisis del HTML hasta que el script haya sido descargado, analizado y ejecutado. Esto es un cuello de botella significativo y es una causa común de que las páginas se muestren lentamente.
Podemos comenzar a compensar el costo de cargar JavaScript haciendo que los scripts se descarguen asíncronamente (usando el atributo async
), este atributo sólo detiene el analizador de HTML durante las fases de análisis y ejecución de JavaScript y no durante la de descarga, o diferidamente (usando el atributo defer
), este atributo no detiene al analizador de HTML nunca. Ambos atributos sólo pueden aplicarse a scripts externos, no se pueden aplicar a scripts inline.
En móviles, los scripts externos representan el 59.0% de todos los scripts encontrados.
Como nota, cuando hablamos anteriormente acerca de cuánto JavaScript es cargado en una página, ese total no tomaba en cuenta el tamaño de los scripts inline. Debido a que son parte del documento HTML, se cuentan como parte del tamaño de marcado. Esto significa que cargamos aún más scripts de lo que los números muestran.
De los scripts externos, sólo el 12.2% son cargados con el atributo async
y 6.0% son cargados con el atributo defer
.
Tomando en consideración que defer
provee el mejor desempeño al cargar (ya que se asegura que la descarga del script ocurre en paralelo a otras tareas y la ejecución se realiza hasta después de que la página pueda ser mostrada), desearíamos que el porcentaje de uso fuera mayor. De hecho, el 6.0% anterior está un poco inflado.
Cuando el soporte para IE8 e IE9 era más común, era relativamente común usar ambos atributos. Cuando ambos están presentes, cualquier navegador que soporte ambos usará async
. IE8 e IE9 no soportan async
entonces usarán defer
.
En días recientes, este patrón no es necesario para la mayoría de los sitios y cualquier script cargado con este patrón interrumpirá al analizador de HTML cuando debe ser ejecutado, en lugar de diferir hasta que la página haya cargado. Este patrón tiene un uso sorprendentemente frecuente, 11.4% de las páginas móviles tienen al menos un script con este patrón. En otras palabras, al menos una parte del 6% de scripts que usan defer
no están obteniendo los beneficios del atributo defer
.
Pero hay una historia alentadora sobre esto.
Harry Roberts hizo un tweet sobre este antipatrón en Twitter, lo cual fue lo que nos motivó a medir que tan frecuentemente ocurre en realidad. Rick Viscomi revisó quiénes eran culpables de esto con mayor frecuencia, y resultó que “stats.wp.com” era la fuente de los culpables más frecuentes. @Kraft de Automattic respondió y el patrón será removido de ahora en adelante.
Una de las grandes ventajas sobre lo abierta que es la web es que una observación puede llevar a un cambio significativo como el que vimos aquí.
Resource hints
Otra herramienta que tenemos a nuestra disposición para compensar algunos de los costos de cargar JavaScript son los resource hints, específicamente prefetch
y preload
.
El hint de prefetch
permite a los desarrolladores indicar que un recurso será utilizado en la siguiente navegación de página, por ende el navegador deberá intentar descargarlo una vez que se encuentre desocupado.
El hint de preload
indica que un recurso será utilizado en la página actual y que el browser lo debería tratar de descargar cuanto antes posible.
Globalmente, 16.7% de las páginas móviles usa al menos uno de estos dos resource hints para cargar JavaScript proactivamente.
De ese 16.7%, casi todo el uso viene de usar preload
. Mientras que el 16.6% de las páginas móviles usa al menos un hint de preload para cargar JavaScript, sólo el 0.4% de las páginas móviles usan al menos un hint de prefetch
.
Existe un riesgo, en particular con preload
, al usar demasiados hints pues se reduce su eficacia, así que vale la pena analizar las páginas que usan estos hints para ver cuántos usan.
En la mediana, las páginas que usan hints de prefetch
para cargar JavaScript los usan 3 veces, mientras que las páginas que usan preload
lo usan sólo una vez. La cola se pone un poco más interesante, en el percentil 90 se usan 12 hints de prefetch
y 7 hints de preload
. Para mayor detalle acerca de resource hints vaya al capítulo de Resource Hints de este año.
¿Cómo servimos JavaScript?
Al igual que con otros recursos basados en texto en la web, podemos ahorrar una cantidad significativa de bytes a través de minimización y compresión. Ninguna de estas optimizaciones son nuevas, llevan siendo usadas por mucho tiempo, así que deberíamos verlas usadas frecuentemente.
Una de las auditorías en Lighthouse revisa si el JavaScript no ha sido minimizado y provee una calificación (0.00 siendo la mínima calificación y 1.00 siendo la máxima) basado en lo que encuentra.
La gráfica anterior muestra que la mayor parte de las páginas evaluadas (77%) tienen una calificación de 0.90 o superior, lo que significa que pocos scripts sin minimización han sido encontrados.
En general, sólo el 4.5% de las peticiones de JavaScript medidas no están minimizadas.
Algo interesante es que, si bien hemos sido quisquillosos con las peticiones a terceros, esta es un área donde los scripts de terceros tienen un mejor resultado que los propios. En la página móvil promedio, el 82% de los bytes de JavaScript sin minimizar vienen de código propio.
Compresión
Minimizar los scripts es una buena manera de reducir el tamaño de los archivos, pero la compresión es aún más efectiva y por ende más importante. La compresión provee la mayor parte del ahorro en transmisión con mayor frecuencia.
85% de todas las peticiones de JavaScript usan algún tipo de compresión. Gzip ocupa la mayoría de ese porcentaje, con 65% de los scripts siendo comprimidos usando Gzip en comparación a un 20% para Brotli (br). Mientras que el porcentaje de Brotli (qué es más efectivo que Gzip) es bajo tomando en cuenta el soporte que tiene en los navegadores, la tendencia va en la dirección correcta, pues subió 5 puntos porcentuales comparado con el año pasado.
Una vez más, esta parece ser un área donde los scripts de terceros están haciendo un mejor trabajo que los propios. Si hacemos la comparativa entre los métodos de compresión entre scripts propios y de terceros, podemos ver que el 24% de los scripts de terceros son comprimidos usando Brotli en comparación con un 15% en scripts propios.
Los scripts de terceros también son menos propensos a ser servidos sin ningún tipo de compresión: 12% de los scripts de terceros no usan ni Gzip ni Brotli comparado al 19% de scripts propios.
Vale la pena ver más de cerca a los scripts que no usan compresión. La compresión se vuelve más eficiente en términos de ahorros mientras más contenido tiene que comprimir. En otras palabras, si el archivo es pequeño, a veces el costo de compresión no sobrepasa la minúscula reducción al tamaño del archivo.
Por fortuna, eso es exactamente lo que podemos observar, en particular para los scripts de terceros donde el 90% de los scripts sin comprimir tiene un tamaño menor a 5 KB. Por otro lado, 49% de los scripts propios son de menos de 5 KB y 37% de los scripts propios sin comprimir son de más de 10 KB. Así que mientras que si vemos una gran cantidad de scripts propios pequeños sin comprimir, aún existen muchos que podrían beneficiarse de la compresión.
¿Qué usamos?
Mientras usamos cada vez más JavaScript para crear nuestros sitios y aplicaciones también se ha incrementado la demanda por librerías y frameworks open source que ayuden a mejorar la productividad de los desarrolladores y hacer más mantenible el código. Los sitios que no usan una de estas librerías son una minoría, solamente jQuery se encuentra en el 85% de las páginas móviles medidas por el HTTP Archive.
Es importante que seamos críticos acerca de las herramientas que usamos al construir la web y cuáles son sus pros y contras. Por lo que tiene sentido analizar más de cerca qué usamos hoy en día.
Librerías
El HTTP Archive usa Wappalyzer para detectar las tecnologías usadas en una página. Wappalyzer revisa tanto las librerías de JavaScript (estas son una colección de fragmentos de código y funciones útiles para hacer facilitar el desarrollo como jQuery) y frameworks de JavaScript (estos son más scaffolding y proveen plantillas y estructuras como React).
Las librerías más populares no cambiaron mucho respecto al año pasado, con jQuery manteniendo un dominio en el uso y sólo una de las librerías en el top 21 bajando posiciones (lazy,js siendo reemplazado por DataTables). De hecho, el porcentaje de las librerías más comunes prácticamente no cambió con respecto al año pasado.
El año pasado Houssein listó algunas de las razones por las cuales la dominación de jQuery continúa:
WordPress, que es usado en más del 30% de los sitios e incluye jQuery por defecto. Migrar de jQuery a una librería del lado del cliente más nueva puede tomar tiempo dependiendo de qué tan grande es la aplicación y muchos sitios consisten de jQuery en conjunto con alguna librería más nueva.
Ambas son suposiciones bastante sólidas y parece que la situación no ha cambiado mucho en ninguno de los casos.
De hecho, la dominación de jQuery tiene un mayor respaldo si consideramos que, de las librerías en el top 10, 6 son ya sea jQuery o requieren de jQuery para ser usadas: jQuery UI, jQuery Migrate, FancyBox, Lightbox y Slick.
Frameworks
Cuando tomamos un vistazo a los frameworks, no vemos un cambio dramático en términos de uso en los frameworks principales que fueron destacados el año pasado. Vue.js ha incrementado su uso significativamente y AMP creció un poco, pero la mayoría siguen más o menos donde estaban el año pasado.
Vale la pena mencionar que el problema de detección que fue notado el año pasado aún aplica e impacta los resultados aquí. Es posible que haya habido un cambio significativo en la popularidad de más de estas herramientas pero no podemos notarla con la manera en la que estos datos son recolectados en este momento.
Qué significa todo esto
Nos interesa más el impacto que tienen estas herramientas en las cosas que construimos que su popularidad.
Para empezar, es importante notar que mientras podemos pensar en el uso de una herramienta contra el de otra, en realidad, pocas veces usamos sólo una librería o framework en producción. Sólo el 21% de las páginas analizadas usaban sólo una librería o framework. Dos o tres frameworks era algo común y la cola se vuelve larga muy rápidamente.
Cuando observamos las combinaciones más comunes en producción, la mayoría son esperadas. Sabiendo el dominio de jQuery, no sorprende ver que la mayoría de las combinaciones populares incluyen jQuery y algún número de plugins relacionados a jQuery.
Combinaciones | Páginas | (%) |
---|---|---|
jQuery | 1,312,601 | 20.7% |
jQuery, jQuery Migrate | 658,628 | 10.4% |
jQuery, jQuery UI | 289,074 | 4.6% |
Modernizr, jQuery | 155,082 | 2.4% |
jQuery, jQuery Migrate, jQuery UI | 140,466 | 2.2% |
Modernizr, jQuery, jQuery Migrate | 85,296 | 1.3% |
FancyBox, jQuery | 84,392 | 1.3% |
Slick, jQuery | 72,591 | 1.1% |
GSAP, Lodash, React, RequireJS, Zepto | 61,935 | 1.0% |
Modernizr, jQuery, jQuery UI | 61,152 | 1.0% |
Lightbox, jQuery | 60,395 | 1.0% |
Modernizr, jQuery, jQuery Migrate, jQuery UI | 53,924 | 0.8% |
Slick, jQuery, jQuery Migrate | 51,686 | 0.8% |
Lightbox, jQuery, jQuery Migrate | 50,557 | 0.8% |
FancyBox, jQuery, jQuery UI | 44,193 | 0.7% |
Modernizr, YUI | 42,489 | 0.7% |
React, jQuery | 37,753 | 0.6% |
Moment.js, jQuery | 32,793 | 0.5% |
FancyBox, jQuery, jQuery Migrate | 31,259 | 0.5% |
MooTools, jQuery, jQuery Migrate | 28,795 | 0.5% |
También podemos ver una cantidad relativamente alta de frameworks “modernos” como React, Vue y Angular usados en conjunto con jQuery, por ejemplo como resultado de una migración o inclusión por terceros.
Combinación | Sin jQuery | Con jQuery |
---|---|---|
GSAP, Lodash, React, RequireJS, Zepto | 1.0% | |
React, jQuery | 0.6% | |
React | 0.4% | |
React, jQuery, jQuery Migrate | 0.4% | |
Vue.js, jQuery | 0.3% | |
Vue.js | 0.2% | |
AngularJS, jQuery | 0.2% | |
GSAP, Hammer.js, Lodash, React, RequireJS, Zepto | 0.2% | |
Total | 1.7% | 1.4% |
Es más importante notar que todas estas herramientas usualmente derivan en más código y más tiempo de procesamiento.
Revisando específicamente los frameworks en uso, vemos que la mediana de bytes de JavaScript por páginas usándolos varía dramáticamente dependiendo de qué está siendo usado.
La gráfica siguiente muestra la mediana de bytes por páginas donde cualquiera de los 35 frameworks más comunes fueron encontrados divididos por tipo de cliente.
En un lado del espectro están frameworks como React, Angular o Ember, que tienden a resultar en mucho código sin importar el cliente. Por otro lado, observamos que frameworks minimalistas como Alpine.js y Svelte muestran resultados muy prometedores. La configuración por defecto es muy importante, y parece ser que, al empezar con una base con un alto desempeño, Svelte y Alpine están teniendo éxito (hasta ahora… la muestra es bastante pequeña) en crear páginas más ligeras.
La situación es muy similar cuando tomamos un vistazo al tiempo de ejecución del hilo principal para páginas donde estas herramientas fueron detectadas.
El tiempo de ejecución del hilo principal de Ember destaca tanto que distorsiona la gráfica por tanto tiempo que tarda en ejecutarse. (Pasé algo de tiempo extra investigando esto y parece haber una gran influencia de una cierta plataforma usando este framework de manera poco eficiente en vez de ser un problema con Ember en sí.) Quitar Ember de la gráfica la hace un poco más fácil de entender.
Herramientas como React, GSAP y RequireJS tienden a ocupar mucho del tiempo de ejecución del hilo principal del browser, sin importar si es una página de escritorio o móvil. Las mismas herramientas que dan como resultado una menor cantidad de código—herramientas como Alpine o Svelte—también tienden a tener un menor impacto en el hilo principal.
También vale la pena indagar en el intervalo que existe entre la experiencia que un framework provee en escritorio y móvil. El tráfico de dispositivos móviles cada vez se vuelve más dominante y es crítico que nuestras herramientas se desempeñen tan bien como sea posible en móviles. Una gran diferencia en el desempeño en móviles de un framework es una gran alerta roja.
Como era de esperarse, existe un intervalo para todas las herramientas usadas debido al bajo poder de procesamiento del Moto G4 emulado. Ember y Polymer parecen ser ejemplos particularmente atroces, mientras que RxJS y Mustache varían muy poco entre escritorio y móvil.
¿Cuál es el impacto?
Ahora tenemos una buena idea de cuanto JavaScript usamos, de donde viene y para que lo usamos. Eso es interesante por su cuenta pero la verdadera pregunta aquí es el “¿Y eso qué?” ¿Qué impacto tiene todo este script que usamos en la experiencia de nuestras páginas?
La primera cosa que debemos considerar es qué ocurre con todo ese JavaScript una vez que ha sido descargado. La descarga es sólo la primera parte del viaje del JavaScript. El navegador aún tiene que analizar ese script, compilarlo y eventualmente ejecutarlo. Mientras que los browsers están en una constante búsqueda de maneras de mover parte de ese costo a otros hilos, mucho de ese trabajo aún ocurre en el hilo principal, lo que impide al navegador realizar trabajo de layout o pintado, así como de responder a interacciones del usuario.
Como mencionamos antes, sólo existe una diferencia de 30KB entre lo que se le envía a dispositivos móviles y de escritorio. Dependiendo de tu punto de vista, es entendible si no te molesta mucho la pequeña diferencia entre la cantidad de código enviado a un navegador de escritorio contra uno móvil—después de todo, ¿Qué son 30KB, no?
El mayor problema viene cuando todo ese código llega a un dispositivo de gama media o baja, algo poco parecido a los dispositivos que la mayoría de los desarrolladores tienden a usar, y un poco más parecido al tipo de dispositivos usados por la mayoría de las personas en el mundo. Esa diferencia relativamente pequeña entre escritorio y móvil es mucho más notoria cuando la medimos en términos de tiempo de procesamiento.
Un sitio de escritorio en la mediana pasa 891 ms en lo que el navegador ejecuta todo ese JavaScript en el hilo principal. Mientras tanto, un sitio móvil en la mediana pasa 1,897 ms—más del doble de tiempo que en escritorio. Esto es aún peor para el resto de los sitios. En el percentil 90, los sitios móviles tienen un tiempo de ejecución del hilo principal de JavaScript abrumador de 8,921 ms, comparado con 3,838 ms en sitios de escritorio.
La correlación entre el uso de JavaScript y la calificación de Lighthouse
Una manera de ver cómo todo esto se traduce en un impacto en la experiencia de usuario es intentar encontrar una correlación entre algunas de las métricas de JavaScript que identificamos anteriormente con las calificaciones de Lighthouse para diferentes métricas y categorías.
La gráfica anterior utiliza el coeficiente de correlación de Pearson. Hay una larga y relativamente compleja explicación de lo que eso significa, pero en pocas palabras significa que estamos buscando el grado de correlación entre dos números diferentes. Si encontramos un coeficiente de 1.00, tenemos una correlación directa positiva. Una correlación de 0.00 mostraría que no hay conexión entre ambos números. Cualquier cosa menor a 0.00 indica que hay una correlación negativa—en otras palabras, si un número aumenta el otro disminuye.
Para empezar, no parece haber una correlación medible entre nuestras métricas de JavaScript y la calificación de accesibilidad de Lighthouse (“LH A11y” en la gráfica). Esto es completamente opuesto a lo que se encontró en otros estudios, especialmente en el estudio anual de WebAIM.
La explicación más probable para esto es que las pruebas de accesibilidad de Lighthouse (aún) no son tan completas comparadas con otras herramientas enfocadas en accesibilidad, como WebAIM.
Donde sí vemos una correlación fuerte es entre la cantidad de bytes de JavaScript (“Bytes”) y tanto la calificación general de desempeño de Lighthouse (“LH Perf”) como el Tiempo Total de Bloqueo (“TBT”).
La correlación entre los bytes de JavaScript y las calificaciones de desempeño de Lighthouse es de -0.47. En otras palabras, mientras la cantidad de bytes de JS aumenta, la calificación de Lighthouse de desempeño disminuye. La cantidad total de bytes tiene una correlación más fuerte que la cantidad de bytes de terceros (“3P bytes”), lo cual sugiere que si bien los scripts de terceros fungen un rol, no podemos echarles toda la culpa a ellos.
La conexión entre el Tiempo Total de Bloqueo y los bytes de JavaScript es aún más significativa (0.55 para bytes totales y 0.48 para bytes de terceros). Esto no es sorpresivo debido a que conocemos todo el trabajo extra que los navegadores deben hacer para hacer que el código JavaScript corra en una página—más bytes significa más tiempo.
Vulnerabilidades de seguridad
Otra auditoría útil que Lighthouse corre es revisar si existen vulnerabilidades de seguridad conocidas en librerías de terceros. Hace esto detectando que librerías y frameworks y que versiones son usadas en una página. Después revisa la base de datos open source de Snyk para ver si alguna vulnerabilidad ha sido descubierta en las herramientas detectadas.
De acuerdo a la auditoría, 83.5% de las páginas móviles usan una librería o framework con al menos una vulnerabilidad de seguridad conocida.
Esto es a lo que llamamos el efecto jQuery. Anteriormente vimos como jQuery es usado en un 83% de las páginas. Múltiples versiones viejas de jQuery contienen vulnerabilidades conocidas, lo cual constituye la vasta mayoría de las vulnerabilidades que esta auditoría revisó.
De las casi 5 millones de páginas móviles que fueron probadas, 81% de ellas contiene una versión vulnerable de jQuery—una delantera considerable contra la segunda librería vulnerable más común—jQuery UI con un 15.6%.
Librería | Páginas vulnerables |
---|---|
jQuery | 80.86% |
jQuery UI | 15.61% |
Bootstrap | 13.19% |
Lodash | 4.90% |
Moment.js | 2.61% |
Handlebars | 1.38% |
AngularJS | 1.26% |
Mustache | 0.77% |
Dojo | 0.58% |
jQuery Mobile | 0.53% |
En otras palabras, si podemos hacer que se haga una migración de esas versiones viejas y vulnerables de jQuery, veríamos el número de sitios con vulnerabilidades conocidas desplomarse (al menos hasta que encontremos vulnerabilidades en los frameworks más nuevos).
La mayor parte de las vulnerabilidades encontradas cae en la categoría de severidad “media”.
Conclusión
La popularidad de JavaScript está aumentando continuamente y eso tiene muchos lados positivos. Es increíble considerar todo lo que podemos lograr con la web de hoy gracias a JavaScript que, hasta hace unos años, sería inimaginable.
Pero es claro que también debemos andar con cuidado. La cantidad de JavaScript aumenta de manera consistente cada año (si el mercado accionario fuera así de predecible todos seríamos increíblemente ricos) y eso tiene sus contras. Mayores cantidades de JavaScript están conectadas a un incremento en el tiempo de procesamiento lo cual afecta negativamente métricas clave como el Tiempo Total de Bloqueo. Y, si descuidamos todas esas librerías sin actualizarlas, corremos el riesgo de exponer a los usuarios a vulnerabilidades de seguridad conocidas.
Nuestras mejores apuestas para asegurar que construyamos una web accesible, con buen desempeño y segura son medir cuidadosamente el costo de los scripts que agregamos a nuestras páginas y estar dispuestos a ver con un ojo crítico a las herramientas que usamos y pedirles que sean mejores.