Tree shaking vs minificación: qué hace cada palanca

Tree shaking vs minificación: qué hace cada palanca

La minificación acorta el JS conservado. El tree shaking retira módulos innecesarios. Tabla comparativa, Vite/Webpack, y cuándo combinarlos.

13.05.2026
9 min de lectura
Compartir este artículo:
JavaScript
Tree shaking
Minificación
Webpack
Vite
Rendimiento
Optimización
Bundle
Tutorial

Dos técnicas que a menudo se confunden

Al optimizar un front moderno, oyes sin parar « minificar » y « tree-shaker » tus bundles. No son dos nombres para lo mismo: la minificación comprime el código ya incluido en el archivo final (espacios, nombres cortos), mientras que el tree shaking retira del grafo los módulos que nunca se usan. Ambos reducen los bytes transferidos, pero en etapas distintas del pipeline. Para un paso rápido sobre un archivo aislado (sin bundler), un minificador JavaScript en línea suele bastar; para una aplicación completa, combinas en general análisis estático de los imports, bundler en modo producción y minificador (Terser, esbuild, SWC…). Esta guía fija las definiciones, una tabla comparativa y una configuración realista con Vite o Webpack — remitiendo a nuestra guía de minificación JavaScript para los ajustes finos.

Saber qué palanca reduce el número de módulos y cuál reduce el tamaño del texto ya incluido
Evitar creer que « minificar » elimina lodash entero cuando importas una sola función
Configurar bundler + minificador para acumular tree shaking y minificación
Detectar cuándo el CSS debe purgarse a modo de « tree shaking » (Tailwind, PurgeCSS)
Medir con un analizador de bundle en lugar de adivinar las ganancias

Minificación y tree shaking: dos efectos distintos

Minificación: comprimir lo que queda en el archivo

La minificación trabaja sobre un archivo cuyo contenido ya está decidido: quita todo lo superfluo para el motor JS (espacios, comentarios, renombrado local agresivo según la herramienta). No puede adivinar si una función exportada servirá más tarde si ya está presente en el bundle. Para las bases y comparativas de herramientas, consulta nuestra guía completa sobre la minificación JavaScript. Para inspeccionar o recuperar la legibilidad a posteriori, ten a mano un desminificador JavaScript o la función Embellecer.

Antes

function calculateTotal(price, quantity) { const taxRate = 0.2; return price * quantity * (1 + taxRate); } export { calculateTotal };

Después

function calculateTotal(n,t){return n*t*1.2}export{calculateTotal};
Tree shaking: retirar las ramas muertas del grafo

El tree shaking se apoya en los módulos ES (`import` / `export`) y en un análisis estático: todo lo que no está referenciado desde una entrada puede apartarse antes incluso de que intervenga la minificación. Las bibliotecas deben exponer builds compatibles (`sideEffects` en `package.json`, sin mutaciones globales ocultas). La demostración más clara sigue siendo el paso de un import « barril » a un import puntual.

Prefiere un import nombrado desde lodash-es o un camino preciso en lugar de un import por defecto de lodash cuando tu cadena soporta el shaking
Expón correctamente los campos module y exports en el package.json de las libs para una resolución estática
Añade sideEffects: false (o una lista precisa) en package.json cuando tus archivos son puramente funcionales
Evita los imports dinámicos demasiado amplios que obligan a conservar chunks enteros sin análisis fino
Combina con code splitting — el shaking se aplica por chunk, no « mágicamente » en todo el sitio

Antes

// utils/math.ts — todo el barrel exportado puede arrastrarse export function square(x){return x*x} export function cube(x){return x*x*x} export function unusedLegacy(){/* API antigua */} // main.ts import { square } from './utils/math'

Después

// Tras el análisis del bundler: solo las definiciones // realmente usadas pueden permanecer en el chunk, // luego la minificación reduce aún la sintaxis. // cube() y unusedLegacy() pueden eliminarse // si ningún otro archivo los reimporta.
CSS: purge y « shaking » pragmático

No existe un tree shaking de módulos ES para tu hoja CSS como para el JS, pero los pipelines PostCSS / Tailwind / PurgeCSS juegan un rol equivalente: retiran las reglas no usadas antes de la fase en la que aplicas un minificador CSS en línea o PostCSS cssnano sobre la salida final.

Escanea tus templates JSX/HTML para entregar solo los utilitarios Tailwind realmente presentes
Corta las hojas « glob » antiguas una vez migradas a imports locales por componente
Valida visualmente después del purge — una clase dinámica concatenada puede desaparecer por error
Después del purge, pasa la hoja al minifier para ganar aún algunos puntos porcentuales en bytes

Medir lo que de verdad cambia en el bundle

Analizar antes / después

Las dos técnicas se ven en columnas distintas del informe: el tree shaking disminuye el número y la superficie de los módulos (por ejemplo lodash que desaparece casi por completo), la minificación reduce la columna « tamaño gzip » para un mismo grafo. Usa un treemap para evitar regresiones tras una actualización de dependencias.

rollup-plugin-visualizer, webpack-bundle-analyzer o la herramienta integrada de Vite (`vite-bundle-visualizer`)
Source Map Explorer para relacionar bytes con el archivo fuente
Chrome DevTools Coverage para detectar el JS/CSS cargado pero nunca ejecutado
Comparación gzip/brotli después del build para validar la ganancia de red real
No olvidar la prod

Activa sistemáticamente `NODE_ENV=production` (o equivalente): sin esa señal, algunos bundlers desactivan las optimizaciones y la dead-code elimination.

