Ahora, al final de la década, es hora de reevaluar críticamente lo que se consideró correcto en el pasado reciente y descubrir si ha perdido relevancia hoy. Las mejores prácticas de ayer a veces se convierten en antipatrones de hoy.

El autor del artículo, cuya traducción publicamos hoy, explorará tres enfoques para agrupar proyectos de JavaScript utilizando el ejemplo de una sencilla aplicación Hello World creada con React. Algunos de los ejemplos que cita incluyen la lectura de los conceptos básicos de los creadores de módulos, como
Webpack , que parece ser la herramienta más popular en la actualidad.
Enfoque n. ° 1: absolutamente todo se mete en el paquete (parece una gran bola de hilo)
La idea principal: no use este enfoque.
Con este enfoque, el generador de módulos simplemente se usa para empaquetar todo en el paquete, tanto las dependencias como el código de la aplicación. La salida es algo así como una gran bola de hilo. En mi ejemplo, esto incluye
react
,
react-dom
y el código de la aplicación en sí. Un único paquete que contiene todo el código del proyecto está conectado a la página:
<!-- index.html --> <script src="bundle.[hash].min.js"></script>
Antes del lanzamiento de HTTP / 2, este patrón podría considerarse, de alguna manera, bastante aceptable, ya que su uso reduce la cantidad de solicitudes HTTP que ejecuta el navegador al cargar los materiales de la página. Pero dado que la mayoría de los sitios actuales usan HTTP / 2, este patrón se ha vuelto antipatrón.
Por qué El hecho es que cuando se usa HTTP / 2, la ejecución de muchas solicitudes ya no crea la misma carga en el sistema que antes. Como resultado, empaquetar el código en un solo paquete grande ya no le da al proyecto ventajas significativas.
Con este enfoque, la organización eficiente del almacenamiento en caché del navegador es complicada. Por ejemplo, cambiar solo una línea de código en una aplicación simple cambiará el hash del paquete e invalidará el caché que almacena todo el código del proyecto. Como resultado, todos los visitantes que regresan tienen que descargar el código completo del sitio nuevamente, a pesar de que este código no es diferente en un 99% del que descargaron en la visita anterior. Aquí nos ocupamos del uso irracional de los recursos de la red debido a la transmisión repetida de los mismos datos del servidor al cliente.
HTTP / 2 hoy es compatible con
más del 95% de los clientes . En 2019, este protocolo fue implementado por la
mayoría de los servidores. Obtenga más información sobre el uso de HTTP / 2 en 2019 aquí.
Enfoque n. ° 2: empaquetado separado del código del proyecto y el código de las bibliotecas de terceros (separación de código)
Idea principal: utilice este enfoque.
Tomemos en cuenta lo que hablamos en la sección anterior y mejoremos la situación con el almacenamiento en caché del navegador al separar el código del proyecto del código de dependencia. Esto resuelve el problema en el caso descrito anteriormente, cuando cambiamos ligeramente el código del proyecto y luego publicamos la actualización en producción. Ahora solo ha cambiado el hash del paquete de
index
, que almacena el propio código del proyecto, y el hash del paquete de
vendor
permanece sin cambios. Los visitantes que regresan al sitio actualizado solo descargarán el archivo de
index
modificado con este enfoque, lo que ahorrará algunos recursos de red.
Si hablamos de Webpack, para implementar esta estrategia, necesitará
configuraciones adicionales con respecto a la separación de código. Con su ayuda, informamos al paquete sobre dónde está el código de dependencia. Una forma simple y conveniente de detectar dicho código es que hay
node_modules
en la ruta a los archivos correspondientes, ya que todo el código de dependencia se almacena en esta carpeta.
Esto es en lo que se ha convertido el código de conexión del script:
<!-- index.html --> <script src="vendor.[hash].min.js"></script> <script src="index.[hash].min.js"></script>
Y aquí está la línea de tiempo en cascada para cargar la página, cuando se trabaja con HTTP / 2.
Programa de carga de página de cascadaEste es un paso en la dirección correcta. Pero podemos seguir optimizando la agrupación. Si piensa en todo esto, puede comprender que algunas dependencias del proyecto cambian con menos frecuencia que otras. Tal vez
react-dom
menos probable que
react
y
react-dom
react
y cuando una biblioteca se actualiza, otra se actualiza. Como resultado, podemos concluir que estas dos bibliotecas se pueden agrupar en un fragmento lógico, que se puede separar de otras dependencias, que cambian con más frecuencia que
react
y
react-dom
. Al darnos cuenta de esta idea, obtenemos lo siguiente:
<!-- index.html --> <script src="vendor.react.[hash].min.js"></script> <script src="vendor.others.[hash].min.js"></script> <script src="index.[hash].min.js"></script>
Si continuamos con el desarrollo de esta idea, podemos decidir que los visitantes del sitio web no necesiten descargar todo el código del proyecto para ver solo una página. En invierno, algunos de nosotros tendemos a aumentar de peso, por lo que el archivo de
index
, que contiene el código de la aplicación, crece con el tiempo. En algún momento puede resultar que el código del proyecto esté sujeto de manera justificada a una mayor separación,
cargando dinámicamente componentes individuales e incluso organizando la
precarga de módulos individuales.
Para mí, este nivel de separación de código todavía parece bastante desalentador. Todavía parece una tecnología experimental (y algo así, en el que los errores sutiles pueden manifestarse). Pero para mí es muy claro que una fuerte separación de código es la dirección en la que se mueve la industria del desarrollo web. Quizás debido al soporte del navegador para módulos JavaScript, eventualmente podremos abandonar completamente los paquetes como Webpack y simplemente dar módulos individuales de código a los clientes. ¡Será interesante ver a dónde nos lleva todo esto!
Enfoque n. ° 3: uso de CDN públicas para el código de algunas dependencias
La idea principal: no use este enfoque.
Si usted es uno de los que están un poco anticuados en el desarrollo web (como yo), entonces puede tener la sensación interna de que podríamos conectar el archivo
vendor.react
, que se trata en la sección "Enfoque No. 2 ", utilizando un recurso público de CDN:
<!-- index.html --> <script crossorigin src="https://unpkg.com/react@16.12.0/umd/react.production.min.js"></script> <script crossorigin src="https://unpkg.com/react-dom@16.12.0/umd/react-dom.production.min.js"></script> <script src="index.[hash].min.js"></script>
Observo que cuando se usa este enfoque, es necesario
decirle al recopilador de proyectos de Webpack que debe excluir el código de
react
y
react-dom
del paquete.
A primera vista, todo esto parece bastante sólido, pero este enfoque tiene algunas desventajas que propongo considerar.
▍ Menos # 1: ¿Usa diferentes sitios de los mismos archivos de dependencia? Ya no ...
Los desarrolladores de la vieja escuela mantienen la esperanza de que si todos los sitios enlazan con el mismo recurso CDN y usan la misma versión de React que nuestro sitio, los visitantes de nuestro sitio si ya hay un código React en el caché de sus navegadores, No perderá tiempo volviéndolo a cargar. Esto aumentaría seriamente la velocidad de visualización de páginas de nuestro sitio en modo de trabajo. Sí, y la
documentación de React sobre este tema parece prometedora. Por lo tanto, con seguridad, algunos desarrolladores usan este patrón. Derecho?
Aunque anteriormente esto podría funcionar bien, recientemente en los navegadores, en aras de una mayor seguridad, comenzaron a implementar un mecanismo para compartir cachés. Estamos hablando del hecho de que, incluso en condiciones ideales, cuando dos sitios usan la misma biblioteca, cargados a través del mismo enlace CDN, el código se descarga de forma independiente para cada dominio, y el caché, por razones de privacidad, termina en la caja de arena asignado a un dominio específico. Al
final resultó que , este mecanismo ya se ha implementado en Safari (aparentemente, existe desde 2013?!). Y si hablamos de Chrome 77, para habilitar la separación de caché por el momento, debe usar un
indicador especial.
Supone razonablemente que el uso de CDN disponibles públicamente disminuirá a medida que se implemente el uso compartido de caché en más navegadores.
▍ Menos No. 2: desperdicio de recursos del sistema en operaciones auxiliares (para cada dominio)
Aquí se expresa
la idea de que el uso de CDN conduce a un aumento de la carga en el sistema, ya que incluso antes de enviar la solicitud HTTP, el navegador debe resolver muchos problemas: resolución de nombres DNS, conexión TCP, protocolo de enlace SSL. Para conectarse al sitio, el navegador debe realizar estas acciones en cualquier caso, pero si se ve obligado a conectarse también a la red CDN, esto aumenta la carga.
Aquí hay un gráfico en cascada que ilustra el proceso de cargar una página que utiliza scripts de un recurso CDN disponible públicamente.
Línea de tiempo en cascada para cargar una página utilizando recursos CDN disponibles públicamenteLos óvalos rojos resaltan las áreas en las que ocurren las operaciones que preceden a la ejecución de consultas. Esto parece demasiado para una simple aplicación de Hello World.
A medida que mi ejemplo simple evoluciona y crece, llegará un momento en que quiera usar mi propia fuente. Por ejemplo, tomado de Google Fonts. Y esto significa que el número de tales retrasos solo aumentará, ya que tendrá que conectarse al dominio correspondiente para descargar las fuentes. Aquí, la idea de alojar todos los recursos del sitio en su propio dominio principal (que, por supuesto, se encuentra detrás del propio recurso CDN del proyecto basado en Cloudflare o Cloudfront) parece ser muy atractiva.
Si en nuestro ejemplo cambiamos a la descarga de dos dependencias React del dominio principal del sitio, esto conducirá al hecho de que la programación en cascada de la carga de la página será mucho más precisa.
Programa de carga en cascada para una página que no utiliza recursos CDN disponibles públicamenteInMinus No. 3: uso de diferentes versiones de dependencias por diferentes sitios
Preparé un pequeño
estudio de investigación
de los 32 sitios más grandes usando React. Desafortunadamente, descubrí que solo el 10% de ellos usa recursos CDN disponibles públicamente para descargar React. Resultó, sin embargo, dadas las versiones de React que usan todos los sitios estudiados, que esto realmente no importa. En un mundo ideal, no habría separación de la memoria caché del navegador, y todos los sitios podrían organizarse y usar las mismas versiones de script de los mismos CDN públicos. En realidad, hay una variación extremadamente fuerte en las versiones de React utilizadas por diferentes sitios. Esto destruye la idea de un caché de navegador compartido.
Reaccionar versiones utilizadas por diferentes sitiosSi primero abre un sitio popular usando React, y luego otro, entonces resulta que las posibilidades de que ambos sitios usen la misma versión de React son muy pequeñas.
En el curso de la investigación, encontré información más interesante sobre estos sitios React. Quizás también te parezcan interesantes:
- En 2/3 sitios, Webpack se usa para construir código.
- El 87% de los sitios usan HTTP / 2, que es más que el valor promedio del 58%.
- La mayoría de los proyectos (aproximadamente el 56%) alojan las fuentes en sí.
Aquí están los datos de origen para mi experimento.
InMinus No. 4: problemas de no rendimiento
Desafortunadamente, hoy en día aquellos que usan recursos CDN disponibles públicamente se enfrentan no solo con problemas relacionados con la velocidad de carga de la página, sino también con otros problemas:
- Problemas de seguridad. Existen problemas de seguridad asociados con el uso de recursos de CDN disponibles públicamente que no sean los destinados a resolver el uso compartido de caché en los navegadores. Si, por ejemplo, los piratas informáticos entran en un recurso CDN de acceso público, pueden inyectar con mucho cuidado código malicioso de JavaScript en las bibliotecas. Dicho código tendrá todos los privilegios del código del sitio ejecutado en el cliente, podrá trabajar con los datos de los usuarios que han iniciado sesión en el sitio.
- Problemas de privacidad Muchas empresas recopilan datos de usuarios de solicitudes realizadas por recursos de terceros. En teoría, si el uso de un recurso CDN disponible públicamente para descargar fuentes o código de dependencia se implementa en todos los sitios, entonces este recurso CDN podrá rastrear las sesiones de los usuarios y las características de su trabajo en Internet. Un recurso similar podrá hacer suposiciones sobre lo que les interesa (por ejemplo, con fines publicitarios). Y todo esto, ¡sin el uso de cookies!
- Punto único de falla. La distribución de los materiales necesarios para el funcionamiento del sitio en varios dominios aumenta las posibilidades de que, debido a problemas en uno de estos dominios, el cliente pueda descargar solo una parte de los materiales necesarios para que las páginas funcionen. Para ser sincero, estos problemas se pueden resolver utilizando JavaScript, pero para esto el desarrollador del sitio tendrá que hacer algunos esfuerzos adicionales.
Resumen
Es muy obvio que el futuro está en el enfoque No. 2.
Hospede sus propios recursos CDN frente a sus servidores utilizando HTTP / 2 (como Cloudflare o Cloudfront). Divida el código en pequeños fragmentos para utilizar de manera efectiva el caché del navegador. En el futuro, los fragmentos en los que se divide el código del sitio pueden volverse aún más pequeños, alcanzando el tamaño de
módulos JavaScript individuales, debido al hecho de que los navegadores han comenzado a implementar el soporte para esta tecnología.
Estimados lectores! ¿Utiliza tecnologías de separación de código en sus proyectos web?
