Repensando las Estrategias de Agrupación

Rate this content
Bookmark
Damos un vistazo a diferentes desafíos y decisiones al agrupar código para aplicaciones web. Observamos cómo se resuelven comúnmente estos y por qué necesitamos repensarlos.
Tobias Koppers
Tobias Koppers
32 min
08 Dec, 2023

Comments

Sign in or register to post your comment.

Video Summary and Transcription

La charla discute sobre repensar las estrategias de agrupación, enfocándose en desafíos como el almacenamiento en caché a largo plazo y la mejora del estado de Next.js y Webpack. Explora el manejo del almacenamiento en caché inmutable y los hashes de contenido, optimizando las referencias de activos y los manifiestos de página, y abordando problemas con la navegación del lado del cliente y el almacenamiento en caché a largo plazo. La charla también cubre la eliminación de árboles y la optimización, optimizando los fragmentos de módulo y la ubicación del código, y el uso y la relación de TurboPack con Webpack. Además, toca la personalización de la configuración y los riesgos de hash, las importaciones de barril y la división de código, y los puntos de entrada y las heurísticas de fragmentación.

Available in English

1. Replanteando Estrategias de Agrupación

Short description:

Soy Tobias Cobbers, el creador de Webpack. Hoy quiero hablar sobre replanteando estrategias de agrupación, centrándome en dos desafíos en la escritura de agrupadores. El primer desafío es el almacenamiento en caché a largo plazo, aprovechando la caché del navegador para almacenar recursos entre implementaciones. El segundo desafío implica mejorar el estado actual de Next.js y Webpack. Vamos a sumergirnos en estos desafíos y explorar cómo podemos hacerlo mejor.

Gracias. Sí, en realidad estoy hablando de replanteando estrategias de agrupación hoy, y mi nombre es Tobias Cobbers. Creé Webpack hace 11 años o 12 años, y hace dos años, o hace tres años, me uní a Vessel y trabajé un poco en Next.js, mejorando Webpack para Next.js.

Ahora estoy trabajando en TurboPack e integrando Next.js con TurboPack. Mi charla es en realidad un poco más general, así que quiero hablar de algunas cosas. Quiero ver dos desafíos diferentes en la escritura de agrupadores. En realidad estamos mirando la magia en los agrupadores. Así que agarré dos temas para eso, dos desafíos que actualmente o en el futuro enfrentaré con la construcción de TurboPack. Y quiero profundizar un poco en eso porque creo que aprender esta magia de bundler puede ser importante, incluso si técnicamente no deberías enfrentarte a ella en tu trabajo diario. El bundler debería hacerlo transparente y no debería enfrentarte con todos estos desafíos. Debería resolverlo mágicamente. Pero creo que todavía es útil saberlo, y obtienes una visión profunda de eso, y puede ayudarte en algunos casos extremos.

Primero, quiero presentar estos dos desafíos, y luego entrar en el estado actual con Next.js y Webpack para eso. Y después de eso, quiero dedicar un poco de tiempo a repensar eso y cómo podemos mejorar en eso, qué podemos hacer mejor en el futuro, y qué queremos hacer en TurboPack con estos desafíos. Un pequeño descargo de responsabilidad primero, principalmente trabajo con Next.js, Webpack, y TurboPack, así que todo es desde la perspectiva de estas herramientas. Y todavía hay otras herramientas afuera, y tienen cosas similares, diferentes implementaciones. Y aunque la mayoría de las ideas no son realmente nuevas, están más inspiradas por otras herramientas y sí. Así que el primer tema es principalmente sobre el almacenamiento en caché a largo plazo, que realmente no es muy conocido por muchas personas. ¿Y qué es el almacenamiento en caché a largo plazo en absoluto? Así que el almacenamiento en caché a largo plazo significa que queremos aprovechar la caché del navegador, por lo que la memoria caché en el navegador para almacenar nuestros recursos, y especialmente entre implementaciones. Así que básicamente hay tres niveles, o tres niveles prácticos de aprovechamiento de la caché del navegador. El primero es el almacenamiento en caché máximo, donde simplemente especificas que mis recursos son válidos para dos horas, y no tienes que verificar eso de nuevo, y puedes usar la caché para dos horas. Pero en la práctica, es bastante inadecuado para nuestro caso de aplicación, porque podríamos tener una corrección de error crítica para solucionar, y queremos implementar algo, y no queremos esperar dos horas hasta que el usuario realmente obtenga una corrección de error. Así que no queremos usar eso en absoluto. Y lo que queremos usar es como el almacenamiento en caché e-tech, por ejemplo. Y el almacenamiento en caché e-tech significa básicamente que cuando el servidor responde con el recurso, envía un encabezado especial, e-tech, que generalmente contiene un hash del contenido, y luego el navegador almacena eso en su caché, y básicamente, en la caché. Y también quieres especificar tres fechas válidas, así que la próxima vez que el navegador quiera usar el recurso, simplemente hace una nueva solicitud para eso, pero incluye un encabezado especial si-no-coincide que incluye el e-tech, por lo que el hash del contenido, y luego el servidor podría, si el recurso no cambió en el ínterin, podría responder con un código de estado especial, como, no ha cambiado, puedes usar la caché, y no necesitas descargarlo de nuevo. Y eso básicamente siempre funciona, eso es genial. Pero siempre también revalida la solicitud. Así que básicamente envía una nueva solicitud, tienes que pagar el viaje de ida y vuelta, pero no tienes que pagar el costo de descarga. Así que es bueno, pero puedes hacerlo mejor.

2. Manejo de Caché Inmutable y Hashes de Contenido

Short description:

La mejor manera de manejar el almacenamiento en caché para recursos estáticos es a través del almacenamiento en caché inmutable, donde el navegador puede almacenar en caché los recursos indefinidamente. Para garantizar la consistencia, se utiliza una URL única con un hash de contenido, lo que permite realizar actualizaciones fácilmente sin romper la caché. Para lograr compilaciones deterministas, el agrupador debe generar la misma salida para la misma aplicación, al tiempo que garantiza que los pequeños cambios resulten en pequeños cambios de salida. Sin embargo, el manejo de los hashes de contenido se vuelve más complejo cuando hay referencias entre diferentes partes de la aplicación. Webpack y Next.js han avanzado en la solución de estos desafíos, pero el problema de los hashes de contenido persiste.

El mejor, creo, al menos para recursos estáticos y para ese tipo de cosas, es el almacenamiento en caché inmutable, lo que significa que envías control de caché inmutable y algunos otros encabezados, y eso significa que el navegador puede almacenarlo en caché para siempre, nunca tiene que hacer un viaje de ida y vuelta, nunca tiene que solicitarlo de nuevo, simplemente puede almacenarlo para siempre, generalmente un año o algo así.

Pero solo funciona, básicamente, si lo almacena sin revalidar para siempre, básicamente no puedes cambiar el contenido del recurso, porque si lo cambias, entonces podría ser inconsistente, y los navegadores podrían tenerlo aún en caché, no funciona.

Entonces, generalmente abordas eso haciendo que la URL de eso sea única de tal manera que nunca cambie. Entonces, generalmente la cosa es que simplemente agregas un hash de contenido a la URL, podrías haber visto eso con nombres de archivos que tienen este hash adjunto, y eso hace que la URL sea tan única que nunca cambiará y si implementas una nueva versión, simplemente obtendrá una nueva URL con un nuevo hash.

Sí, ese sería el mejor. Entonces, ¿cómo enfrentamos eso desde un nivel de agrupador? Entonces, el desafío se puede resolver con algunas técnicas diferentes. Entonces, una cosa es que queremos hacer que el bundler de tal manera que esté generando compilaciones deterministas. Entonces, una compilación debería, si compilas la misma aplicación, simplemente debería generar el mismo activo de salida para que la caché pueda ser utilizada realmente. Si generaras diferentes activos de salida, entonces no puedes usar la caché. Pero también quieres otra propiedad. Quieres esta propiedad de que incluso si haces un pequeño cambio en tu aplicación, que usualmente haces, como en cada solicitud de extracción o lo que sea, quieres una propiedad que un pequeño cambio resulte en un pequeño cambio de salida. Si solo cambias un módulo, podrías esperar que solo uno o pocos fragmentos cambien en el paquete de salida. Y sí, esa es la forma en que podemos usar generalmente nuestra caché del navegador. Ahora queremos usar esta cosa de almacenamiento en caché inmutable, por lo que solo queremos poner un hash de contenido en cada fuente o cada nombre de archivo que emitimos desde el bundler. Suena bastante fácil. Simplemente haces un hash del contenido, lo agregas al nombre del archivo. Pero se vuelve un poco complicado porque en realidad hay referencias entre las diferentes cosas en tu aplicación. Entonces, como un ejemplo, HTML hace referencia a tus fragmentos, los fragmentos se refieren entre sí, tal vez para carga asíncrona y esas cosas. Y los fragmentos también hacen referencia a los activos, como imágenes, fuentes, esas cosas. Y ahí es donde entra el problema. Entonces, sí, básicamente resolvimos estas primeras cosas con Webpack en el estado actual con Next.js. Entonces, para hacer compilaciones deterministas, simplemente tenemos cuidado al implementar eso y tratamos de evitar partes absolutas, básicamente evitamos partes absolutas. Y para hacerlo independiente de estos cambios donde clonas tu repositorio en un directorio diferente y todas esas cosas. Y eso es bastante fácil, en realidad. Y el más difícil es esta propiedad de pequeño cambio de entrada, pequeño cambio de salida, donde tienes que considerar cada algoritmo para hacerlo realmente sin tener este efecto de toda la aplicación. Como los ID de módulo, realmente no podemos numerarlos uno por uno, tenemos que... Porque si los numeras uno por uno, insertar un módulo al principio renombraría todos los modules no a la propiedad que queremos. Entonces, haciendo uso de hashes para generar ID de módulos, y también para dividir tus modules en fragmentos, tienes que hacerlo determinista de tal manera que los pequeños cambios se conviertan en pequeños cambios de salida. También es relevante para las optimizaciones, como la ofuscación y esas cosas. En general, resolvimos algunas cosas, pero veamos este problema de los hashes de contenido.