Comprueba que tu CI reconstruye bien el mismo comando que tu entorno staging
Guarda los informes de tamaño máximo de bundle como presupuesto de perf
Compara antes/después de una actualización npm mayor — una dependencia puede romper el shaking

Tabla mental: minificación vs tree shaking

Síntesis comparada

Usa este recap cuando estimes un ticket de optimización: la primera pregunta es « ¿este código debe existir en el grafo? », la segunda es « ¿cómo reducir su representación textual? ».

Minificación

objet:Reescribir el código ya incluido para quitar todo lo superfluo sintácticamente
moment:Después del bundling o sobre un archivo aislado
gain typique:A menudo 10–40 % sobre la misma entrada según estilo y comentarios
limites:No elimina un módulo entero importado pero no usado

Tree shaking

objet:Retirar exports / módulos no alcanzados desde los puntos de entrada
moment:Durante la resolución del grafo ES modules
gain typique:Puede dividir por dos (o más) un import de biblioteca mal elegido
limites:Imposible si el código es dinámico o CommonJS opaco sin transpilación
Preguntas rápidas que plantearte

Estos controles evitan las optimizaciones en el aire.

¿Sigo teniendo imports « todo el package » allí donde existe un camino preciso?
¿Mis libs declaran correctamente el campo sideEffects para que el bundler se atreva a podar?
¿La minificación corre después del shaking para comprimir lo que queda?
¿Necesito una herramienta en línea para un snippet fuera del bundle o un rebuild completo para la app?
Para el CSS, ¿he purgado antes de medir la minificación sola?

Minificar rápido un archivo fuera del bundler

FastMinify para un paso puntual

Cuando aún no has conectado Webpack/Vite — o cuando optimizas un script entregado tal cual — pega tu JS en nuestra herramienta: obtienes una salida compactada de inmediato, con opción inversa para releer el código.

1

Pegar o cargar tu archivo

Usa el minificador JavaScript en línea: todo permanece en el navegador.

2

Comparar con Embellecer

Alterna con Embellecer para un formato legible equivalente a un pequeño « undo » antes de reinjectarlo en tu pipeline.

3

No confundir con el shaking

La herramienta minifica un archivo a la vez; para eliminar módulos en todo un proyecto, hay que bundlear en producción.

Relacionar con los workflows modernos

Cuando tu codebase crece, alinéate con las prácticas descritas en nuestra comparativa minificadores en línea vs herramientas de build: la herramienta en línea conserva un lugar para las excepciones y los prototipos.

Prototipo o landing estática: minificador en línea
Aplicación SPA o SSR: bundler + shaking + minificación
Audit puntual: desminificar con FastMinify y luego corregir en origen

Combinar tree shaking y minificación en el build

Vite (Rollup bajo el capó)

`vite build` activa Rollup en producción con tree shaking y minificación esbuild por defecto — comprueba que tus imports son compatibles ES modules.

Configuration

// vite.config.ts (extracto) import { defineConfig } from 'vite' export default defineConfig({ build: { target: 'es2019', minify: 'esbuild', rollupOptions: { treeshake: { moduleSideEffects: (id) => !id.includes('.css'), propertyReadSideEffects: false, }, }, }, })

Uso

# Build prod con métricas NODE_ENV=production npm run build # Inspecciona dist/assets/*.js — los chunks reflejan # lo que Rollup conservó después del shaking y luego la minificación.
Webpack 5

`mode: 'production'` activa `usedExports` y la compilación con minifier; asegúrate de que el `package.json` de las libs declara correctamente los efectos de borde.

Configuration

// webpack.config.js (extracto) module.exports = { mode: 'production', optimization: { usedExports: true, sideEffects: true, // respeta package.json "sideEffects" minimize: true, minimizer: [ /* TerserPlugin o SWCMinifyPlugin */ ], }, };

Uso

// Para una entrada evidente: // webpack analiza desde tu entrypoint, // marca exports no usados, luego el minifier compacta. import { initApp } from './app' initApp()
CSS en producción

Encadena purge Tailwind o PurgeCSS, luego minificación — como se ve en nuestra guía sobre la minificación CSS. El shaking « lógico » está del lado del purge; la minificación pule la salida.

Ejemplo básico

/* Después del purge de las clases no usadas */ .btn{padding:.5rem 1rem;border-radius:.375rem}

Minificación de archivo

/* postcss con cssnano al final de la cadena */ .btn{padding:.5rem 1rem;border-radius:.375rem} /* → se convierte en una línea ultra compacta */

Conclusión

Tree shaking y minificación son complementarios: el primero dibuja un grafo ligero, el segundo escribe ese grafo con el mínimo de bytes. Ignora uno u otro y dejas o bien código muerto incluido, o bien una representación todavía verbosa de un grafo ya limpio. Para los snippets fuera del proyecto, un minificador en línea basta; para todo lo demás, automatiza en tu bundler y guarda FastMinify a mano para los casos límite.

Reduce el tamaño de tu JavaScript en unos segundos

Combina imports ES precisos, declaración sideEffects honesta y build de producción sistemático
Mide con un analizador de bundle después de cada refacto de dependencias
Para el CSS, purge y luego minificación con las guías FastMinify dedicadas
Ten a mano la comparativa minificadores en línea vs build para las decisiones de equipo
¿Necesitas releer JS compacto? Usa Embellecer o un desminificador antes del debug
Compartir este artículo
Compartir este artículo: