-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Turn off negate_iife by default as it hurts V8 performance. #886
Comments
Do you have some actual numbers showing the difference in performance? |
I second @rvanvelzen. Can't believe there is any significant difference, or else I'll make fun of @mraleph. >-) |
@mishoo I haven't touched V8 source for 3 years now - no need to make fun of me ;) |
@mishoo this is on an internal app and I'm focused on android performance issues testing on an S3, I'll pull together the numbers for you but if I do, please don't make fun of anyone or tweet it. |
@krisselden you should report the numbers to V8 folks. I am sure they'll be interested. Startup issues caused by overly zealous lazy parsing heuristics have been increasingly on the radar lately AFAIK. |
@mraleph in a single page app, they help by deferring components and templates you don't use in initial render is actually pretty nice, it is just a bit touchy because it is double parsing a lot of code that is needed for initial render. |
Just kidding. @mraleph is one of the greatest compiler/JIT engineers and V8 rocks. Any case, can't believe this small thing could cause a big slowdown — if it does then the V8 folks definitely want to know about it. |
It is hard to reduce this to a simple example because the issue is deferring work that happens when you use code in the app, just reducing it to a simple example really alters the trade off, I also regret because I think changing the default is a bit alarmist and I was tired and frustrated. It is good enough for me that it is optional. |
Related to #543, #640, and rollup/rollup#774. |
FWIW I made a benchmark around this, seems to confirm it's a perf boost for V8 and Chakra: rollup/rollup#774 (comment) |
they should add this style to there iife detection I'm also concerned that as we bring attention to this lots of people are going to start wrapping parens around everything forcing the browser to compile stuff that should be lazy. V8 also recently has improved parse perf |
Yeah the tricky part here is that it's not the case that you want to add parens around functions willy-nilly, but that you want to do it everywhere where you know the function will be executed. The current optimization in Chakra (and I assume for V8 as well) is due to the fact that most JS functions out in the wild are never executed (i.e. web authors ship a lot of unused code), so it's a perf boost to lazy-parse. However when people ship highly-optimized tree-shaken bundles where every function gets immediately executed, it's a perf regression to do the lazy-parse. Probably the main problem with the current Also worth pointing out: this optimization doesn't just apply to IIFEs - it also applies to any paren-wrapped functions that are immediately executed. So it's not clear that changing the default |
OK, so I ran some more benchmarks and have some updated info on this.
Edit: my bad, I was wrong, see below. |
@nolanlawson your benchmarks are bad, at least for Chrome, the heuristics in the top level of a large script (above 1024) follow the preparse rules which are more simplistic. Also, this option seems to affect unrelated things: https://gist.github.com/krisselden/c43d47be74dcc3e870a8c014c6e68079 |
Just to clarify, the preparse phase is only for script files and only top level function literals. Lazy parsing still happens for literals below but the heuristic isn't a simple. |
@krisselden I'm sorry, I don't understand what you mean; can you clarify? Also my benchmark is open-source, so please feel free to fork to show me what you mean. 😃 Based on that benchmark it seems to me that unwrapped UMD and declare-then-execute are the only two unoptimized ones in either Chrome or Edge, but I may have made a mistake. |
having trouble with github's image upload, but you can't wrap your script in a function literal, this is a top level thing with chrome. |
Hm OK in that case I need to go back and rewrite the bench without the top-level |
@nolanlawson I've trolled myself many times with benchmarks, it is important to check your work, but at least you made it verifiable and public. |
Thanks for calling me out @krisselden; here's a corrected benchmark. My results show that Edge is optimized for the |
On Safari it errors out with:
|
@nolanlawson Chrome on Mac Version 53.0.2785.116 (64-bit)
Edit: My bad. It's consistent with your observations. |
For Firefox 48.0.1 on Mac I'm seeing 2.8ms across all techniques. |
You may have to switch to a slower computer to see the difference in Firefox. I tested 48.0 in both Mac and Windows and I see the same perf characteristics as Chrome. Here's a typical run:
So the slow version is ~3.5-4ms and the fast version is ~1.5-2ms. Perhaps it would be easier to discern if I used a larger library than Immutable.js. I tested in Safari 10 and can't repro your |
Safari 9.1.3. Is 10 out of beta? |
No, I'm on macOS Sierra, but it's still a preview. |
Removing the
(
before iife causes V8 to preparse to skip function bodies in top level iifes (when the script is large) then parse it when executing and also affects the hinting for lazy function body compiling.From the V8
preparser.h
:The text was updated successfully, but these errors were encountered: