MAISON CODE .
/ Performance · Webpack · Javascript · React · Core Web Vitals

Tamaño del paquete: la dieta para tu JavaScript

JavaScript es el recurso más caro de la web. Una guía técnica sobre Tree Shaking, Code Splitting y cómo usar Partytown para sobrevivir al apocalipsis de los scripts de terceros.

AB
Alex B.
Tamaño del paquete: la dieta para tu JavaScript

“El sitio es rápido en mi MacBook Pro.” Esta es la frase más peligrosa en ingeniería frontend. Tu MacBook Pro tiene un chip M3 Max. Analiza 1 MB de JavaScript en 50 ms. Tu usuario tiene un Samsung Galaxy A15 de €200. Analiza ese mismo 1 MB en 2,5 segundos. Durante esos 2,5 segundos, el hilo principal se congela. El usuario hace clic en “Agregar al carrito”. No pasa nada. Se van.

En 2025, la velocidad de la red (4G/5G) rara vez será el cuello de botella para el comercio electrónico. La CPU es el cuello de botella. Y la métrica que rastrea esto es Interacción con la siguiente pintura (INP). Para corregir INP, debe reducir la carga útil de JavaScript.

En Maison Code Paris, aplicamos presupuestos estrictos: <100 KB de carga inicial.

Por qué Maison Code habla de esto

En Maison Code Paris, actuamos como la conciencia arquitectónica de nuestros clientes. A menudo heredamos stacks “modernos” construidos sin una comprensión fundamental de la escala.

Discutimos este tema porque representa un punto de inflexión crítico en la madurez de la ingeniería. Implementarlo correctamente diferencia un MVP frágil de una plataforma resistente de nivel empresarial.

1. El costo de las importaciones: sacudir los árboles

Tree Shaking (Eliminación de código muerto) es el proceso de eliminar las exportaciones no utilizadas de su paquete. Pero no funciona por arte de magia. Debes escribir código que sea “Shakeable”.

La trampa del archivo de barril

A los desarrolladores les encantan los “Barrel Files” (“index.ts” que exporta todo). Destruyen Tree Shaking.

Mal patrón:

// componentes/index.ts
exportar * desde './Botón';
exportar * desde './Carrusel'; // Componente gigante de 50kb
exportar * desde './Table';

// aplicación.tsx
importar {Botón} desde './components';

En muchas configuraciones de paquetes (especialmente Webpack más antiguo), la importación de “Botón” también incluirá “Carrusel” en el paquete, debido a limitaciones de detección de efectos secundarios.

Solución: Importaciones directas o configuración cuidadosa de sideEffects: false en package.json.

La trampa de la biblioteca (Lodash)

importar {mapa} desde 'lodash'; extrae toda la biblioteca de 70 KB. Utilice lodash-es o importaciones específicas: importar mapa desde 'lodash/map';. Aún mejor, utilice métodos de matriz nativos. [].map() cuesta 0 bytes.

2. División de código: rutas de carga diferida

¿Por qué enviar el código del “Panel de administración” a un cliente que acaba de comprar una camiseta? Usamos División de código basada en rutas.

En Next.js (App Router), esto sucede automáticamente para los archivos page.tsx. En Vite/React Router, debes usar lazy().

importar {perezoso, Suspenso} desde 'reaccionar';

// Esta importación dinámica crea un fragmento separado (por ejemplo, Settings.chunk.js)
const ConfiguraciónPágina = lazy(() => import('./pages/Configuración'));

función aplicación() {
  regresar (
    <Rutas>
      <Ruta de ruta="/" elemento={<Inicio />} />
      <Ruta ruta="/configuración" elemento={
        <Reserva de suspenso={<Spinner />}>
          <Página de configuración/>
        </Suspenso>
      } />
    </Rutas>
  );
}

División a nivel de componente

¿Su “Visor de modelos 3D” es pesado? No lo cargue al cargar la página. Cárgalo al interactuar.

const ModelViewer = dinámico(() => import('./ModelViewer'), { ssr: false });

función PáginaProducto() {
  const [show3D, setShow3D] = useState(false);

  regresar (
    <>
      <button onClick={() => setShow3D(true)}>Ver en 3D</button>
      {mostrar3D && <ModelViewer />}
    </>
  );
}

El JS pesado sólo se descarga cuando el usuario realmente lo solicita.

3. Visualizando la hinchazón

No puedes arreglar lo que no puedes ver. Usamos @next/bundle-analyzer (o rollup-plugin-visualizer). Ejecútelo antes de cada implementación.

Encontrarás horrores:

  • ¿Tres.js dentro del paquete de la página de inicio?
  • ¿Moment.js locales? (Utilice la API date-fns o Intl).
  • ¿Faker.js en producción? (Debería ser una dependencia de desarrollo).

Normalmente reducimos el tamaño del paquete en un 30% simplemente eliminando las dependencias no utilizadas que se encuentran en el visualizador.

4. Scripts de terceros: la solución “Partytown”

Optimicó el código de su aplicación a 50 KB. Perfecto. Luego el equipo de marketing agrega GTM (Google Tag Manager). GTM inyecta:

  • Píxel de Facebook (40 KB)
  • Píxel de TikTok (50 KB) *Hotjar (70 KB)
  • Klaviyo (40 KB)
  • Gorgias (200KB)

De repente, su hilo principal queda bloqueado por 500 KB de scripts de marketing. La solución es Arquitectura fuera del subproceso principal.

Usamos Partytown. Ejecuta scripts de terceros en un Web Worker. Proporciona acceso DOM (por ejemplo, document.cookie) desde el trabajador al hilo principal a través de XHR (espera atómica) sincrónico.

// diseño.tsx (Siguiente.js)
importar {Validación} desde './Partytown';

<Cabeza>
  <Partytown debug={true} forward={['dataLayer.push']} />
</cabeza>
<Guión
  src="https://www.googletagmanager.com/gtm.js?id=GTM-XXXX"
  type="text/partytown" // Atributo mágico
/>

Resultado: el píxel de Facebook se ejecuta en un hilo en segundo plano. Calcula los datos de seguimiento sin congelar el botón “Agregar al carrito”. El INP mejora dramáticamente.

5. Formatos modernos: envío menos código

Los Polyfills están obsoletos

¿Es compatible con Internet Explorer 11? No. Dejar de enviar polyfills para Promise, Map, Set, fetch. Establezca su objetivo de “lista de navegadores” en “valores predeterminados, no en IE 11”. Esto elimina ~30 KB de basura heredada.

Compresión Brotli

Gzip es bueno. Brotli es mejor. Brotli (br) comprime JavaScript ~20% mejor que Gzip. Asegúrese de que su CDN (CloudFront/Vercel) tenga Brotli habilitado.

6. Optimización de imágenes: la carga útil oculta

JavaScript es el cuello de botella de la CPU, pero las imágenes son el cuello de botella del ancho de banda. Si carga un PNG de 2 MB en una conexión 4G, la descarga de JS se retrasa. Estrategia:

  1. Formato: utilice AVIF. Es un 30% más pequeño que WebP.
  2. Carga diferida: <img loading="lazy"> para todo lo que se encuentra debajo de la página.
  3. Dimensiones: establezca siempre “ancho” y “alto” para evitar cambios de diseño (CLS).
  4. CDN: use Cloudinary o Imgix para cambiar el tamaño sobre la marcha. imagen.jpg?w=400&q=auto

7. Estrategia de carga de fuentes

Las fuentes bloquean el procesamiento. Si sus archivos OTF son de 100 KB, el texto es invisible (FOIT) durante 2 segundos. Reparar:

  1. Autoanfitrión: no utilice Google Fonts. La búsqueda de DNS te atrapa.
  2. Subconjunto: elimine los glifos que no utilice (por ejemplo, caracteres cirílicos).
  3. Intercambio de pantalla: pantalla de fuente: intercambio;. Muestra la fuente alternativa inmediatamente.
  4. Precarga: <link rel="preload" href="/font.woff2" as="font"> solo para la fuente del encabezado.

8. El DX “Costo de Importación”

Los desarrolladores son vagos. Si pueden importar una biblioteca, lo harán. Instale la extensión Importar costo en VS Code. Muestra el tamaño de la importación en línea a medida que escribe.

importar {formato} desde 'fecha-fns'; // 14 KB (comprimido) Este ciclo de retroalimentación instantánea hace que los desarrolladores lo piensen dos veces antes de agregar una dependencia.

8. El futuro: reanudabilidad (Qwik)

El defecto fundamental de React es la Hidratación. Hidratación significa: “Descargue el HTML. Luego descargue el JS. Luego ejecute el JS para adjuntar detectores de eventos”. Es un trabajo duplicado. Los marcos como Qwik introducen la Resumabilidad. No hay hidratación. El detector de eventos se serializa en HTML: <button on:click="./chunk.js#handleClick">. El JS para el controlador de clics solo se descarga cuando el usuario realmente hace clic. Si nunca hacen clic, descargas 0 KB de JS. Este es el ideal “O(1) JavaScript”. Estamos observando esto de cerca para 2026.

9. Componentes del servidor React (RSC)

Next.js App Router utiliza RSC. RSC le permite mantener las dependencias en el servidor. Antes de RSC: importar {formato} desde 'date-fns' -> El paquete de cliente aumenta en 20 KB. Después de RSC: importar {formato} desde 'date-fns' -> Se ejecuta en el servidor. Representa HTML. El paquete de clientes aumenta en 0 KB. Estrategia: Mover todo el formato pesado, la obtención de datos y el procesamiento de rebajas a los componentes del servidor. Mantenga los componentes del cliente solo para interactividad (useState, useEffect). Los “nodos hoja” deben ser componentes del cliente. Los “nodos de contenedor” deben ser componentes de servidor.

9. La regla del presupuesto de 100 kb

Tenemos una regla estricta: No puede fusionar un PR que lleve el paquete inicial a más de 100 kb. Hacemos cumplir esto a través de CI. La comprobación de bundlesize falla:

“Error: el paquete principal es de 105 kb. El límite es de 100 kb”. Esto obliga a una conversación. “¿Realmente necesitamos esta biblioteca? ¿Podemos cargarla de forma diferida?” Si no lo aplica, el paquete crecerá infinitamente. Cada KB debe luchar por su vida.

10. Conclusión

El rendimiento no es algo “agradable de tener”. Son ingresos. Amazon descubrió que 100 ms de latencia les costaban el 1% de las ventas. Latencia de JavaScript IS inflada. Trate su presupuesto de Tamaño del paquete como un presupuesto financiero. Si lo excede, deberá “devolverlo” eliminando el código.


¿Su sitio es pesado?

¿Su puntuación de Lighthouse Performance muestra “Reducir JavaScript no utilizado”?

Auditar mi paquete. Lea sobre Core Web Vitals y Edge Computing.

El rendimiento no es algo “agradable de tener”. Son ingresos. Amazon descubrió que 100 ms de latencia les costaban el 1% de las ventas. Latencia de JavaScript IS inflada. Trate su presupuesto de Tamaño del paquete como un presupuesto financiero. Si lo excede, deberá “devolverlo” eliminando el código.

¿Su sitio es pesado?

¿Su puntuación de Lighthouse Performance muestra “Reducir JavaScript no utilizado”?

Auditar mi paquete. Contrate a nuestros arquitectos.