From e3aca1c0f964803724a48758a53b6badb7f44643 Mon Sep 17 00:00:00 2001 From: Tyler Smalley Date: Tue, 2 Jan 2018 11:52:31 -0800 Subject: [PATCH 1/2] [optimize] More aggressive chunking of common/vendor code 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 Vendored code (anything inside 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 --- src/optimize/base_optimizer.js | 21 ++++++++++++--------- src/ui/ui_render/views/ui_app.jade | 3 +++ tasks/config/karma.js | 6 ++++++ 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/optimize/base_optimizer.js b/src/optimize/base_optimizer.js index 4a45291df1f4dc..a014ca3c81da31 100644 --- a/src/optimize/base_optimizer.js +++ b/src/optimize/base_optimizer.js @@ -4,10 +4,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'; @@ -122,12 +118,19 @@ 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', + minChunks: module => module.context && module.context.indexOf('node_modules') !== -1 + }), + + new webpack.NoEmitOnErrorsPlugin(), ], module: { @@ -225,12 +228,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 }, diff --git a/src/ui/ui_render/views/ui_app.jade b/src/ui/ui_render/views/ui_app.jade index 1595059410bfa0..120f26ad9046af 100644 --- a/src/ui/ui_render/views/ui_app.jade +++ b/src/ui/ui_render/views/ui_app.jade @@ -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') ]; diff --git a/tasks/config/karma.js b/tasks/config/karma.js index b362b5471c6e57..b72df5f6ad7097 100644 --- a/tasks/config/karma.js +++ b/tasks/config/karma.js @@ -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' ] From 313c59c15b118c7bae0ec77cb6378dfe21525266 Mon Sep 17 00:00:00 2001 From: Tyler Smalley Date: Wed, 3 Jan 2018 10:28:23 -0800 Subject: [PATCH 2/2] Vendors only Kibana direct node_modules Signed-off-by: Tyler Smalley --- src/optimize/base_optimizer.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/optimize/base_optimizer.js b/src/optimize/base_optimizer.js index a014ca3c81da31..8f7e86157447e6 100644 --- a/src/optimize/base_optimizer.js +++ b/src/optimize/base_optimizer.js @@ -97,6 +97,7 @@ export default class BaseOptimizer { }); } + const nodeModulesPath = fromRoot('node_modules'); const commonConfig = { node: { fs: 'empty' }, context: fromRoot('.'), @@ -127,7 +128,8 @@ export default class BaseOptimizer { new webpack.optimize.CommonsChunkPlugin({ name: 'vendors', filename: 'vendors.bundle.js', - minChunks: module => module.context && module.context.indexOf('node_modules') !== -1 + // only combine node_modules from Kibana + minChunks: module => module.context && module.context.indexOf(nodeModulesPath) !== -1 }), new webpack.NoEmitOnErrorsPlugin(),