[optimizer] More aggressive chunking of common/vendor code (#15816)

Previously, we were not aggressive in combining common code which resulted in duplicates included in the bundles.

As an example `node_modules/elasticsearch-browser/elasticsearch.angular.js` is present in the following chunks:

* kibana.bundle.js
* dashboardViewer.bundle.js
* apm.bundle.js
* monitoring.bundle.js
* ml.bundle.js
* timelion.bundle.js
* graph.bundle.js

Vendor code (anything inside Kibana's node_modules) is placed in vendors.bundle.js while everything else with more than two references is placed in commons.bundle.js.

This has a couple positive side-effects (numbers are with x-pack & canvas):

* Decreased build time. Seeing builds go from 475.76 seconds to 274.72.
* Decreased memory overhead. Uses roughly 1/3 the memory overhead.
* Decreased bundle size. A 68% reduction in overall bundle size. Going from 66.16 MB to 21.13 MB.

Signed-off-by: Tyler Smalley <tyler.smalley@elastic.co>
This commit is contained in:
Tyler Smalley 2018-01-05 10:05:17 -08:00 committed by GitHub
parent 2fd41d5a6b
commit 92b373b304
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 24 additions and 9 deletions

View file

@ -3,10 +3,6 @@ import { writeFile } from 'fs';
import Boom from 'boom';
import ExtractTextPlugin from 'extract-text-webpack-plugin';
import webpack from 'webpack';
import CommonsChunkPlugin from 'webpack/lib/optimize/CommonsChunkPlugin';
import DefinePlugin from 'webpack/lib/DefinePlugin';
import UglifyJsPlugin from 'webpack/lib/optimize/UglifyJsPlugin';
import NoEmitOnErrorsPlugin from 'webpack/lib/NoEmitOnErrorsPlugin';
import Stats from 'webpack/lib/Stats';
import webpackMerge from 'webpack-merge';
@ -98,6 +94,8 @@ export default class BaseOptimizer {
});
}
const nodeModulesPath = fromRoot('node_modules');
/**
* Adds a cache loader if we're running in dev mode. The reason we're not adding
* the cache-loader when running in production mode is that it creates cache
@ -141,12 +139,20 @@ export default class BaseOptimizer {
allChunks: true
}),
new CommonsChunkPlugin({
new webpack.optimize.CommonsChunkPlugin({
name: 'commons',
filename: 'commons.bundle.js'
filename: 'commons.bundle.js',
minChunks: 2,
}),
new NoEmitOnErrorsPlugin(),
new webpack.optimize.CommonsChunkPlugin({
name: 'vendors',
filename: 'vendors.bundle.js',
// only combine node_modules from Kibana
minChunks: module => module.context && module.context.indexOf(nodeModulesPath) !== -1
}),
new webpack.NoEmitOnErrorsPlugin(),
],
module: {
@ -233,12 +239,12 @@ export default class BaseOptimizer {
return webpackMerge(commonConfig, {
plugins: [
new DefinePlugin({
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': '"production"'
}
}),
new UglifyJsPlugin({
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
},

View file

@ -120,8 +120,11 @@ block content
return anchor.href;
}
var files = [
bundleFile('vendors.style.css'),
bundleFile('commons.style.css'),
bundleFile('#{app.getId()}.style.css'),
bundleFile('vendors.bundle.js'),
bundleFile('commons.bundle.js'),
bundleFile('#{app.getId()}.bundle.js')
];

View file

@ -37,8 +37,11 @@ module.exports = function (grunt) {
// list of files / patterns to load in the browser
files: [
'http://localhost:5610/bundles/vendors.bundle.js',
'http://localhost:5610/bundles/commons.bundle.js',
'http://localhost:5610/bundles/tests.bundle.js',
'http://localhost:5610/bundles/vendors.style.css',
'http://localhost:5610/bundles/commons.style.css',
'http://localhost:5610/bundles/tests.style.css'
],
@ -126,8 +129,11 @@ module.exports = function (grunt) {
singleRun: true,
options: {
files: [
'http://localhost:5610/bundles/vendors.bundle.js',
'http://localhost:5610/bundles/commons.bundle.js',
`http://localhost:5610/bundles/tests.bundle.js?shards=${TOTAL_CI_SHARDS}&shard_num=${n}`,
'http://localhost:5610/bundles/vendors.style.css',
'http://localhost:5610/bundles/commons.style.css',
'http://localhost:5610/bundles/tests.style.css'
]