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

Cache individual programmatic descriptors along with the overall list. #8494

Merged
merged 1 commit into from Aug 20, 2018

Conversation

loganfsmyth
Copy link
Member

Q                       A
Fixed Issues?
Patch: Bug Fix?
Major: Breaking Change?
Minor: New Feature?
Tests Added + Pass? Yes
Documentation PR Link
Any Dependency Changes?
License MIT

We added caching for presets early on for Babel 7. These caches affect how often a plugin/preset's overall function is re-executed, and come in three flavors:

  • Programmatic plugins/presets
  • Config-file based plugins/presets
  • Preset-based plugins/presets

Invalidation, and thus re-execution of these functions, has been managed differently for each of these. Up until this PR, invalidation of programmatic options has been purely based on the identity of the array itself, so if you did

const presets = ['@babel/preset-env'];

babel.transformFile("tmp.js", { presets });
babel.transformFile("tmp.js", { presets });

it would only evaluate the env preset's function a single time.

const presets = ['@babel/preset-env'];

babel.transformFile("tmp.js", { presets: presets.slice() });
babel.transformFile("tmp.js", { presets: presets.slice() });

then each call would have a different array, even though the contents were identical, and the preset function would be evaluated twice.

This PR changes the second case to still only evaluate the preset a single time, even in the second case. When I originally wrote the caching, I was on the fence about how aggressive to be here, and how much power to give to users. Over the course of 7.x's beta, I've come to the conclusion that expected usage will mean that the behavior without this PR would result in too many re-executions of the plugins/presets, and thus reduced performance.

With this PR, we preserve the old behavior, so if you give exactly the same array, it will still be the fastest, but if you give two different arrays, we'll still do our best to recognize that it is actually exactly the same preset both times, and avoid re-executing the preset.

Note, this still relies on object identity for the preset/plugin and the options object, so if you do

babel.transformFile("tmp.js", { presets: [['@babel/preset-env', {}]] });
babel.transformFile("tmp.js", { presets: [['@babel/preset-env', {}]] });

this will still run the preset twice, because it has gotten two entirely different options objects. I think that is acceptable and more along the lines of what a user might actually expect, so I don't think it's too bad. It seems too aggressive to actually try to deep-compare the options objects themselves, since that could incur a bit of a performance hit.

@loganfsmyth loganfsmyth added PR: Polish 💅 A type of pull request used for our changelog categories pkg: core labels Aug 20, 2018
@babel-bot
Copy link
Collaborator

Build successful! You can test your changes in the REPL here: https://babeljs.io/repl/build/8849/

@loganfsmyth loganfsmyth merged commit 3a399d1 into babel:master Aug 20, 2018
@loganfsmyth loganfsmyth deleted the descriptor-caching branch August 20, 2018 17:08
@lock lock bot added the outdated A closed issue/PR that is archived due to age. Recommended to make a new issue label Oct 4, 2019
@lock lock bot locked as resolved and limited conversation to collaborators Oct 4, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
outdated A closed issue/PR that is archived due to age. Recommended to make a new issue pkg: core PR: Polish 💅 A type of pull request used for our changelog categories
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants