Optimizando bundles: cómo llegamos a 12KB en producción
La optimización de bundles es una mezcla de buenas prácticas arquitectónicas, decisiones de build y la configuración adecuada del servidor. En este artículo explico las técnicas que usamos en DailyMP para reducir el tamaño de nuestra salida y por qué, tras todas las optimizaciones, el bundle se sirve en producción con apenas ~12KB transferidos gracias a Brotli y a una entrega estática cuidadosa.
Diagnóstico inicial: medir antes de tocar
Antes de optimizar, medimos. Usamos ANALYZE=true npm run build -- --webpack para generar reportes en .next/analyze/ y du para inspeccionar los chunks. El objetivo no es adivinar, sino encontrar "top offenders": librerías grandes, polyfills innecesarios o módulos incluidos en el cliente que podrían ser server-side.
Principales palancas que aplicamos
-
Eliminar dependencias no usadas: revisamos
package.jsony quitamos paquetes que solo se usaban en scripts (p.ej.png-to-ico) o que eran transitorios. Esto reduce la superficie de árbol de dependencias y evita que herramientas de build embeban código innecesario. -
Preferir Server Components sobre Client Components cuando no necesitas interactividad. Cada
"use client"obliga a empaquetar React y lógica cliente. Migrar páginas que solo generan HTML a Server Components quita peso al bundle cliente. -
Optimizar MDX y procesamiento Markdown: usamos
next-mdx-remotepara serializar en server y hydratar en cliente solo lo estrictamente necesario. Además, procesamos MDX en el servidor conunified/remarkpara generar HTML SEO-friendly, y solo serializamos la versión cliente cuando hace falta. -
Evitar polyfills innecesarios: configuramos
.browserslistrcpara apuntar a navegadores modernos y no incluir polyfills legacy que inflanpolyfills(~100KB). -
Usar lazy-loading y dynamic imports: componentes de interacción que no son críticos (widgets, visualizadores, editores) se cargan con
next/dynamicyssr: falsecuando corresponda. -
Mantener
@tailwindcss/postcsspero eliminar autoprefixer duplicado: el pipeline de CSS es esencial, pero revisamos redundancias. -
Aprovechar Turbopack: por defecto Next 16 usa Turbopack que produce bundles más pequeños y builds muchísimo más rápidos que webpack en este proyecto.
Cambios concretos que implementamos (ejemplos)
- Migración a Server Component (ejemplo simplificado):
// Antes (client)
"use client";
import { useLanguage } from '@/app/context/LanguageContext';
export default function ServicePageClient() {
const { t } = useLanguage();
return <div>{t('serviceTitle')}</div>;
}
// Después (server):
import { getTranslations } from '@/lib/i18n';
export default async function ServicePageServer({ params }) {
const t = await getTranslations(params.locale);
return <div>{t('serviceTitle')}</div>;
}
- Dynamic import para componentes pesados:
import dynamic from 'next/dynamic';
const HeavyVisualizer = dynamic(() => import('@/components/HeavyVisualizer'), { ssr: false });
- Comprobar compresión en producción:
curl -I -H "Accept-Encoding: br, gzip" https://dailymp.es/ | grep -i content-encoding
# Esperamos: content-encoding: br
Resultado: ¿cómo llegamos a 12KB transferidos?
- Tras las optimizaciones, el bundle generado (JS + chunks) pesa en crudo ~800–1.1MB descomprimido en
.next/static, pero lo que realmente importa para el usuario es el tamaño transferido por la red. - Hostinger sirve Brotli por defecto; al solicitar
Accept-Encoding: brel navegador recibe archivos ya comprimidos. En nuestra comprobación real la página principal se transfiere en ~12KB. - La diferencia entre "tamaño de bundle" y "tamaño transferido" radica en la compresión y el hecho de que gran parte del trabajo se mueve al servidor/SSG.
Buenas prácticas para mantener el bundle pequeño
- Automatiza el análisis: generar
.next/analyze/client.htmlregularmente y revisar librerías grandes. - Mantén la lógica pesada en el servidor y pasa datos ya procesados al cliente.
- Usa
dynamic()para partes no críticas. - Revisa
.browserslistrcy evita polyfills para navegadores muertos o muy antiguos.
Enlaces internos útiles
- Servicios de integración IA: /servicios/ai-driven-development
- QA y performance: /servicios/bug-shield
Conclusión y llamada a la acción
Reducir el tamaño del bundle no es solo reducir KB en disco: es tomar decisiones sobre arquitectura, delegar trabajo al servidor y configurar entrega (Brotli, CDN). En nuestro caso, la suma de pequeñas mejoras y una entrega estática optimizada permitió que la página se sirviera con apenas ~12KB transferidos, ofreciendo una experiencia de carga instantánea. ¿Te interesa optimizar tu sitio o reducir el tamaño transferido? Contáctanos — ofrecemos auditorías y mejoras prácticas para ayudarte a lograr resultados similares.