mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-10 07:37:19 +02:00
perf(v2): significantly reduce bundle size & initial html payload (#1898)
* perf(v2): reduce bundle size significantly with super short chunk name and registry * changelog * use hash:8 as id for better long term caching * even shorter filename. slice contenthash
This commit is contained in:
parent
c23f981f67
commit
fabaf7772b
7 changed files with 45 additions and 20 deletions
|
@ -3,6 +3,7 @@
|
|||
## Unreleased
|
||||
|
||||
- Convert sitemap plugin to TypeScript
|
||||
- Significantly reduce main bundle size and initial HTML payload on production build. Generated JS files from webpack is also shorter in name.
|
||||
|
||||
## 2.0.0-alpha.31
|
||||
|
||||
|
|
|
@ -108,6 +108,20 @@ describe('load utils', () => {
|
|||
Object.keys(secondAssert).forEach(str => {
|
||||
expect(genChunkName(str, undefined, 'blog')).toBe(secondAssert[str]);
|
||||
});
|
||||
|
||||
// Only generate short unique id
|
||||
const thirdAssert = {
|
||||
a: '0cc175b9',
|
||||
b: '92eb5ffe',
|
||||
c: '4a8a08f0',
|
||||
d: '8277e091',
|
||||
};
|
||||
Object.keys(thirdAssert).forEach(str => {
|
||||
expect(genChunkName(str, undefined, undefined, true)).toBe(
|
||||
thirdAssert[str],
|
||||
);
|
||||
});
|
||||
expect(genChunkName('d', undefined, undefined, true)).toBe('8277e091');
|
||||
});
|
||||
|
||||
test('idx', () => {
|
||||
|
|
|
@ -101,9 +101,16 @@ export function genChunkName(
|
|||
modulePath: string,
|
||||
prefix?: string,
|
||||
preferredName?: string,
|
||||
shortId?: boolean,
|
||||
): string {
|
||||
let chunkName: string | undefined = chunkNameCache.get(modulePath);
|
||||
if (!chunkName) {
|
||||
if (shortId) {
|
||||
chunkName = createHash('md5')
|
||||
.update(modulePath)
|
||||
.digest('hex')
|
||||
.substr(0, 8);
|
||||
} else {
|
||||
let str = modulePath;
|
||||
if (preferredName) {
|
||||
const shortHash = createHash('md5')
|
||||
|
@ -114,6 +121,7 @@ export function genChunkName(
|
|||
}
|
||||
const name = str === '/' ? 'index' : docuHash(str);
|
||||
chunkName = prefix ? `${prefix}---${name}` : name;
|
||||
}
|
||||
chunkNameCache.set(modulePath, chunkName);
|
||||
}
|
||||
return chunkName;
|
||||
|
|
|
@ -56,9 +56,11 @@ function ComponentCreator(path) {
|
|||
}
|
||||
|
||||
const chunkRegistry = registry[target] || {};
|
||||
optsLoader[keys.join('.')] = chunkRegistry.loader;
|
||||
optsModules.push(chunkRegistry.module);
|
||||
optsWebpack.push(chunkRegistry.webpack);
|
||||
/* eslint-disable prefer-destructuring */
|
||||
optsLoader[keys.join('.')] = chunkRegistry[0];
|
||||
optsModules.push(chunkRegistry[1]);
|
||||
optsWebpack.push(chunkRegistry[2]);
|
||||
/* eslint-enable prefer-destructuring */
|
||||
}
|
||||
|
||||
traverseChunk(chunkNames, []);
|
||||
|
|
|
@ -117,11 +117,10 @@ export async function load(siteDir: string): Promise<Props> {
|
|||
`export default {
|
||||
${Object.keys(registry)
|
||||
.map(
|
||||
key => ` '${key}': {
|
||||
'loader': ${registry[key].loader},
|
||||
'module': ${JSON.stringify(registry[key].modulePath)},
|
||||
'webpack': require.resolveWeak(${JSON.stringify(registry[key].modulePath)}),
|
||||
},`,
|
||||
key =>
|
||||
` '${key}': [${registry[key].loader}, ${JSON.stringify(
|
||||
registry[key].modulePath,
|
||||
)}, require.resolveWeak(${JSON.stringify(registry[key].modulePath)})],`,
|
||||
)
|
||||
.join('\n')}};\n`,
|
||||
);
|
||||
|
|
|
@ -24,6 +24,7 @@ function getModulePath(target: Module): string {
|
|||
}
|
||||
|
||||
export async function loadRoutes(pluginsRouteConfigs: RouteConfig[]) {
|
||||
const isProd = process.env.NODE_ENV === 'production';
|
||||
const routesImports = [
|
||||
`import React from 'react';`,
|
||||
`import ComponentCreator from '@docusaurus/ComponentCreator';`,
|
||||
|
@ -82,7 +83,7 @@ export async function loadRoutes(pluginsRouteConfigs: RouteConfig[]) {
|
|||
}
|
||||
|
||||
const modulePath = getModulePath(value as Module);
|
||||
const chunkName = genChunkName(modulePath, prefix, name);
|
||||
const chunkName = genChunkName(modulePath, prefix, name, isProd);
|
||||
const loader = `() => import(/* webpackChunkName: '${chunkName}' */ ${JSON.stringify(
|
||||
modulePath,
|
||||
)})`;
|
||||
|
|
|
@ -32,8 +32,8 @@ export function createBaseConfig(
|
|||
output: {
|
||||
pathinfo: false,
|
||||
path: outDir,
|
||||
filename: isProd ? '[name].[contenthash].js' : '[name].js',
|
||||
chunkFilename: isProd ? '[name].[contenthash].js' : '[name].js',
|
||||
filename: isProd ? '[name].[contenthash:8].js' : '[name].js',
|
||||
chunkFilename: isProd ? '[name].[contenthash:8].js' : '[name].js',
|
||||
publicPath: baseUrl,
|
||||
},
|
||||
// Don't throw warning when asset created is over 250kb
|
||||
|
@ -157,8 +157,8 @@ export function createBaseConfig(
|
|||
},
|
||||
plugins: [
|
||||
new MiniCssExtractPlugin({
|
||||
filename: isProd ? '[name].[contenthash].css' : '[name].css',
|
||||
chunkFilename: isProd ? '[name].[contenthash].css' : '[name].css',
|
||||
filename: isProd ? '[name].[contenthash:8].css' : '[name].css',
|
||||
chunkFilename: isProd ? '[name].[contenthash:8].css' : '[name].css',
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue