Turbopack Persistent Caching


1. Tobias Koppers sobre TurboPack y el Almacenamiento en Caché Persistente
Tobias Koppers del equipo de Vercel TurboPack discute la implementación del almacenamiento en caché persistente para el desarrollo de aplicaciones web a largo plazo, previendo un crecimiento significativo en el tamaño de las aplicaciones durante la próxima década.
Mi nombre es Tobias Koppers y trabajo para Vercel en el equipo de TurboPack. Y quiero hablarles sobre la historia del almacenamiento en caché persistente que implementamos para TurboPack. Así que cuando comenzamos a trabajar en TurboPack, queríamos construir algo para los próximos 10 años. Así que primero reflexionamos sobre los últimos 10 años de desarrollo web, y notamos que las aplicaciones web han crecido mucho. Hace 10 años, algunas personas incluso usaban texto de script normal y ni siquiera usaban un bundler en el desarrollo web, o usaban Grunt o Gulp para concatenar cosas. Así que ahora extrapolamos eso para los próximos 10 años. Veremos que las aplicaciones web serán enormes en tamaño, y eso será un problema.
2. AI's Impact on TurboPack Build Vision
El papel de la IA en la escritura de código, la visión de TurboPack para construcciones instantáneas, los desafíos en el control de la construcción y el cambio hacia el rendimiento incremental con almacenamiento en caché para construcciones más rápidas.
Y creamos esto básicamente hace dos años, y ahora si miras esto retrospectivamente, tiene mucho más sentido. Porque ahora ves que la IA está escribiendo todo el código, y puedes esperar que la IA escriba mucho más código en los próximos 10 años. Así que tiene sentido. Pero también teníamos este objetivo de construcciones instantáneas para TurboPack. Teníamos esta visión de que nadie debería esperar nunca a que una construcción termine. Básicamente deberías enviar tu código, e instantáneamente puedes compartir directamente ese código en la vista previa de implementación o la construcción terminada con tus compañeros de trabajo. O incluso la IA envía código y quiere compartirlo directamente contigo en una especie de ciclo de retroalimentación.
Así que esto está un poco en contraste entre sí, y hay incluso más problemas con eso. Ni siquiera podemos controlar todo el proceso de construcción. Queremos permitir plugins personalizados, transformaciones personalizadas, como los cargadores de webpack, o ni siquiera podemos controlar el código del usuario y todas las bibliotecas NPM que nos lanzan. Así que con todo eso, todavía podemos usar Rust para escribir código nativo, solo paralelismo para usar otros núcleos, pero eso no nos ayudará con todos estos problemas. Porque si hay algo lento en un plugin personalizado o en un cargador de webpack o en cualquier cosa que no tenemos control, eso romperá nuestro objetivo de construcciones instantáneas.
Así que necesitamos repensar eso, y necesitamos un enfoque diferente. Si tenemos que aceptar que algo de la construcción es lento, ¿cómo podríamos aún lograr nuestro objetivo de construcción instantánea? Así que nuestro enfoque fue que queríamos cambiar el enfoque. En lugar de centrarnos en el rendimiento bruto de la construcción, queríamos centrarnos en el rendimiento de la construcción incremental. Así que tal vez tengamos que aceptar que algunas cosas son lentas en la construcción inicial, pero podemos al menos asegurarnos de que nunca las volvamos a ejecutar. Básicamente lo hacemos más rápido que todas las otras construcciones, todas las construcciones incrementales. Y de hecho, en la práctica, casi todas las construcciones pueden tener un caché. En el desarrollo local y el servidor de desarrollo o algo, puedes tener un disco accesible, podemos almacenar cosas allí, podemos almacenar en caché cosas. E incluso en construcciones CI, casi todos los buenos proveedores de CI tienen la capacidad, la infraestructura para proporcionarte algunas capacidades de almacenamiento en caché.
3. TurboPack Performance Strategy
Dos partes del lema para el rendimiento de TurboPack: Hacer que las construcciones incrementales sean rápidas y que cada construcción sea incremental. Necesidad de almacenamiento en caché persistente para construcciones incrementales y desafíos con la confianza del usuario en el sistema.
Eso es genial. Así que se nos ocurrió este lema de dos partes para nuestra visión o motivación para el rendimiento de TurboPack, que es hacer que las construcciones incrementales sean rápidas y hacer que cada construcción sea incremental. Y nuestra idea era que tal vez este tipo de enfoque tiene el potencial de cumplir nuestro objetivo de construcciones instantáneas. Incluso con cosas que son lentas o cosas sobre las que no tenemos control, o incluso el tamaño de las aplicaciones web en 10 años. Así que veamos qué necesitamos para lograr eso.
Quiero mirar la segunda parte del lema primero, como hacer que cada construcción sea incremental. Así que para hacer que cada construcción sea incremental, lo primero que necesitamos es algún tipo de almacenamiento en caché persistente. El caché en memoria tal vez sea lo suficientemente bueno para el desarrollo porque allí, la mayoría de las construcciones están dentro de un solo proceso y no reinicias tu servidor de desarrollo tan a menudo. Pero para obtener la historia completa, necesitamos algo que sea persistente. Quieres reiniciar tu servidor de desarrollo y aún tener una construcción incremental al reiniciar.
Y para las construcciones CI, ni siquiera tenemos un proceso en ejecución. Necesitamos algo que funcione a través de reinicios del proceso. Necesitamos un caché persistente. Podrías pensar, está bien, ahora el caché es persistente, ahora cada construcción es incremental. Al menos todo es posible. Pero no tan rápido. Hay un problema, que es el usuario. Porque el usuario puede eliminar el caché, puede desactivar el almacenamiento en caché. Y de hecho lo harán si no confían en el sistema.
4. Asegurando Construcciones Incrementales Confiables y Granulares
Construir un sistema confiable para la confianza de los usuarios, evitar prácticas incorrectas de almacenamiento en caché, centrarse en la persistencia, confianza y granularidad para construcciones incrementales.
Si no están 100% seguros de que sus cambios se reflejan correctamente en el sistema de construcción, podrían limpiar el caché solo para asegurarse de que no es su culpa o es como tal vez es un fallo del bundle o lo que sea. Así que realmente queremos construir algo que sea realmente confiable. Queremos construir un sistema confiable para que los usuarios tengan la confianza de que sus cambios se reflejan correctamente y el almacenamiento en caché no es el problema. Así que básicamente queremos evitar todos los trucos, soluciones alternativas o incluso compensaciones para un mejor rendimiento que no son 100% correctas desde la perspectiva del almacenamiento en caché. Ni siquiera podemos confiar en nosotros mismos para escribir correctamente la lógica del código de invalidación de caché. Porque eso también es una fuente común de errores.
Así que estos dos ingredientes, como la persistencia y la confianza, son lo que pensamos que son los ingredientes principales para hacer que cada construcción sea incremental. Pero también queremos mirar la primera parte del modelo, como hacer que las construcciones incrementales sean rápidas. Si necesitamos resumir ese tipo de lema en un solo ingrediente, sería granular. Así que queremos que granular signifique que solo tocamos cosas que están afectadas por un cambio y no tocamos todo solo porque podemos. Así que para las invalidaciones de caché podría significar que solo queremos invalidar y por lo tanto recomputar el trabajo que está afectado por el cambio. Eso significa que en la práctica realmente queremos hacer la mínima cantidad de trabajo que se necesita para aplicar los cambios o hacer una construcción incremental.
Porque hacer el trabajo rápido es genial, pero no hacer trabajo es aún mejor. Así que ese es el lema de eso. Eso podría ser simple para cambios simples como cambiar alguna línea de código fuente. Pero también queremos que funcione para todo tipo de cambios. Eso significa que podrías hacer cambios complejos, como cambiar una dependencia o cambiar tu configuración. Ese tipo de cambio también debería reflejarse de manera granular. Eso también podría ser más interesante con construcciones de producción, donde tienes este tipo de optimizaciones que funcionan en toda la aplicación, como un chunk compartido o algo así, donde un simple cambio, como cambiar algunas importaciones, puede tener efectos de amplio alcance en la compilación, en la aplicación de salida. Así que queremos manejar todo eso.
5. Efficient Granular Cache Handling in TurboEngine
Evitar la invalidación completa del caché centrándose en la granularidad en el acceso al caché. TurboEngine automatiza el manejo del caché, rastrea dependencias y gestiona eficientemente la invalidación del caché. Al recomputar solo las partes afectadas, el sistema optimiza el rendimiento y reduce el cálculo innecesario.
Nunca queremos estar en el escenario donde necesitamos invalidar todo el caché porque alguien cambió la opción de configuración o algo así. O ni siquiera cambiar una gran parte de la compilación porque ocurren algunos cambios. Pero la granularidad también es importante en otras áreas, como para el acceso al caché. Básicamente queremos tener acceso granular al caché.
Nunca quieres restaurar todo el caché persistente solo porque se cambió un comando simple o algo así. Queremos acceder solo a lo que realmente necesitamos del caché, así que solo acceder a lo que está afectado por el cambio. Ahora tenemos estos ingredientes o los requisitos para eso. Lo que los desarrolladores suelen hacer cuando tienen algún tipo de desafío, generalmente construyen un framework.
Básicamente lo que hicimos, construimos este motor llamado TurboEngine, que es el motor de caché que impulsa TurboPack. La idea de eso es que queremos permitirnos a nosotros, o al desarrollador de TurboPack, poder trabajar con caché reducido en un patrón sin miedo y sin preocuparse por todas estas tareas complejas sobre invalidación de caché, implementables, y todo eso. Básicamente este framework nos da las primitivas para optar por el caché a nivel de función para que podamos construir un sistema de caché realmente granular y cosas de invalidación realmente granulares.
6. Automatic Granular Cache Invalidation
El sistema automatiza la invalidación del caché, rastrea las dependencias para mejorar la eficiencia y asegura una recomputación granular. Con un sofisticado gráfico de dependencias, los cambios desencadenan una recomputación eficiente, optimizando el rendimiento. El enfoque se centra en tocar solo las partes afectadas, mejorando el rendimiento y minimizando el cálculo innecesario.
La verdadera magia ocurre en lo que respecta a la invalidación del caché en el sistema. No te permite escribir código de invalidación de caché. Básicamente lo hace automáticamente por ti. Rastrea lo que lees en una función, qué tipo de cosas de Excel lees, qué tipo de valores de otras funciones lees, y construye un gráfico de dependencias de toda esta ejecución. Básicamente, depende del gráfico de la ejecución de la compilación. Y con este gráfico de dependencias, puede hacer implementables realmente eficientes.
Todo en este ejemplo es una versión realmente simplificada del gráfico de dependencias. En la práctica, es como miles de millones de nodos. Pero en esta versión simplificada, podría comenzar con un archivo que ha cambiado, entonces uno de estos nodos, los llamamos tareas en este caso, se invalida y se vuelve a computar, y eso podría causar que más cosas se invaliden. Por ejemplo, cuando el archivo ha cambiado, el module.js ha cambiado, el análisis podría necesitar ser re-ejecutado, porque el contenido ha cambiado. Así que básicamente, este cambio sube por el gráfico. Sigue los bordes dependientes, y eso podría invalidar más cosas.
Pero también podría suceder que leamos algunos datos en caché existentes sin cambios, o algo que no tenga ningún efecto en eso. Si solo cambio algún tipo de línea de código sin tocar las importaciones, tal vez el chunking no tenga más actualizaciones, o se cancele allí. Pero al final, todo el asunto termina y se vuelve a computar, como hacer un implementable solo tocando las partes que son afectadas por el cambio. Y eso es lo que quiero decir con granularidad. Así que hacemos un implementable solo tocando, y solo leyendo, y solo accediendo a nodos del gráfico que son afectados por el cambio. Y eso tiene muchos beneficios.
7. Efficient Persistent Cache Integration
El sistema optimiza el rendimiento al computar solo los elementos necesarios, mejorando la eficiencia y apoyando el almacenamiento en caché persistente. Almacenar el estado del gráfico en disco usando un almacén de clave-valor facilita el acceso eficiente a los datos. La arquitectura se integra perfectamente con el almacenamiento en caché persistente, asegurando un rendimiento rápido de los implementables.
Es realmente genial para el rendimiento, porque solo volvemos a computar lo que realmente se necesita, y no tocamos otras cosas en absoluto. Y también es excelente para el almacenamiento en caché persistente, porque solo necesitamos restaurar cosas del caché que se accede, y no tenemos que tocar todas estas cosas en gris, y nodos en gris en este caso. Y generalmente, las cosas que se ven afectadas por el cambio son mucho, mucho más pequeñas que el gráfico completo en absoluto.
Esto también nos da el beneficio de tener un rendimiento de implementables independiente de la aplicación. Así que el gráfico podría ser realmente grande, pero si el cambio solo afecta a un grupo de nodos, eso debería ser realmente rápido. Así que ahora tenemos el motor para implementables. Queremos agregar almacenamiento en caché persistente además de eso.
Así que veamos cómo se ve el caché en este motor. Así que el caché no es básicamente este gráfico que ves en esta imagen aquí. Es básicamente el caché en este tipo de sistema.
8. Graph State Persistence and Database Optimization
El estado del gráfico se almacena en caché, los nodos contienen datos, requiriendo persistencia en disco usando almacenamiento de clave-valor y base de datos. El uso inicial de LMDB para el almacenamiento funcionó para los implementables, asegurando un acceso rápido. Sin embargo, volcar todo el gráfico en la base de datos causó construcciones iniciales lentas y tamaños de disco grandes. La transición a una base de datos más eficiente como RoxDB fue esencial para la mejora.
El estado del gráfico es lo que se almacena en caché, y los nodos almacenan los datos. Así que para hacerlo, si quieres agregar almacenamiento en caché persistente, básicamente queremos persistir este gráfico en disco. Y en realidad no es tan complicado. Así que podemos simplemente usar un simple almacén de clave-valor, como para cada nodo, almacenar los datos, almacenar los bordes, y esas cosas. Y básicamente, necesitamos una base de datos para almacenar eso. Y la base de datos funciona principalmente como volcar todo al disco, y luego acceder a él desde la base de datos nuevamente. Así que básicamente lo que hacen las bases de datos.
Así que genial. Así que comenzamos con, necesitamos un simple almacén de clave-valor. Usamos una base de datos simple. Usamos LMDB en este caso en nuestra primera iteración. Y eso funciona. Así que funcionó para la parte implementable. Así que almacenamos todo en disco, y luego accedimos solo a las partes que se necesitan. Como almacenar algunas claves de la base de datos es barato. Eso funciona. Así que los implementables son realmente rápidos. Así que toda la arquitectura de los implementables funciona para el almacenamiento en caché persistente. Tiene sentido, porque ya probamos eso para el almacenamiento en caché en memoria, y eso también funcionó. Así que eso funciona.
Pero había un gran problema con eso. Y las construcciones iniciales eran realmente lentas. Y sí, el problema es que básicamente tenemos que volcar todo el gráfico inicial al disco, y eso es como millones de nodos, y volcar millones de claves en la base de datos. No es lo más rápido que puedes hacer. También tiene un problema de que el tamaño del disco era realmente grande, porque un gran gráfico almacenado en la base de datos creó una gran base de datos. Así que iteramos más en eso. Probamos una mejor base de datos. Tal vez pensaste, tal vez la base de datos no es la cosa perfecta. Usamos una base de datos realmente simple, incrustada. Así que usemos una base de datos de prueba lista para producción, RoxDB en este caso, para meta.
9. Custom Persistent Layer Creation
Resolvió problemas de tamaño de disco y velocidad de construcción inicial. El patrón de acceso a la base de datos llevó a la creación de una capa persistente personalizada. La capa personalizada optimizó la sobrecarga de la construcción inicial e incorporó características existentes de la base de datos. Las pruebas de rendimiento mostraron una mejora significativa en los tiempos de construcción.
Y eso resolvió algunas cosas. Tiene compresión incorporada, por lo que resuelve este problema de tamaño de disco. También es mucho más rápido que MDB, por lo que también resuelve el problema de la construcción inicial. La construcción inicial ahora tenía una velocidad aceptable. Básicamente, agrega un 50% de sobrecarga a la construcción. No está bien, pero podría ser aceptable, porque al final, la mayoría de las construcciones serán incrementales de todos modos, y eso es rápido. Suena bien.
Sí, pero no queríamos detenernos ahí. Queríamos trabajar más en eso. Y notamos que nuestro patrón de base de datos es un patrón de acceso realmente inusual. Usualmente las bases de datos están optimizadas para... Escribo algunas cosas y leo muchas cosas, por lo que son cargas de trabajo pesadas en lectura. Y nuestra carga de trabajo, al menos para la construcción inicial, era como... No teníamos lecturas en absoluto, porque no había base de datos al principio. Y luego escribimos una cantidad gigantesca de datos en la base de datos. Y para construcciones incrementales, es solo una pequeña cantidad de datos que leemos y escribimos que funcionó bien. ¿Pero la construcción inicial? Problemática.
Así que no pudimos encontrar una base de datos que tuviera este patrón de acceso diferente, así que terminamos escribiendo nuestra propia capa persistente. No es una base de datos completa. Es más como una versión más simple especializada para un patrón de uso, y hace muchos compromisos que está optimizada para nuestro uso. Como, no tenemos escrituras paralelas y esas cosas, por lo que podemos optimizar algunas cosas. Y eso básicamente resolvió esa sobrecarga de la construcción inicial y la hizo mucho más pequeña. Así que, eso no era un rendimiento aceptable. También tomamos muchas cosas de la base de datos existente, como la compresión y esas cosas. También hicimos pruebas de rendimiento para una aplicación de cliente a gran escala real, que tiene un tiempo de construcción de un minuto.
10. Optimizing Build Time Efficiency
LMDB a WuxDB para una persistencia más rápida. La capa personalizada mejoró el rendimiento. Mejoras en memoria y construcción incremental con el uso de WuxDB y solución personalizada.
Si miras los números aquí, comenzamos con LMDB para este tiempo de construcción de un minuto. Tenía tres minutos de tiempo de persistencia. Eso parece realmente grande, y era algo inaceptable para nosotros. Y luego WuxDB mejoró mucho eso. Es como seis veces más rápido para persistir. Así que, ahora la construcción de un minuto solo se extendió en un 50% del tiempo de construcción para persistir. Y con nuestra capa personalizada, pudimos mejorar aún más al mejorarla por otro factor de 3x para lograr un mejor rendimiento.
También ves que la memoria mejoró con eso, porque WuxDB almacenaba todo en una tabla de memoria además de en un disco, y eso no es lo más optimizado para hacer. También tiene problemas como que asigna todo en un lote blanco primero antes de comprometerlo. Así que hicimos muchas mejoras en eso. Y también ves el rendimiento de la construcción incremental. Eso siempre fue bueno porque es más bueno por diseño porque no leemos mucho de la base de datos. No depende tanto de la base de datos, pero pudimos mejorarlo un poco al no usar LMDB, sino WuxDB y nuestra propia solución.
Eso es genial. Así es como implementamos el almacenamiento en caché persistente con nuestra base de datos. Hay algunas otras capas sobre eso. Tenemos algún mecanismo de instantáneas para tomar instantáneas de la compilación mientras estás trabajando en ella porque nunca queremos detener el proceso del servidor de desarrollo solo para persistir algo. Queremos tomar atómicamente alguna instantánea del gráfico y luego persistirla en segundo plano para que no te detengas o tu HMR no se vea afectado al hacer un almacenamiento en segundo plano o al hacer una instantánea o almacenamiento del caché persistente. Pero si miras esto en un alcance más amplio, el almacenamiento en caché persistente agrega algunos problemas más o desafíos.
11. Challenges of Incremental Builds
Los reinicios de procesos introducen nuevos desafíos. La granularidad en la aplicación de cambios es crucial. Las optimizaciones de producción y la persistencia del almacenamiento en caché plantean desafíos ya que todo es persistente.
Ahora tienes reinicios de procesos que añaden muchos más cambios diferentes a eso. Antes, la mayoría de los cambios consistían en cambiar un archivo y esas cosas. {{^}}Ahora tienes reinicios de procesos que cambian el entorno, las variables de entorno podrían cambiar, la creación de configuraciones podría cambiar. Así que todos estos nuevos desafíos tenemos que hacer nuestro YTOPIC de una manera que sea granular para aplicar estos cambios. Especialmente los archivos finales son realmente problemáticos porque los archivos finales podrían estar integrados en cada módulo. Así que no queremos invalidar cada módulo porque algunos archivos finales han cambiado. Así que eso fue un poco complicado.
También están estas optimizaciones de producción de las que ya hablé, que son desafiantes de aplicar como cambios a nivel granular. Hay más cosas a considerar como parches de red durante la construcción, como tal vez obtienes algo de Google fonts, como un archivo de fuente, cuándo invalidar eso, ¿tenemos que invalidar todo, como el almacenamiento en caché y esas cosas son relevantes cuando no puedes reiniciar el servidor de desarrollo. La persistencia del almacenamiento en caché añade muchos nuevos desafíos a eso porque usualmente puedes solucionar todos los problemas reiniciando el servidor de desarrollo, pero ahora todo está persistente, así que no podemos aceptar ninguno de estos problemas de que el caché no se borre correctamente o no se invalide correctamente porque todo es persistente y no queremos que elimines el caché.
También hay un desafío completamente nuevo cuando se trata de CI, cuando realmente has pasado algún tiempo subiendo y descargando el caché de construcción, lo que también podría afectar tu tiempo total. En general, también es importante mirar todo el ciclo de vida de despliegue, no solo en la construcción de TurboPack, porque usualmente la construcción de TurboPack es a menudo la mayor parte de su despliegue, pero allí, cuando tenemos construcciones incrementales para TurboPack, entonces podría no ser el caso más. La construcción de TurboPack es realmente rápida, pero luego tenemos todos los otros desafíos que también necesitan hacerse incrementales, como queremos hacer que la clonación de Git sea incremental, la descarga del caché de construcción pero tal vez solo descargar lo que necesitamos del caché de construcción. Tienes el estilo de gestión de paquetes, podemos hacer eso incremental también, como usar un caché para eso. Hay todo este paso de pre-renderizado, paso de pre-generación, que ocurre usualmente después de la construcción que puede ser almacenado en caché, no puede ser almacenado en caché, sí, depende. Así que muchas otras cosas que tienes que considerar al usar esta herramienta de construcción incremental. Colaboramos con otros equipos para hacer esto posible para que todos podamos beneficiarnos de eso.
QnA
TurboPack Expansion and Differentiation
TurboPack es de código abierto y se está expandiendo a un empaquetador de propósito general. El enfoque único de almacenamiento en caché de abajo hacia arriba distingue a TurboPack de otras herramientas. La arquitectura de TurboPack difiere significativamente de Webpack, enfatizando los beneficios a largo plazo de una nueva herramienta.
Así que gracias por invitarme, espero que también haya sido interesante. Bien, primero, vamos con la más votada. Para TurboCache, había servidores de código abierto, ¿esta nueva cosa será de código abierto también o bloqueo de proveedor? ¿Qué es TurboCache para TurboPack tal vez? Así que sí, TurboPack ya es completamente de código abierto, por lo que actualmente solo funciona con Next.js pero queremos hacerlo disponible como un empaquetador de propósito general, por lo que será una herramienta independiente también. Pero ya es de código abierto en este sentido. Bien, genial. Entonces, la siguiente pregunta sería ¿cómo se compara esto con otras herramientas de monorepo como Rush en términos de caché de construcción y características de co-construcción? Sí, así que nuestro enfoque de almacenamiento en caché es un poco diferente, nuestra construcción incremental es un poco diferente. Usualmente construimos de abajo hacia arriba, por lo que invalidamos como los nodos hoja y construimos hacia arriba. Y la mayoría de las otras herramientas, hacen el almacenamiento en caché de una manera diferente, a menudo lo hacen como de arriba hacia abajo. Así que comienzan con la compilación y buscan cosas en el caché y cancelan por eso. Así que eso es un poco diferente. Pero en general, las herramientas de monorepo están más en un nivel superior, como en un monorepo trabajan en nivel de script y TurboPack es más como en nivel de archivo fuente, así que como una herramienta de nivel de empaquetador. Sí, así es como se compara, supongo.
Bien, sí, estoy bastante seguro de que eso respondió la pregunta. Y sí, tenemos tiempo para muchas más preguntas. Así que Bobby ha preguntado, ¿la construcción incremental con TurboPack está relacionada con la federación de módulos? La característica en sí no está relacionada con la federación de módulos, pero eventualmente probablemente queramos soportar la federación de módulos en TurboPack también, así que similar a Webpack, pero es una característica diferente, no está relacionada con las construcciones incrementales y esas cosas. Pero a veces la gente usa la federación de módulos para un mejor rendimiento de construcción, así que si eso se usa solo para el rendimiento de construcción, entonces podría ser un reemplazo usar construcciones incrementales con TurboPack. Interesante. Bien. La siguiente será, ¿pueden estas características ser añadidas a Webpack en lugar de una nueva herramienta? Sí, así que intencionalmente bifurcamos, como no continuar trabajando en Webpack y mejorar eso, pero hicimos una nueva arquitectura y comenzamos TurboPack para poder usar la nueva arquitectura, así que como toda la arquitectura es realmente diferente de Webpack. Webpack es solo almacenamiento en caché de arriba hacia abajo, TurboPack usa almacenamiento en caché de abajo hacia arriba. Así que es realmente diferente, así que básicamente tomamos la decisión de no añadirlo a Webpack, sino escribir una nueva herramienta que tal vez sea más difícil de migrar, pero al final, esperamos que todos se beneficien de eso a largo plazo.
Enhancing TurboPack Framework Compatibility
Planes para que TurboPack soporte varios frameworks en el futuro. Enfoque actual en Next.js con planes para la integración de un empaquetador de propósito general. Disponibilidad de Next.js confirmada con el lanzamiento inminente de la función de caché persistente.
Bien. Tenemos otra pregunta votada, esta de Dennis. ¿Cuáles son los planes para que TurboPack sea más fácil de integrar con otros frameworks? Mi experiencia es que si no es React, Vue o Svelte, es un lío. Sí, actualmente eso es cierto. Así que actualmente nos centramos en hacer que TurboPack funcione con Next.js y actualmente solo funciona con Next.js, pero nuestro plan siempre fue, y sigue siendo, que queremos convertirlo en un empaquetador de propósito general y luego será más fácil integrarlo con otros frameworks.
Bien, ¿entonces al menos para el futuro esperamos eso? Es para el futuro, sí. Genial. Y por supuesto, hay más personas interesadas en el framework, así que preguntaron si habrá disponibilidad también para Next.js. Sí, eso ya está disponible para Next.js. La caché persistente aún no se ha lanzado. Hay una bandera secreta para habilitarla, pero se lanzará, como lo planeamos, en un mes. Pero sí, todavía estamos trabajando en la estabilidad de eso y cuando se considere lo suficientemente estable, entonces se lanzará. Perfecto, perfecto. Ya está completamente funcional, diría yo.
Clarifying TurboRepo and CI Feature Consideration
Confusión entre TurboRepo y TurboPack aclarada. TurboRepo y TurboPack son herramientas separadas. Consideración para la función de CI con caché persistente en la nube. Enfoque en mejorar el uso de memoria en TurboPack para aplicaciones más grandes en comparación con ESBuild.
Y, sí, también tenemos otra pregunta sobre si puedo usar TurboRepo Remote Cacher para compartir caché entre mis builds? Así que a menudo es un problema que la gente confunde TurboRepo con TurboPack. Son básicamente dos herramientas independientes, pero sí. No sé sobre TurboRepo. No puedo responder a esta pregunta, pero no confundan TurboRepo con TurboPack. Es una herramienta diferente y básicamente no está muy relacionada con la otra. Sí, el nombre tal vez no nos está ayudando.
Y Quentin también está preguntando, ¿será esto una función de CI a través de caché persistente en la nube? Sí, pensamos en eso. Actualmente es solo esto, pero habría beneficios de descargar bajo demanda la caché de build desde la nube y podríamos hacer eso. Depende de cómo sería el rendimiento de eso, pero es una consideración hacer algo así. Bien. Dije que todos ya están adelantados en todo lo que están construyendo.
Y sí, la siguiente pregunta es, mi Purl GitHub Action Runner tiene 40 de RAM. El uso de memoria ISO es bastante alto. ¿Es eso un punto de enfoque además de la velocidad? Sí, para este benchmark, usamos una aplicación realmente grande que tiene un mayor uso de memoria, por supuesto, no por la caché persistente, más porque el build simplemente es más grande. Y sí, es un punto de enfoque. Actualmente tenemos tal vez un uso de memoria demasiado alto en TurboPack y estamos trabajando en eso. Sí, pero cuatro gigabytes podrían no ser suficientes para una aplicación realmente grande. Bien. No sé. Sí, cómo... Oh, no, respondí mal, pero ¿cómo se compara con ESBuild? Puedes responder eso. Sí, ESBuild también es un bundler. Creo que nuestro enfoque es un poco diferente.
Comparing TurboPack and ESBuild Cache Granularity
Enfoque en builds incrementales sobre el rendimiento bruto de build como ESBuild. Énfasis en la integración personalizada. ESBuild sobresale en velocidad bruta en comparación con TurboPack. Granularidad detallada de caché con un enfoque basado en tokens, casi como de IA. Consideraciones sobre el impacto en el tiempo de build debido a la obtención de caché permanente.
Nos enfocamos más en builds incrementales mientras que ESBuild se enfoca más en el rendimiento bruto de build. También queremos permitir más integración personalizada, más cosas personalizadas, y por eso nuestro enfoque es diferente, como expliqué. Pero ESBuild también es una gran herramienta. Es súper rápida. Probablemente su velocidad bruta es mucho más rápida que TurboPack. Esperamos que seamos mejores en la parte de build incremental. Pero también es una gran herramienta. Sí.
Genial. Bien. Tengamos algunas más preguntas antes de que tengamos al próximo orador. Entonces, ¿cuál es la granularidad de caché? ¿Es por archivo, por módulo o por build? Es menor que por archivo. Así que lo tenemos basado en el nivel de función o implementación. Al menos por módulo, pero usualmente un módulo tiene de 50 a 100 funciones más pequeñas que hacen algo como analizar, archivar, extraer dependencias. Cada dependencia tiene su propio caché. La resolución tiene su propio caché. Es realmente granular. Y a veces tal vez incluso demasiado granular. Pero es realmente granular. Es casi basado en tokens.
Parece como IA. Y sí. Bobby está preguntando, ¿puede ser mayor el tiempo de build porque el caché permanente necesita ser obtenido cada vez? Sí. Depende del build. Si es un build realmente rápido, entonces a veces es más rápido simplemente hacer el build en lugar de tener caché persistente. Pero el beneficio de eso es usualmente que la descarga del caché de build ocurre antes del build. Puede ocurrir en paralelo al clonado de git y a la obtención de npm. Así que usualmente no pagas ningún tiempo por la descarga del caché de build.
TurboPack Cache Handling and Comparison with NX
Discusión sobre el proceso de descarga y carga de caché de build. Preocupaciones sobre la recolección de basura y comparación con otras aplicaciones en términos de uso de espacio en disco. Comparación con NX para monorepo y detalles sobre la base de código utilizada para el banco de pruebas de caché persistente.
Al menos lo que probé con implementaciones RESTful. Pero también depende de tu proveedor de CI. ¿Puede hacer la descarga en paralelo? ¿Puede hacer... ¿Tiene un paso bloqueante de descarga de caché de build? Y la carga de caché de build también suele ocurrir después de que se termina la implementación. Así que todo ya está listo, y luego en segundo plano subimos la caché de build. Así que no deberías tener ningún impacto por la descarga de caché de build. Bien.
Sí, tengamos un par más y luego podemos terminar aquí. Entonces, ¿cuándo ocurrirá la recolección de basura? ¿Debería preocuparme por llenar mi disco con la caché de TurboPax? Sí, esa es una buena pregunta. No tenemos recolección de basura para eso todavía. Podrías preocuparte por llenar un disco, pero comparado con otras aplicaciones, probablemente no sea eso, que llene el disco. Tal vez npm nodemodules esté llenando más tu disco que tu caché. Sí, probablemente el raspbian si no lo limpiaste, y hay muchos nodemodules allí. Eso también puede suceder. Bien.
Bobby también está preguntando, ¿cómo se compara TurboPax con NX para monorepo? Eso probablemente también sea una pregunta de TurboRepo. Creo que es confuso. Me saltaría eso. ¿Qué tamaño de base de código se utilizó para el banco de pruebas de caché persistente? Uno bastante grande. Uno de los más grandes que hemos encontrado. Creo que son 70,000 módulos. Así que de tamaño decente, y también bastante antiguo. Así que sí, probablemente haya muchas cosas heredadas allí y bibliotecas de iconos. Bastante genial, en realidad. Bueno, creo que podemos dejarlo aquí. Si tienes más preguntas para él, puedes ir al lugar, y puedes hacérselas en persona a él. Sí, muchas gracias, Tobias. Gracias por invitarme. Fue increíble. No.
Available in other languages:
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
Comments