-
Notifications
You must be signed in to change notification settings - Fork 313
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
Hoist __DEV__'s process.env use out of hot code. #86
base: main
Are you sure you want to change the base?
Conversation
Thank you for your pull request and welcome to our community. We require contributors to sign our Contributor License Agreement, and we don't seem to have you on file. In order for us to review and merge your code, please sign up at https://code.facebook.com/cla - and if you have received this in error or have any questions, please drop us a line at cla@fb.com. Thanks! |
Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Facebook open source project. Thanks! |
I don't think it's practical for us to use |
This is an interesting idea… I think we thought about it before but jstransform made this really tricky & Babel is much nicer. Thanks for taking a stab at it. cc @cpojer @voideanvalue who are much better at this whole transform stuff and can give a better review. If we do go down this route we'll definitely want to make sure we update the big comment blocks describing how this works. We'll also have to do some more testing with minifiers. I don't think we want to use |
Agreed re: shipping const. IMO, there's not going to be any way, with current UglifyJS (perhaps Closure is better) to eliminate dead code only with Because of that, we'll risk an extra ~16kb in users' browser builds if they're using browserify or Webpack. I have an idea, though, and I'll explore it in UglifyJS - we should be able to tag a var as a const so we get backwards-compatible consts that can be eliminated by Uglify. Then, all we'd have to do is update this PR to print a |
We could probably do another pass in the browserify step with another babel transform. Might not be ideal but it's workable. |
Well, technically if we just changed our uglify step to replace |
UglifyJS PR is in, if it is merged I'll change this to use |
UglifyJS PR has been merged |
See react/#812. Naive benchmarks show nearly 100% performance increase in server rendering performance.
I've rebased this in case anyone's still interested: a brief history of where this is at:
This means that we no longer have to repeat a constant condition in order for UglifyJS to replace it, like so: if (process.env.NODE_ENV !== 'production') {
// dev code, this will be eliminated
} We can now just make var __DEV__ = process.env.NODE_ENV !== 'production';
if (__DEV__) {
// dev code, this will be eliminated
} Because this dead code elimination is now happening properly on browser builds, it's safe to hoist |
FWIW it's probably not going to be important soon because with React 16 we plan to have separate precompiled bundles for development and production, and just one switch. |
@gaearon And that includes SSR? Will all the files be individually compiled or will you be essentially |
We don't have Fiber-compatible implementation of SSR but the plan is to figure it out for 16 release. By that time, we intend to have |
Ref #18 Since the problem with uglify is fixed there is not reason to keep browser version which do not add any benefits. Actually it blocks us from distributing `esm` version which is widely used these days and supported by the most popular bundlers like webpack, rollup and parcel. Here's a few links facebook/fbjs#86 (comment) Both uglify and babel minify support evaulation and eliminating ```js (function () { function warning() {} var __DEV__ = 'production' !== 'production' if (__DEV__) { warning = function (msg) { console.log(msg) } } warning() } ()); ``` https://skalman.github.io/UglifyJS-online/ https://babeljs.io/repl#?babili=true&browsers=&build=&builtIns=false&code_lz=BQMwrgdgxgLglgewgAmASmQbwFDOeaeJZAdwEMAnCOCAc3SwF9tdkA3S5AfS4BEBRAGo9kAXmQByAA4UEAEzCxEECcgCEo8dNkKlSCSzxwQqHgOFcMOPHnJUatMfkh6UwALYBnWldY3kUEieCAA2AKYAdCEI9F4-fsjMeMysdtR06NiMqGhoANxAA&debug=false&forceAllTransforms=false&shippedProposals=false&circleciRepo=&evaluate=false&fileSize=false&lineWrap=false&presets=babili%2Cenv&prettier=false&targets=&version=6.26.0&envVersion=1.6.2
closes #18 Since the problem with uglify is fixed there is not reason to keep browser version which do not add any benefits. Actually it blocks us from distributing `esm` version which is widely used these days and supported by the most popular bundlers like webpack, rollup and parcel. Here's a few links facebook/fbjs#86 (comment) Both uglify and babel minify support evaulation and eliminating ```js (function () { function warning() {} var __DEV__ = 'production' !== 'production' if (__DEV__) { warning = function (msg) { console.log(msg) } } warning() } ()); ``` https://skalman.github.io/UglifyJS-online/ https://babeljs.io/repl#?babili=true&browsers=&build=&builtIns=false&code_lz=BQMwrgdgxgLglgewgAmASmQbwFDOeaeJZAdwEMAnCOCAc3SwF9tdkA3S5AfS4BEBRAGo9kAXmQByAA4UEAEzCxEECcgCEo8dNkKlSCSzxwQqHgOFcMOPHnJUatMfkh6UwALYBnWldY3kUEieCAA2AKYAdCEI9F4-fsjMeMysdtR06NiMqGhoANxAA&debug=false&forceAllTransforms=false&shippedProposals=false&circleciRepo=&evaluate=false&fileSize=false&lineWrap=false&presets=babili%2Cenv&prettier=false&targets=&version=6.26.0&envVersion=1.6.2
See react/#812.
Naive benchmarks show nearly 100% performance increase in server
rendering performance.
Benched and built on 0.14.3 tag.
Sizes:
Benchmark (50000 creations of a small nested element):
Repository for bench is at https://github.com/STRML/react-bench (soon to be updated).
In order for uglify to properly kill dead code for the browser builds, we need to blacklist
es6.constants
so the files compile with theconst
intact. UglifyJS will then optimize them away.Re: non const-supporting browsers, we'll likely need to add a post-process step to the React grunt build in case of users browserifying React without
varify
. This could potentially cause some dead code to enter user's generated browserify/uglify builds as uglify will not properly optimize consts that aren't declared withconst
. This may be something that we could solve on the UglifyJS end as it makes library compatibility difficult when forcing the use ofconst
. UglifyJS has a tracking issue.