-
Notifications
You must be signed in to change notification settings - Fork 71
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
Single pass ReplaceSource .node performance improvement #23
Single pass ReplaceSource .node performance improvement #23
Conversation
Update ReplaceSource .node to process all replacements in a single pass
Codecov Report
@@ Coverage Diff @@
## master #23 +/- ##
==========================================
+ Coverage 71% 75.04% +4.04%
==========================================
Files 11 11
Lines 438 505 +67
Branches 66 83 +17
==========================================
+ Hits 311 379 +68
+ Misses 127 126 -1
Continue to review full report at Codecov.
|
@sokra @TheLarkInn please let me know if there is anything additional I can provide to help clarify the issue or to explain how the updated ReplaceSource.node() method works. We are keen to get this PR merged as it makes our CI webpack builds 3 minutes faster. |
Hey @brentwilton I'm sorry for not seeing this right away. I'm slowly migrating to Octobox for tracking all of these issues and PR's across our orgs' 100+ repos. :-D Let me see if I can get this prioritized. |
This is on my weekend hotlist to merge. Again so sorry for the delay. We want to make sure this doesn't break upstream. |
Reminder! |
@alan-agius4 We have been using a postinstall script in the package.json to manually patch ReplaceSource.js for the last few months while we have been waiting for this PR to be merged. With webpack 3.8.1 and the 1.1.0 version of ReplaceSource our CI build takes 47 minutes. With the PR version, it takes 17 minutes. (the patch version was temporarily not being applied on our CI build yesterday and everyone thought that the CI server had broken due to builds taking forever) |
I dont understand why this pr is not being prioritized and it’s frustrating! I have the same problem. My CI build it takes approx 40mins because of this method. |
This is difficult to review, but I take a look soon. |
Thanks for the update @sokra. I know you guys have been busy the last few months with progressing webpack 4. To give a bit more information about the cause of the slowdown and the solution: The current algorithm does the following:
There are some performance issues with this approach
The new algorithm changes this to only traverse the source node tree a single time making a copy of it to a new tree.
The ReplacementEnumerator class handles the state of the emit flag and current replacement index. There are some special cases we also deal with:
We had a situation where a single ReplaceSource.node call was taking 15 minutes on a complex build. The new algorithm reduced that call to 0.12 seconds. |
Hello, @brentwilton! I've tried use your branch on our project, but unfortunately found a bug. We use |
Hi @vladimir-tikhonov. Thanks for trying this PR out and submitting a repro of your issue. |
…rlapping replaces
@vladimir-tikhonov I have pushed a new version. Can you check to see if it resolves your issue ? The code was double emitting the |
@brentwilton yes, the issue is resolved now. Great job! |
Can we have this re-reviewed please? |
Yes cc @sokra and @ooflorent also.
…On Sun, Jan 7, 2018, 12:30 PM Alan Agius ***@***.***> wrote:
Can we have this re-reviewed please?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#23 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ADQBMAoKsgJ51a4d4QVMv4ra-hFecZjDks5tISl3gaJpZM4Oe2IV>
.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me. It also passes all webpack's integration tests.
lib/ReplaceSource.js
Outdated
} | ||
|
||
_sortReplacementsAscending() { | ||
this.replacements.sort(function(a, b) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you define the sort function outside of the class?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@brentwilton bump
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ooflorent Moved sort function outside of class as requested.
Can we merge this obe? Super imporant for me as I have a huge app |
I think we are waiting on @ooflorent's request, and I'd like @sokra to review as well for this. Given we just released [email protected] we need to make sure this doesn't cause any breaking changes (even if tests passing). |
Any idea when will it be merged? |
Is there any update on getting this issue merged? Thanks! |
Ping! |
:tumbleweed: |
Is this getting merged? I mean who doesn't want faster compilation times :D |
Would love to see this merged too! |
@ooflorent @sokra Can we merge this one? It seems it works :) |
1yr later and this PR is not merged yet! This is just ridiculous. |
Would be awesome to see this merged! 🙏 |
Hey @sokra @ooflorent Just checking in as well if this can be merged in and released soon? |
🎉 finally merged Sorry for the delay, this was difficult to review |
and released as |
thank you :)
…On Wed, 29 Aug 2018 at 14:10, Tobias Koppers ***@***.***> wrote:
and released as 1.2.0
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#23 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AQv-WteNxcCLROvWIsoYIWXlsaC3wC99ks5uVoShgaJpZM4Oe2IV>
.
|
Is it possible to create a beta release version of webpack with this new version? |
@eranimo why? It is not major release, just update your lock file. Look on https://github.com/webpack/webpack/blob/master/package.json#L32 |
This decreased the time taken for our warm (babel-loader and uglify-webpack-plugin caches enabled) webpack 4 |
What kind of change does this PR introduce?
Performance improvement. Up to 35% faster webpack builds on large solutions.
(small solutions do not spend as much time in ReplaceSource)
Did you add tests for your changes?
Added tests to improve coverage around prepending and appending replaces as these were not covered by existing tests.
If relevant, link to documentation update:
N/A
Summary
Replaces the .node method in ReplaceSource with a version which performs all replacements in a single pass.
Does this PR introduce a breaking change?
No
Other information
This PR can produce significantly faster build times when processing large files with devtool: 'source-map'
The existing .node method walks the SourceNode tree for every replace each time, twice splitting the SourceNode tree at the replace start and end. In large source maps this can take significant time as the SourceNode constructor will individually .add each child node on each split.
The new method processes all replaces inline, turning on and off an emit flag depending on if you are in the middle of a replace or not.
The PR emits identical module and source map output as webpack 3.4.1 / webpack-sources 1.0.1. (Including use with ModuleConcatenationPlugin which chains ReplaceSource's)
For our current Angular prod build using devtool: 'source-map' and 2481 modules, this PR reduces the chunk asset optimization time (average over 3 runs) from ~314 seconds to ~127 seconds, and reduces total webpack build time from ~485 seconds to ~314 seconds. (38.5% or 187 seconds faster)