React: 5 consejos sencillos para reducir el tamaño del bundle principal
Aprende a cómo reducir el tamaño de tu bundle principal de React

Si habéis estado pendientes estos últimos meses de las últimas novedades de React habréis notado que una buena parte de los esfuerzos están muy enfocados en conseguir mejorar (aún más) el rendimiento de las aplicaciones escritas bajo esta librería. Por ejemplo, Dan Abramov en esta charla daba una visión general de hacia donde se estaba orientando el desarrollo de React y el impacto directo que éste iba a tener sobre el rendimiento tanto a nivel de uso de CPU como de red:
A raíz de esta charla he querido recopilar 4 consejos muy simplones de implementar que os permitirán reducir el tamaño del bundle principal, de modo que vuestra aplicación pese menos y no requiera de grandes velocidades de red para funcionar. ¡Vamos allá!
1. Webpack Bundle Analyzer
En mi opinión una herramienta imprescindible si queréis ver poder ver las partes del bundle que más pesan y poder haceros una idea general de qué partes podrían optimizarse para reducir su tamaño.
Para configurarlo el proceso es muy muy sencillo, pues basta con instalarlo de la forma habitual:
npm i --save-dev webpack-bundle-analyzer
Y añadirlo a nuestra configuración de webpack del siguiente modo:
const BundleAnalyzerPlugin = require(‘webpack-bundle-analyzer’).BundleAnalyzerPlugin;module.exports = {... plugins: [
.... new BundleAnalyzerPlugin({ analyzerPort: 7777 }) ]
De este modo, cada vez que ejecutemos webpack para generar el bundle obtendremos una vista similar a la siguiente en http://localhost:7777
(o el puerto que hayáis especificado).

De este modo identificar qué partes conviene separar resulta mucho más sencillo y podremos ir a tiro hecho para optimizar aquellos paquetes que están incrementando el tamaño del bundle final.
2. NO importar todo lodash
Parece algo evidentemente pero creedme que es muy sencillo si vamos rápido tirar una línea como la siguiente:
import _ from ‘lodash’;
y encontrarnos con que nos llevamos de regalo toda la librería lodash
a producción.
Por desgracia, la libreríalodash
todavía emplea imports/exports de CommonJs, lo cual provoca que no sean tree-shakables, es decir, webpack no es capaz de determinar qué código está libre de sideEffects
de modo que pueda eliminar de forma segura aquellas partes que no se utilizan. Esto provoca que pese a que empleemos un import de este tipo:
import { debounce } from ‘lodash’;
Nos encontraremos con el mismo problema de obtener en el bundle final todo lodash
.
Si queréis leer más sobre este problema y algunas soluciones propuestas podéis hacerlo en los siguientes enlaces:
- https://medium.com/@martin_hotell/tree-shake-lodash-with-webpack-jest-and-typescript-2734fa13b5cd
- https://github.com/webpack/webpack/issues/1750
- https://stackoverflow.com/questions/35250500/correct-way-to-import-lodash
Debido a que en el proyecto que ha inspirado este artículo apenas uso funciones de lodas
yo he optado por la siguiente solución:
import debounce from ‘lodash/function/debounce’;
Es decir, he prescindido de instalar lodash-es
y tan solo importo aquellas funciones que voy a emplear.
3. Cuidado con moment
Del mismo modo que es necesario prestar atención a la forma en que importamos lodash
algo similar sucede con la librería momentJs, la cual por defecto se lleva de regalo todos los idiomas al bundle final si no especificamos lo siguiente.
Al igual que para el problema de lodash, yo he encontrado diferentes soluciones para este problema, aunque al final he optado por la siguiente:
...plugins: [...new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /(en|es)$/),...]
Como veis, estoy empleando el plugin ContextReplacementePlugin
de webpack con el fin de escoger tan solo aquellos idiomas que soporta la aplicación y así, reducir el tamaño del bundle drásticamente.
4. gzip, por favor
Este es otro punto muy a tener en cuenta si queremos obtener un tamaño de bundle óptimo (y en general cuando estamos trabajando en entorno web) y además es bastante sencillo de conseguir.
Básicamente deberemos configurar nuestro servidor para que pueda servir contenido comprimido con gzip
al recibir la cabecera Accept-Encoding: gzip
.
Os dejo unos cuantos tutoriales que os serán de gran ayuda para configurar vuestro servidor de esta forma según su tipo:
Configurar gzip en NGINX:
Configurar gzip en APACHE:
Configurar gzip en CloudFront:
5. Code-Splitting
Y aquí llegamos a la parte interesante a la cual dedicaré un artículo entero pero a modo de introducción creo que es muy interesante hablar de una de las principales novedades que trae consigo React 16.6.0 y la forma en que podemos aplicarla para reducir el tamaño de nuestro bundle: lazy y Suspense.
Antes de nada, deciros que lo que aquí describiré es aplicable en el caso de que estemos empleando la librería react-router
para definir las rutas de la aplicación, algo que suele ser bastante habitual dada la popularidad de la misma.
Lo que nos permite React 16.6.0 y su nueva función lazy
es realizar un import dinámico de un componente de modo que mientras se está resolviendo podamos mostrar un placeholder (por ejemplo, un loader básico) todo ello con apenas unas líneas de código como podemos ver en la propia documentación:
import React, {lazy, Suspense} from 'react';
const OtherComponent = lazy(() => import('./OtherComponent'));
function MyComponent() {
return (
<Suspense fallback={<div>Loading...</div>}>
<OtherComponent />
</Suspense>
);
}
En este caso, mientras se resuelve OtherComponent
, React se encarga de mostrar el fallback
, para automáticamente mostrar el componente cargado cuando detecta que ya está disponible.
La ventaja de esto, es que podemos directamente definir todas nuestras rutas de la librería react-router
mediante este método, de modo que cada componente aparezca por separado del bundle principal y así reducir dramáticamente el tamaño del principal.
Para ello, podemos escribir un código similar a éste:
De este modo, los componentes asociados a las rutas serán cargados dinámicamente y, así, aparecerán separados del bundle principal.
Por supuesto existen muchas más aplicaciones para las funciones lazy y el componente Suspense pero he visto conveniente, por su simplicidad de uso, hablaros de ésta. Si tenéis curiosidad podéis consultar la documentación oficial para aprender más de ellas y aprovecharos de las ventajas que pueden aportar a vuestra aplicación:
Y con esto termino esta pequeña guía con consejos básicos sobre cómo poner a dieta el bundle de vuestra aplicación. Por supuesto todos los comentarios son bienvenidos de cara a seguir mejorar y descubrir nuevos trucos que nos ayuden a optimizar nuestras aplicaciones escritas en React.
¿Quieres recibir más artículos como este?
Suscríbete a nuestra newsletter: