Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Massive performance improvement by using sync requires in NodeJS #74

Open
eliseumds opened this issue Nov 8, 2018 · 10 comments
Open

Massive performance improvement by using sync requires in NodeJS #74

eliseumds opened this issue Nov 8, 2018 · 10 comments

Comments

@eliseumds
Copy link

Hi everyone,

I've seen a pretty big performance improvement by using sync requires in NodeJS. I just tweaked the loadOption function:

if (opts.isNode) {
  // import('aaa') => require('aaa')
  argPath.parent.callee.type = 'Identifier'
  argPath.parent.callee.name = 'require'
}
else {
  // import('aaa') => import(/* webpackChunkName: 'aaa-123' */ 'aaa')
  argPath.addComment('leading', ` webpackChunkName: '${chunkName}' `)
  otherValidMagicComments.forEach(validLeadingComment =>
    argPath.addComment('leading', validLeadingComment.value)
  )
}

It seems like generating multiple chunks, and then using LimitChunksWebpackPlugin to merge them all together for SSR is slow. Does my change make sense? Could it break stuff?

@konpikwastaken
Copy link
Contributor

Can you explain the perf improvement you're seeing? Is this with regards to build time?

An import statement and a require statement are more or less equivalent as webpack transforms it to it's own webpack import statement AFAIK.

@eliseumds
Copy link
Author

eliseumds commented Nov 8, 2018

@konpikwastaken yes, build time. We have a pretty large app with thousands of modules that went from 10s to 2s rebuild time in dev, for example.

Whenever Webpack sees an import statement, it'll split from that point on. It doesn't seem like it's the splitting part that is slow, but rather the joining of modules by LimitChunksPlugin

@konpikwastaken
Copy link
Contributor

konpikwastaken commented Nov 8, 2018

Yeah, I get it - I just looked through the LimitWebpackChunksPlugin code as well, so I see what you're saying. On building server bundles though, I thought that import(...) statements became require(...) anyway when you have target:'node' set during build - but perhaps I'm confusing this with what occurs after the chunks are all pieced together.

I can try this out on some projects tomorrow and see if it works as expected - we have some projects using wonky setups with SSR, flushing used chunks, and some crazy webpack path aliasing.

/edit: I mean I think require(..) & import(...) (sync import) with target=node becomes __webpack__require__(...)

@ScriptedAlchemy
Copy link
Collaborator

Check out the RFR demo or universal ones if you have any issues.

@ScriptedAlchemy
Copy link
Collaborator

Slowness tho, that’s been problematic server build kills.

@eliseumds
Copy link
Author

@ScriptedAlchemy our setup was already working great, but development build times were not. I indeed followed the RFR demo since the beginning, but it is a very small application that doesn't represent real-world scenarios; it works, it's fast, but it won't be as fast once it expands to thousands of modules and 100+ chunks. I just did a quick test with 500 extra modules and build time was decreased from 37s to 16s when I disabled LimitChunkCountPlugin. It gets worse and worse the more modules are added.

@ScriptedAlchemy
Copy link
Collaborator

I hear you! We all suffer from it.

I might just fork the plugin and use more efficient mapping like fast-transducers

It’s sucks but it’s kind of out of our hands unless we take the hit and try to repair the crap. I hate the plugin. Haaaaaate

@ScriptedAlchemy
Copy link
Collaborator

what you can do, is just disable ssr builds in development. What I’ve been doing do one build and turn off HMR on the server

@ScriptedAlchemy
Copy link
Collaborator

Can someone PR the README with an example webpack configuration.

This would be so helpful and valuable

@eliseumds

@cdoublev
Copy link

cdoublev commented Aug 27, 2020

I believe that the suggested change will break chunk names flushing, and that adding an example in the README isn't a good idea since it's the RUC responsibility to provide it and having multiple examples in different repositories will make it hard to maintain. Or maybe add a link to Universal Demo.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants