Los números nos dicen que el
crecimiento del código JavaScript tiene un efecto negativo en el rendimiento de los proyectos web. Si esto continúa más, muy pronto, al cargar la página central, se transferirán al menos 400 Kb de código JS. Y esta es solo la cantidad de datos transferidos. Al igual que otros recursos de texto, el código JavaScript casi siempre se transmite en forma comprimida. La compresión es probablemente lo único que generalmente se hace correctamente cuando se transfiere código del servidor al cliente.

Desafortunadamente, si bien la reducción del tiempo de transferencia de ciertos recursos hace una contribución importante a lo que llamamos "rendimiento", la compresión no afecta la cantidad de tiempo que tarda el navegador en analizar y procesar el script después de que está completamente cargado .
Si el servidor envía 400 KB de código JS comprimido al cliente, entonces la cantidad real de código que el navegador necesita procesar después de descomprimir los datos recibidos estará en el área de megabytes. La forma en que los diferentes dispositivos manejan este tipo de trabajo depende de los dispositivos mismos.
Se ha escrito mucho sobre esto, pero solo podemos decir con confianza que el tiempo requerido incluso para analizar la cantidad de código que es bastante habitual para su tiempo varía mucho entre los diferentes dispositivos.
Eche un vistazo, por ejemplo, a
este simple proyecto mío. Durante la carga de la página, se transfieren al cliente unos 23 Kb de código JS sin comprimir. Chrome, que se ejecuta en el MacBook Pro, que se lanzó a mediados de 2017, procesa esta pequeña cantidad de código en unos 25 ms. Sin embargo, en el teléfono inteligente
Nokia 2 Android, una cifra similar se expande a 190 ms. Esto no quiere decir que sea muy pequeño, pero en cualquier caso, la página se vuelve interactiva lo suficientemente rápido.
Ahora, una pregunta importante. ¿Qué piensas, cómo un simple teléfono inteligente Nokia 2 maneja las páginas modernas promedio? De hecho, simplemente horrible. La exploración de páginas web, incluso con una conexión rápida a Internet, obliga al usuario a tener paciencia, ya que trabajar con páginas cargadas con código JavaScript solo es posible después de un período de espera considerable.
Descripción general del rendimiento de Nokia 2 al ver una página que contiene una gran cantidad de código JS, cuyo procesamiento bloquea el hilo principalSi bien los dispositivos con los que utilizan para navegar por las páginas web y las redes a través de las cuales se transmiten los datos han mejorado significativamente en los últimos años, los estudios muestran que todas estas mejoras se "ven afectadas" por las grandes cantidades de código JS incluidas en las páginas. Necesitamos usar JavaScript de manera responsable. La responsabilidad comienza con la comprensión de lo que estamos creando y cómo lo hacemos.
Comparación de la ideología de "sitios" y "aplicaciones"
Suceden cosas extrañas con términos inexactos que usamos para llamar a algo, aunque sus significados, en un nivel intuitivo, son comprensibles para todos. A veces sobrecargamos el significado de la palabra "abeja", llamándola "abejas" y avispas, aunque la diferencia entre abejas y avispas es muy significativa. Tener en cuenta tales diferencias puede llevar al hecho de que las "abejas" y las "avispas" actuarán de manera diferente. Por ejemplo, vamos a destruir un nido de avispas, pero si hablamos de abejas, los insectos son mucho más útiles y vulnerables, su nido ubicado en el lugar equivocado probablemente se decidirá no destruirlo, sino transferirlo a algún lugar.
Se puede observar una libertad similar en la forma en que usamos los términos "sitio web" y "aplicación web". Las diferencias entre estos conceptos son mucho menos obvias que las diferencias entre las avispas reales y las abejas melíferas, pero si estos conceptos se combinan, esto puede tener consecuencias muy desagradables. Los problemas comienzan cuando nos permitimos algo, dependiendo de si un determinado proyecto es "solo un sitio web" o "una aplicación web completa". Si está creando un sitio de información para una empresa, lo más probable es que no confíe en un marco poderoso para administrar los cambios DOM o para implementar el enrutamiento en el cliente. Como mínimo, eso espero. El uso de herramientas que no son adecuadas para resolver ciertos problemas no solo perjudicará a quienes utilizarán el sitio, sino que también afectará gravemente el proceso de desarrollo.
Al desarrollar una aplicación web, todo se ve diferente. Instalamos paquetes, que se acompañan de la adición de cientos, si no miles, de dependencias al proyecto. Además, ni siquiera estamos seguros de la
seguridad de algunos de ellos. Escribimos configuraciones complejas para paquetes. Al trabajar en un entorno de desarrollo tan loco y ubicuo, necesita conocimiento y atención para asegurarse de que lo que se recopiló sea rápido, que el proyecto funcione donde debería funcionar. En caso de duda, ejecute el
comando npm ls --prod en el directorio raíz de su proyecto y vea si puede nombrar el propósito de usar
todo lo que muestra este comando. Incluso si puede hacerlo, esto no se aplica a los scripts de terceros. Estoy seguro de que varios de estos scripts también se utilizan en su proyecto.
Olvidamos que tanto los sitios web como las aplicaciones web ocupan el mismo "nicho ecológico". Ambos están bajo la misma influencia del entorno, que consiste en una variedad de redes y dispositivos. Dichas restricciones no desaparecerán si decidimos llamar a lo que estamos desarrollando como una "aplicación", y los dispositivos de nuestros usuarios no se volverán mágicamente mucho más rápidos si llamamos al "sitio web" una "aplicación".
Es nuestra responsabilidad averiguar quién usa lo que creamos, debemos tener en cuenta el hecho de que las condiciones bajo las cuales los diferentes usuarios se conectan a Internet pueden diferir de aquellas en las que confiamos. Al crear algo, debemos conocer el objetivo por el cual lo estamos creando, y después de eso debemos desarrollar lo que ayuda a lograr este objetivo, incluso si el desarrollo resulta
no ser
una tarea tan emocionante .
Esto significa la necesidad de reevaluar nuestra dependencia de JavaScript y cómo su uso, en particular en detrimento de HTML y CSS, puede llevarnos al uso de patrones irracionales que dañan el rendimiento y la accesibilidad de los proyectos web.
No dejes que los marcos te impongan patrones irracionales
Fui testigo del descubrimiento de cosas extrañas en las bases de código cuando trabajé con equipos específicos del marco para ayudarlos a ser más productivos. Muchos de estos hallazgos tienen una cosa en común, y es que la forma en que están escritos a menudo genera problemas con la disponibilidad y el rendimiento de los sitios. Por ejemplo, considere el siguiente componente Reaccionar:
import React, { Component } from "react"; import { validateEmail } from "helpers/validation"; class SignupForm extends Component { constructor (props) { this.handleSubmit = this.handleSubmit.bind(this); this.updateEmail = this.updateEmail.bind(this); this.state.email = ""; } updateEmail (event) { this.setState({ email: event.target.value }); } handleSubmit () {
Aquí puede encontrar varios problemas notables con respecto a la accesibilidad del proyecto:
- Un formulario que no usa el elemento
<form>
ya no es un formulario. De hecho, puede solucionar esto simplemente especificando el rol = "formulario" del elemento padre <div>
, pero si crea un formulario, y lo que vemos definitivamente parece un formulario, use el elemento <form>
, configurándolo en consecuencia atribuye action
y method
. El atributo de action
juega un papel crucial aquí, ya que permite que el formulario haga al menos algo, incluso si JavaScript no está disponible (naturalmente, si el componente se procesó en el servidor). - La
<span>
no sustituye a la <label>
, que proporciona algunas características con respecto a la disponibilidad de proyectos que <span>
no tiene. - El elemento
<button>
sin el atributo type="submit"
es solo un botón, haciendo clic en el que llama al controlador de eventos vinculado a él. Si queremos hacer algo con los datos antes de enviar el formulario, debemos asignar el atributo type="submit"
al botón y mover el código del controlador de eventos onClick
controlador de onSubmit
formulario onSubmit
. - Por cierto, ¿por qué usar JavaScript para verificar las direcciones de correo electrónico, mientras que HTML5 pone a nuestra disposición controles que admiten la verificación de datos de entrada en casi todos los navegadores, hasta IE10? Aquí vemos una oportunidad perdida para aprovechar la funcionalidad que ya está en el navegador y aplicar el tipo de elemento apropiado, así como el atributo requerido . Sin embargo, al usar tales construcciones, tenga en cuenta que configurar su interacción normal con los lectores de pantalla requerirá cierto esfuerzo .
Teniendo en cuenta lo anterior, refactorizamos el código del componente:
import React, { Component } from "react"; class SignupForm extends Component { constructor (props) { this.handleSubmit = this.handleSubmit.bind(this); } handleSubmit (event) {
Ahora, el hecho de que este componente se procesa no solo resulta ser más accesible, sino que se usa menos código JS para implementar la misma funcionalidad que antes. En un mundo que literalmente se ahogó en JavaScript, deshacerse de unas pocas líneas de código debería verse como algo positivo. El navegador nos brinda
muchas oportunidades , y debemos esforzarnos por utilizar estas oportunidades con la mayor frecuencia posible.
No quiero decir aquí que los problemas con la accesibilidad de las páginas surgen exclusivamente cuando se usan ciertos marcos. Quiero decir, confiando demasiado en JavaScript, el desarrollador, como resultado, simplemente se perderá muchas características importantes de HTML y CSS. Estas lagunas en el conocimiento a menudo conducen a errores, además, ni siquiera sospechamos de estos errores. Los marcos pueden ser herramientas útiles que aumentan la productividad del desarrollador, pero el estudio constante de las capacidades de las tecnologías web básicas es extremadamente importante para crear productos convenientes y utilizables, independientemente de las herramientas auxiliares utilizadas en su desarrollo.
Confíe en el poder de la plataforma web y dé a sus proyectos un futuro brillante
Como estamos hablando de marcos, cabe señalar que la plataforma web, en sí misma, también es un gran marco. Como se muestra en la sección anterior, nos encontramos en una mejor posición si podemos confiar en los patrones establecidos para trabajar con el marcado y las capacidades del navegador. Una alternativa a estas características estándar es inventarlas nuevamente. Huelga decir que tal "invención" está cargada de dificultades considerables. Pero, ¿qué pasaría si tales problemas, cada uno a su manera, fueran resueltos por los autores de todos los paquetes de JavaScript que instalamos?
Applications Aplicaciones de página única
Una de las debilidades de los desarrolladores que pueden permitirse fácilmente es el uso del modelo de Aplicación de Página Única (SPA), incluso en aquellos proyectos para los que este modelo no es adecuado. Por supuesto, tales proyectos se benefician del hecho de que los usuarios los perciben como más productivos debido al enrutamiento realizado por el cliente. Pero, ¿cuáles son las desventajas de usar el modelo SPA? Las capacidades de navegación de páginas integradas en el navegador, aunque se basan en un modelo síncrono, le dan al proyecto muchas ventajas. Una de ellas es que la gestión del historial de visitas se lleva a cabo mediante la implementación de
especificaciones complejas . Los usuarios sin JavaScript,
ya sea que lo hayan deshabilitado o no , no perderán la capacidad de trabajar con el proyecto. Para que una aplicación de una página esté disponible en los navegadores con JavaScript desactivado, de repente resulta que se debe prestar mucha atención a la representación del servidor.
Comparación de diferentes opciones para cargar una aplicación experimental en un canal de comunicación lento. La representación de la aplicación a la izquierda depende completamente de JavaScript. La aplicación de la derecha se representa en el servidor, pero luego usa, en el cliente, el método hydrate () para conectar los componentes al marcado ya creado en el servidorAquí puede ver que la aplicación, que se procesa en el cliente, durante unos segundos muestra al usuario una pantalla en blanco y luego muestra la interfaz terminada.
Una aplicación que se procesa en el servidor y se vuelve operativa en el cliente muestra rápidamente los elementos principales de la interfaz, pero puede usarla aproximadamente al mismo tiempo que la aplicación que se procesa completamente en el cliente.
La disponibilidad de la aplicación también se ve afectada si el enrutador ubicado en el cliente no puede informar al usuario sobre lo que ha cambiado en la página que está viendo. Esto puede obligar al usuario a confiar en tecnologías de asistencia para descubrir qué ha cambiado exactamente en la página, como resultado, el trabajo del usuario con el sitio es mucho más complicado.
Además, puedes conocer de inmediato a nuestro viejo enemigo: una carga excesiva en el sistema. Algunos enrutadores cliente son muy pequeños. Pero si realiza un proyecto en
React , utiliza un
enrutador compatible y, posiblemente, una
biblioteca para administrar el estado de la aplicación, esto significa que debe aceptar que contendrá una cierta cantidad de código de servicio, del cual no puede acceder a ningún lado. Es decir, en este caso es aproximadamente 135 Kb de dicho código. Analice cuidadosamente los proyectos que está creando y si el enrutamiento del cliente vale la carga adicional en el sistema. Suele suceder que es mejor rechazar el sistema de enrutamiento del cliente.
Si le preocupan los sentimientos del usuario, si desea que el sitio le parezca rápido, puede confiar en el atributo de enlace
rel = prefetch , que le permite organizar la carga previa de documentos de la misma fuente. El uso de este atributo tiene un gran impacto en la mejora del rendimiento del proyecto, percibido por los usuarios, ya que las páginas vinculadas al uso de este atributo, cuando hace clic en estos enlaces, se cargan instantáneamente desde el caché. Además, dado que la precarga de datos tiene baja prioridad, es poco probable que compita por el ancho de banda con recursos importantes.
El código HTML al que se hace referencia al escribir / se carga previamente cuando visita la página principal del sitio. Cuando un usuario hace clic en el enlace correspondiente, el código HTML se carga instantáneamente desde la memoria caché del navegadorEl principal problema que puede surgir con las páginas de precarga, y que debe tener en cuenta, es que dicha carga puede resultar en una pérdida de tiempo y recursos. Para resolverlo, puede, por ejemplo, usar el pequeño script
Quicklink de Google, que mitiga este problema. Comprueba si el cliente actual está utilizando una conexión lenta, si tiene
habilitado el modo de ahorro de datos y, de forma predeterminada, le permite evitar la carga previa de materiales de fuentes distintas de la fuente de la página.
Para hacer que el sitio se vea rápido a los ojos de los usuarios que lo visitan muchas veces, puede utilizar
los trabajadores del servicio . Se pueden usar independientemente de si el proyecto usa un sistema de enrutamiento de clientes o no, dado que está familiarizado con
algunas de las características de los trabajadores
de servicios. Al realizar el
almacenamiento en caché de rutas mediante trabajadores de servicio, obtenemos muchas de las mismas ventajas que son típicas para la carga previa de materiales de algunos enlaces, pero tenemos capacidades mucho más amplias para trabajar con solicitudes y respuestas. Ya sea que perciba su sitio como una "aplicación" o no, equiparlo con un trabajador de servicios es probablemente un ejemplo de uno de los casos de uso de JavaScript más críticos de nuestro tiempo.
▍JavaScript no está diseñado para el diseño
Si instalamos un paquete JS diseñado para resolver problemas relacionados con los diseños de página, entonces es hora de que tengamos mucho cuidado y nos preguntemos qué estamos tratando de lograr con este paquete. CSS fue creado
específicamente para crear diseños de página, para usarlo de manera efectiva, no necesita ninguna abstracción. La mayoría de las tareas de crear diseños que intentan resolverse usando JavaScript, como
colocar elementos, alinearlos, ajustar sus tamaños, como
administrar texto o incluso
crear diseños completamente usando JavaScript, ahora se pueden resolver usando CSS. Las herramientas modernas para crear diseños como Flexbox y Grid son bien compatibles con los navegadores, por lo que no necesitamos desarrollar proyectos basados en marcos para trabajar con diseños. Por cierto, CSS también es un marco. Cuando tenemos a nuestra disposición la oportunidad de
solicitar propiedades , la mejora progresiva de los diseños para apoyar nuevos medios de formación, como resultado,
no es
tan difícil .
/* , , , CSS Grid. */ /* @supports , CSS Grid, . */ @supports (display: grid) { /* */ @media (min-width: 40em) { /* CSS Grid */ } }
Usar JavaScript para resolver los problemas de crear diseños de página y personalizar su apariencia no es una novedad. Esto es lo que hicimos en 2009, cuando vivíamos en una atmósfera de autoengaño, diciendo que todos los sitios deberían verse en IE6, así como en los navegadores más avanzados de la época. Si hoy, en 2019, continuamos desarrollando sitios para que tengan el mismo aspecto en todos los navegadores, esto significa que debemos reconsiderar nuestros objetivos. Siempre habrá algunos navegadores que deben ser compatibles y que no tienen las mismas capacidades que los navegadores más modernos. La similitud externa completa de los proyectos en todas las plataformas no solo es un desperdicio de energía, sino que también es un enemigo fundamental de la idea de
mejoras progresivas .
En pocas palabras: no voy a convertirme en un asesino de JavaScript
No me malinterpreten, no pertenezco a los enemigos de JavaScript. Gracias a este lenguaje, he desarrollado una carrera y, para ser honesto, JavaScript, por más de diez años, me brinda mucho placer. Al igual que con cualquier relación a largo plazo, cuanto más tiempo paso trabajando con JavaScript, mejor lo conozco. Es un lenguaje maduro con muchas características que, cada año, mejora.
Sin embargo, a veces me parece que algo salió mal con nuestra relación de JavaScript. Lo critico O, más precisamente, critico la tendencia actual de considerar a JavaScript como la herramienta principal para la construcción de sitios, a la que se recurre en primer lugar, sin mirar nada más. Cuando analicé otro paquete que parecía una confusa guirnalda de Navidad, me di cuenta de que la web estaba intoxicada con JavaScript. Recurrimos a este lenguaje por casi cualquier motivo, incluso en los casos en que las circunstancias no lo requieren. A veces pienso en cuán severas pueden ser las consecuencias de esta actitud hacia JS.
Planeo continuar escribiendo sobre JavaScript y el desarrollo web, para seguir buscando formas de usar racionalmente las tecnologías web. Esperemos que juntos mejoremos la web moderna.
Estimados lectores! ¿Crees que la web moderna está realmente sobrecargada con código JavaScript?