mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[optimizer] More aggressive chunking of common/vendor code (#15907)
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 <tyler.smalley@elastic.co>
This commit is contained in:
parent
cae1a82140
commit
41d905309b
7 changed files with 58 additions and 9 deletions
|
@ -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
|
||||
},
|
||||
|
|
|
@ -25,6 +25,10 @@ export default async (kbnServer, server, config) => {
|
|||
|
||||
await uiBundles.writeEntryFiles();
|
||||
|
||||
// Not all entry files produce a css asset. Ensuring they exist prevents
|
||||
// an error from occuring when the file is missing.
|
||||
await uiBundles.ensureStyleFiles();
|
||||
|
||||
// in prod, only bundle when someing is missing or invalid
|
||||
const reuseCache = config.get('optimize.useBundleCache')
|
||||
? await uiBundles.areAllBundleCachesValid()
|
||||
|
|
|
@ -27,6 +27,8 @@ export default class WatchOptimizer extends BaseOptimizer {
|
|||
this.status$.subscribe(this.onStatusChangeHandler);
|
||||
|
||||
await this.uiBundles.writeEntryFiles();
|
||||
await this.uiBundles.ensureStyleFiles();
|
||||
|
||||
await this.initCompiler();
|
||||
|
||||
this.compiler.plugin('watch-run', this.compilerRunStartHandler);
|
||||
|
|
|
@ -33,6 +33,10 @@ export class UiBundle {
|
|||
return this._controller.resolvePath(`${this.getId()}.entry.js`);
|
||||
}
|
||||
|
||||
getStylePath() {
|
||||
return this._controller.resolvePath(`${this.getId()}.style.css`);
|
||||
}
|
||||
|
||||
getOutputPath() {
|
||||
return this._controller.resolvePath(`${this.getId()}.bundle.js`);
|
||||
}
|
||||
|
@ -63,6 +67,20 @@ export class UiBundle {
|
|||
));
|
||||
}
|
||||
|
||||
async hasStyleFile() {
|
||||
return await fcb(cb => {
|
||||
return stat(this.getStylePath(), error => {
|
||||
cb(null, !(error && error.code === 'ENOENT'));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async touchStyleFile() {
|
||||
return await fcb(cb => (
|
||||
writeFile(this.getStylePath(), '', 'utf8', cb)
|
||||
));
|
||||
}
|
||||
|
||||
async clearBundleFile() {
|
||||
try {
|
||||
await fcb(cb => unlink(this.getOutputPath(), cb));
|
||||
|
|
|
@ -146,6 +146,16 @@ export class UiBundlesController {
|
|||
}
|
||||
}
|
||||
|
||||
async ensureStyleFiles() {
|
||||
await this.ensureDir();
|
||||
|
||||
for (const bundle of this._bundles) {
|
||||
if (!await bundle.hasStyleFile()) {
|
||||
await bundle.touchStyleFile();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hashBundleEntries() {
|
||||
const hash = createHash('sha1');
|
||||
for (const bundle of this._bundles) {
|
||||
|
|
|
@ -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')
|
||||
];
|
||||
|
|
|
@ -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'
|
||||
]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue