Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to minimize the size of webpack's bundle?

I'm writing a web app using react and webpack as my module bundler. My jsx code is really light so far, the size of the entire folder is 25 kb.

My bundle.js created from webpack is 2.2 mb though. After running the optimization with the -p flag, it reduces the bundle to 700kb, which is still extremely big.

I have looked into the react.min.js file and its size is 130kb.

Is it possible that the webpack produces such big files or am I doing something wrong?

webpack.config.js

var path = require('path'); var webpack = require('webpack');  module.exports = {   entry: './public/components/main.jsx',   output: {     path: __dirname + "/public",     filename: 'bundle.js'   },   module: {     loaders: [{       test: /.jsx?$/,       loader: 'babel-loader',       exclude: /node_modules/,       query: {         presets: ['es2015', 'react']       }     }, {       test: /\.css$/,       loader: "style!css"     }]   } }; 

EDIT

package.json:

{   "name": "XChange",   "version": "0.0.0",   "private": true,   "scripts": {     "start": "node ./bin/www"   },   "main": "./bin/www",   "devDependencies": {     "body-parser": "~1.13.2",     "cookie-parser": "~1.3.5",     "debug": "~2.2.0",     "express": "~4.13.1",     "jade": "~1.11.0",     "morgan": "~1.6.1",     "serve-favicon": "~2.3.0",     "react-dom": "~0.14.3",     "react": "~0.14.3",     "webpack": "~1.12.9",     "babel-loader": "~6.2.0",     "babel-core": "~6.2.1",     "babel-preset-react": "~6.1.18",     "babel-preset-es2015": "~6.1.18",     "react-bootstrap": "~0.28.1",     "material-ui": "~0.14.0-rc1",     "history": "~1.13.1",     "react-router": "~1.0.2",     "style-loader": "~0.13.0",     "css-loader": "~0.18.0"   },   "dependencies": {     "express-validator": "~2.18.0",     "mongoose": "~4.2.9",     "kerberos": "~0.0.17",     "bcrypt": "~0.8.5"   } } 
like image 522
itaied Avatar asked Dec 12 '15 12:12

itaied


People also ask

How do I reduce my bundle size?

If your application bundle size increases and affects performance, you can compress them to reduce the size. Gzip and Brotli are the most commonly used compression techniques, and you can use their Webpack plugins to simplify the entire process.

How do I reduce react bundle size?

One of the most impactful techniques to reduce the bundle size of a React application is compression. compression is a process in which the size of a file is reduced by re-encoding the file data to use fewer bits of storage than the original file.

How do I make Angular builds smaller?

Build your applications with --prod meta-flag The easiest way to significantly reduce the size of your Angular application is to use the --prod meta flag when you use ng build in the CLI.


2 Answers

According to your comments you are using material-ui and react-bootstrap. Those dependencies are bundled by webpack along with your react and react-dom packages. Any time you require or import a package it is bundled as part of your bundle file.

And here it comes my guess. You are probably importing the react-bootstrap and material-ui components using the library way:

import { Button } from 'react-bootstrap'; import { FlatButton } from 'material-ui'; 

This is nice and handy but it does not only bundles Button and FlatButton (and their dependencies) but the whole libraries.

One way to alleviate it is to try to only import or require what is needed, lets say the component way. Using the same example:

import Button from 'react-bootstrap/lib/Button'; import FlatButton from 'material-ui/lib/flat-button'; 

This will only bundle Button, FlatButton and their respective dependencies. But not the whole library. So I would try to get rid of all your library imports and use the component way instead.

If you are not using lot of components then it should reduce considerably the size of your bundled file.

As further explanation:

When you are using the library way you are importing all these react-bootstrap and all these material-ui components, regardless which ones you are actually using.

like image 165
dreyescat Avatar answered Sep 25 '22 02:09

dreyescat


01/2017 EDIT - I've since learned a little more about different Webpack Plugins, and wanted to update this. It turns out that UglifyJS has a littany of config options that don't seem to be very mainstream, but can have a dramatic effect on your bundle size. This is my current config w/ some annotations (docs on site are great):

 new webpack.optimize.UglifyJsPlugin({       comments: false, // remove comments       compress: {         unused: true,         dead_code: true, // big one--strip code that will never execute         warnings: false, // good for prod apps so users can't peek behind curtain         drop_debugger: true,         conditionals: true,         evaluate: true,         drop_console: true, // strips console statements         sequences: true,         booleans: true,       }     }) 

I once encountered an obscure problem with uglify-ication of escaped unicode chars, so be mindful if you employ these transformations that edge-case things like that are possible.

You can read more about the specific options webpack supports in the webpack docs w/ some follow-on links to further reading.


(sidenote: I think your package.json is mixed-up... at least a few of those dev-dependencies are dependencies in every package.json I've seen (e.g., the react-starter-kit)

If you're preparing for production, there are a few more steps you should take to get your file size down. Here's a snip of my webpack.config.js:

 plugins: [           new webpack.optimize.UglifyJsPlugin(),         new webpack.optimize.DedupePlugin(),         new webpack.DefinePlugin({             'process.env': {                 'NODE_ENV': JSON.stringify('production')             }         })     ], 

1) minifies/uglifies your code

2) replaces duplicate code to minimize file-size

3) tells webpack to omit some things it uses for node environment builds

Finally, if you use a source map (which you probably should), you'll want to add the appropriate line. Sentry wrote a nice blog post about this.

In my build, i use devtool: 'source-map' for production

like image 29
Brandon Avatar answered Sep 25 '22 02:09

Brandon