Skip to content

Commit cede740

Browse files
committed
perf(gatsby): cache babel partial config and babel custom options
1 parent 08b5721 commit cede740

File tree

1 file changed

+35
-4
lines changed

1 file changed

+35
-4
lines changed

packages/gatsby/src/utils/babel-loader.js

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,24 @@ const { getBrowsersList } = require(`./browserslist`)
2323
*
2424
* You can find documentation for the custom loader here: https://babeljs.io/docs/en/next/babel-core.html#loadpartialconfig
2525
*/
26+
27+
const customOptionsCache = new Map()
28+
const configCache = new Map()
29+
2630
module.exports = babelLoader.custom(babel => {
27-
const toReturn = {
31+
return {
2832
// Passed the loader options.
2933
customOptions({
3034
stage = `test`,
3135
reactRuntime = `classic`,
3236
rootDir = process.cwd(),
3337
...options
3438
}) {
35-
return {
39+
if (customOptionsCache.has(stage)) {
40+
return customOptionsCache.get(stage)
41+
}
42+
43+
const toReturn = {
3644
custom: {
3745
stage,
3846
reactRuntime,
@@ -49,11 +57,27 @@ module.exports = babelLoader.custom(babel => {
4957
...options,
5058
},
5159
}
60+
61+
customOptionsCache.set(stage, toReturn)
62+
63+
return toReturn
5264
},
5365

5466
// Passed Babel's 'PartialConfig' object.
5567
config(partialConfig, { customOptions }) {
68+
let configCacheKey = customOptions.stage
69+
if (partialConfig.hasFilesystemConfig()) {
70+
// partialConfig.files is a Set that accumulates used config files (absolute paths)
71+
partialConfig.files.forEach(configFilePath => {
72+
configCacheKey += `_${configFilePath}`
73+
})
74+
}
75+
5676
let { options } = partialConfig
77+
if (configCache.has(configCacheKey)) {
78+
return { ...options, ...configCache.get(configCacheKey) }
79+
}
80+
5781
const [
5882
reduxPresets,
5983
reduxPlugins,
@@ -101,9 +125,16 @@ module.exports = babelLoader.custom(babel => {
101125
})
102126
})
103127

128+
// cache just plugins and presets, because config also includes things like
129+
// filenames - this is mostly to not call `mergeConfigItemOptions` for each file
130+
// as that function call `babel.createConfigItem` and is quite expensive but also
131+
// skips quite a few nested loops on top of that
132+
configCache.set(configCacheKey, {
133+
plugins: options.plugins,
134+
presets: options.presets,
135+
})
136+
104137
return options
105138
},
106139
}
107-
108-
return toReturn
109140
})

0 commit comments

Comments
 (0)