QnA

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

Building Figma’s Widget Code Generator
React Advanced Conference 2022React Advanced Conference 2022
19 min
Building Figma’s Widget Code Generator
Widgets are custom, interactive objects you place in a Figma or Figjam file to extend functionality and make everything a bit more fun. They are written in a declarative style similar to React components, which gets translated to become a node on the canvas. So can you go the other way, from canvas to code? Yes! We’ll discuss how we used the public Figma plugin API to generate widget code from a design file, and make a working widget together using this.
Start Building Your Own JavaScript Tools
JSNation 2023JSNation 2023
22 min
Start Building Your Own JavaScript Tools
Your first JavaScript tool might not be the next Babel or ESLint, but it can be built on them! Let's demystify the secret art of JavaScript tools, how they work, and how to build our own. We'll discover the opportunities in our everyday work to apply these techniques, writing our own ESLint rules to prevent mistakes and code transforms to make breaking changes easy to apply. We’ll walk through the fundamentals of working with an abstract syntax tree, and develop our understanding through a live-code. You will be amazed at what you can build, and together we’ll explore how to get started.
Advanced linting rules with ESLint
TypeScript Congress 2023TypeScript Congress 2023
10 min
Advanced linting rules with ESLint
This talk will explore more advanced ways to write static analysis rules in ESLint using ESLint's control flow APIs. I will quickly explain what a control flow graph is and how you can use it to find issues in your code. I will show you how to detect when a value is assigned to variable uselessly and other logical problems you can detect using this technique.
How not(!) to Build Real-time Apps
Node Congress 2024Node Congress 2024
10 min
How not(!) to Build Real-time Apps
Are you building a chat app, a way to see users’ online status or a real-time collaboration dashboard? All of these use cases have one thing in common: Somehow the user-facing application needs to be informed in real-time about events that happen on the backend of your application.In this talk, we’ll look closely at common approaches like polling, application-level updates and pub-sub systems. We’ll explain the tradeoffs with each approach and elaborate why another approach, called Change Data Capture (CDC), is the most elegant and robust way to achieve this.
Building a Network Stack for our Browser Extension
Node Congress 2024Node Congress 2024
19 min
Building a Network Stack for our Browser Extension
Engineering problems often repeat themselves in places you wouldn't expect. Sometimes the best solution has already been invented, in a different corner of the software engineering domain. In this talk, we show how and why we mirrored the TCP/IP network stack to solve a communication problem between different components of a browser extension.

Workshops on related topic

Build React-like apps for internal tooling 10x faster with Retool
JSNation Live 2021JSNation Live 2021
86 min
Build React-like apps for internal tooling 10x faster with Retool
Workshop
Chris Smith
Chris Smith
Most businesses have to build custom software and bespoke interfaces to their data in order to power internal processes like user trial extensions, refunds, inventory management, user administration, etc. These applications have unique requirements and often, solving the problem quickly is more important than appearance. Retool makes it easy for js developers to rapidly build React-like apps for internal tools using prebuilt API and database interfaces as well as reusable UI components. In this workshop, we’ll walk through how some of the fastest growing businesses are doing internal tooling and build out some simple apps to explain how Retool works off of your existing JavaScript and ReactJS knowledge to enable rapid tool building.
Prerequisites:A free Retool.com trial accountSome minimal JavaScript and SQL/NoSQL database experience
Retool useful link: https://docs.retool.com/docs