Skip to content

Commit

Permalink
Perf: replace LimitChunkCountPlugin with more naive MergeChunksPlugin
Browse files Browse the repository at this point in the history
Use more naive implementation of `MergeChunksPlugin` to concatenate all chunks in a single `server-main.js` bundle when building for server, in place of `LimitChunkCountPlugin` which seems to have quadratic runtime complexity and appears to be very slow for builds that include hundreds of async chunks (vs linear in the `MergeChunksPlugin` case).

Before:
```
[client] Build completed in 4.15s
[server] Build completed in 40.967s
```

After:
```
[client] Build completed in 4.195s
[server] Build completed in 6.801s
```
  • Loading branch information
shYkiSto authored and fusionjs-sync-bot[bot] committed Oct 25, 2022
1 parent 91def84 commit c46971f
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 5 deletions.
4 changes: 2 additions & 2 deletions fusion-cli-tests/test/e2e/typescript/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ describe('TypeScript app', () => {

browser.close();
proc.kill('SIGKILL');
}, 25000);
}, 35000);

test('`fusion dev` works', async () => {
const app = dev(dir);
Expand All @@ -49,5 +49,5 @@ describe('TypeScript app', () => {
t.ok(content.includes('FIXTURE_TYPESCRIPT_LOCAL_PACKAGE_CONTENT'));

await app.teardown();
}, 15000);
}, 35000);
});
4 changes: 2 additions & 2 deletions fusion-cli/build/get-webpack-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const isEsModule = require('../lib/is-es-module.js');
const LoaderContextProviderPlugin = require('./plugins/loader-context-provider-plugin.js');
const ChildCompilationPlugin = require('./plugins/child-compilation-plugin.js');
const NodeSourcePlugin = require('./plugins/node-source-plugin.js');
const MergeChunksPlugin = require('./plugins/merge-chunks-plugin.js');
const {
chunkIdsLoader,
fileLoader,
Expand Down Expand Up @@ -749,8 +750,7 @@ function getWebpackConfig(opts /*: WebpackConfigOpts */) {
// Need to provide same API to source node modules in client bundles
// @see: https://github.com/webpack/webpack/blob/v4.46.0/lib/node/NodeSourcePlugin.js#L21-L36
target !== 'node' && new NodeSourcePlugin(nodeBuiltins),
runtime === 'server' &&
new webpack.optimize.LimitChunkCountPlugin({maxChunks: 1}),
runtime === 'server' && new MergeChunksPlugin(),
onBuildEnd
? new ProgressBarPlugin({
callback: (progressBar) => {
Expand Down
48 changes: 48 additions & 0 deletions fusion-cli/build/plugins/merge-chunks-plugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/** Copyright (c) 2018 Uber Technologies, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

/*eslint-env node */

const PLUGIN_NAME = 'MergeChunksPlugin';

class MergeChunksPlugin {
apply(compiler /*: Object */) {
compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
compilation.hooks.optimizeChunks.tap(
{
name: PLUGIN_NAME,
// @see https://github.com/webpack/webpack/blob/9fcaa243573005d6fdece9a3f8d89a0e8b399613/lib/OptimizationStages.js#L10
stage: 10,
},
() => {
if (compilation.chunks.size < 2) {
return;
}

const chunkGraph = compilation.chunkGraph;
const chunks = Array.from(compilation.chunks);

const rootChunk = chunks[0];
for (let i = 1, len = chunks.length; i < len; i++) {
const chunk = chunks[i];
if (!chunkGraph.canChunksBeIntegrated(rootChunk, chunk)) {
throw new Error(
'Expected to be able to merge all chunks into one'
);
}

chunkGraph.integrateChunks(rootChunk, chunk);
compilation.chunks.delete(chunk);
}
}
);
});
}
}

module.exports = MergeChunksPlugin;
2 changes: 1 addition & 1 deletion fusion-plugin-rpc-redux-react/test/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export const Runtime = class Runtime {
async function untilReady(page, port) {
let started = false;
let numTries = 0;
while (!started && numTries < 10) {
while (!started && numTries < 15) {
try {
await page.goto(`http://localhost:${port}`);
started = true;
Expand Down

0 comments on commit c46971f

Please sign in to comment.