Reputation: 2356
I'm using browserify with npm to create a bundle of js. The web app using react and a lot of other modules so the output file is about 3.4M, 2M uglyfied and 430K gzip.
The browserify process is executed via npm run browserify that is defined in package.json
"browserify": "browserify client/index.js -u server/**/**/**/* -i q -i express-validation | uglifyjs -o public/javascripts/generated/bundle.js"
I have a feeling that the bundle output is too large and there is a way to reduce it but I couldn't find a way to debug the process (tried -d --list
, etc).
Any help will be appreciated.
Upvotes: 4
Views: 1521
Reputation: 31
This could represent a difficult and annoying refactoring step in your situation, but in accordance with the official browserify handbook, you could try the partition feature, this way, you can split the final bundle into multiples files, for an incremental injection of the project dependencies, in the hope to reduce the size of the initial file required by the entry point of your app.
To achieve this, you can use the factor-bundle or partition-bundle plugins, the main difference between them, is that the second plugin have a built-in ajax function (loadjs) to load the js files, IMHO the most flexible solution for large applications.
Follows the official partion-bundle description from the Browserify handbook:
partition-bundle
partition-bundle handles splitting output into multiple bundles like factor-bundle, but includes a built-in loader using a special loadjs() function.
partition-bundle takes a json file that maps source files to bundle files:
{ "entry.js": ["./a"], "common.js": ["./b"], "common/extra.js": ["./e", "./d"] }
Then partition-bundle is loaded as a plugin and the mapping file, output directory, and destination url path (required for dynamic loading) are passed in:
browserify -p [ partition-bundle --map mapping.json \ --output output/directory --url directory ]
Now you can add:
<script src="entry.js"></script>
to your page to load the entry file. From inside the entry file, you can dynamically load other bundles with a loadjs() function:
a.addEventListener('click', function() { loadjs(['./e', './d'], function(e, d) { console.log(e, d); }); });
Additionally you can use Disc, to visually analyze your dependencies tree, to avoid the redundancies/replicates inside it and/or identify dependencies not required during the application startup.
From the official Disc website:
Disc is a tool for analyzing the module tree of browserify project bundles. It's especially handy for catching large and/or duplicate modules which might be either bloating up your bundle or slowing down the build process.
The demo included on disc's github page is the end result of running the tool on browserify's own code base.
Command-Line Interface
Note: you'll need to build your bundle with the --full-paths flag for disc to do its thing.
discify [bundle(s)...] {options} Options: -h, --help Displays these instructions. -o, --output Output path of the bundle. Defaults to stdout.
When you install disc globally, you the discify command-line tool is made available as the quickest means of checking out your bundle. As of disc v1.0.0, this tool takes any bundled browserify script as input and spits out a standalone HTML page as output.
For example:
browserify --full-paths index.js > bundle.js discify bundle.js > disc.html open disc.html
Last but not least, when you import your modules, avoid to entirely load the module if you need only few functions of it, example:
Instead of this:
import { core, fp } from 'lodash'
make this:
import core from 'lodash/core'
import fp from 'lodash/fp'
Upvotes: 2