-
Notifications
You must be signed in to change notification settings - Fork 213
Improve the performance of config generation #239
Comments
I guess one complication is that if we only hashed In addition to more Neutrino-specific caching, I guess it might be worth looking into v8-compile-cache. Initial testing locally (ie adding it to the main neutrino package.json and then adding We may also want to do some profiling to see if we can fix any underlying slowness, which depending on wins might mean we don't need Neutrino-specific caching (this would help speed up the cold run cases too). |
Didn't even know about the compile cache package, that's pretty neat. |
So I've been digging into this a bit. For Treeherder's WIP Neutrino 9 This is pretty awful, and something we really need to fix. I tried I then used time-require, which showed that virtually all of the time is taken up with the many As such, I think a big win would be to lazy-require the plugins, that way for use-cases that don't generate a full webpack config (eg linting, jest, mocha) no time is wasted importing the plugins, and even for cases where a webpack config is generated, we would avoid To achieve this, I was thinking we could modify webpack-chain, so that if the plugin was passed as a string, then webpack-chain would @eliperelman - thoughts? |
I guess this is another case where the inability of middleware to know what command is being run (since middleware accumulation occurs before calling the output handler) limits what we can do. If we were starting from scratch, it would seem that perhaps the middleware API would allow presets to have multiple phases/events, so accumulation, registering commands and actual execution were all separate (and sometimes optional) steps. |
@edmorley we could support the string require use case, and worst case scenario, a plugin could be defined that did: plugin('alpha')
.use((...args) => new require('alpha')(...args), [1, 2, 3]) |
I've opened neutrinojs/webpack-chain#102 |
Since we don't need all of `yargs`, just the smaller parsing component, which pulls in fewer dependencies. This reduces `time node -e "require('neutrino')([]);"` (ie the baseline overhead from Neutrino before any middleware is used) on my machine from 295ms to 185ms. Refs #239.
webpack-chain 4.11.0's `.plugin('abc').use(...)` now supports being passed the path to a plugin, instead of the plugin itself. See: neutrinojs/webpack-chain#102 This means we can avoid the expensive `require()` of plugins in cases where the plugin isn't used - such as when: * running ESLint's CLI with a Neutrino-generated `.eslintrc.js` * running tests with Jest/Mocha (which don't perform a webpack build) * the plugin isn't needed for that `NODE_ENV` (eg `clean-webpack-plugin` isn't used in development). For example, this reduces `time node .eslintrc.js` for a React+AirBnb project from 1700ms to 370ms - and for projects that use more of the non-default core Neutrino presets, the improvement will be even more noticeable. As an added bonus, plugins specified by path also have their `require()` statement generated automatically when using `toString()`, meaning that the configuration output by `--inspect` no longer needs any adjustments before it can be run. ie this "just works" with the core presets: ``` $ echo "module.exports = $(yarn neutrino --inspect --mode production);" > exported-config.js $ yarn webpack --config exported-config.js ``` The webpack-chain docs have also been synced with those from upstream. Refs #239.
Should we consider this fixed now? |
Yeah config generation is now 5x faster for the eslintrc case, and further improvements would mean more invasive changes. |
Not sure how this would work yet, but it would be great to cache the accumulation of middleware between command runs. Some sort of combination of hashing package.json, yarn.lock, .neutrinorc.js, and any other used middleware, stored in a dot file in cwd.
The text was updated successfully, but these errors were encountered: