dillon1000/react

Commit

Option to not memoize non-aliased function parameters

This has been nagging at me for a _long_ time: we unnecessarily memoize function 
callbacks passed to things like Array.prototype.map, even though we know these 
functions can't escape. This PR fixes this as follows: 

* Adds a `noAlias?: boolean` flag to builtin function signatures, defaulting to 
false if not specified. 

* Adds a feature flag, `enableNoAliasOptimizations`, to gate optimizations based 
on the value of that new flag. 

* When the feature is enabled, `PruneNonEscapingScopes` now looks up the 
signature of method calls, and avoids memoizing the arguments if the signatures 
specifies `noAlias: true`. 

* Annotates Array.prototype.map and Array.prototype.filter as `noAlias`. 

This does not mean we'll never memoize arguments to Array.prototype.map, it just 
means that the argument itself won't be considered as escaping. If the function 
still escapes by some other means it will get memoized: 

``` 

function Component(props) { 

const f = () => {}; // memoized! 

const x = [].map(f); // not from here.. 

return [x, f]; // but bc it escapes here 

} 

``` 

Note: this delivers some of the wins from #1640. That PR tried to do a bunch of 
things, part of which I already landed w the introduction of 
ConditionallyMutate, which allowed us to type Array.prototype.map. This PR 
further gives us the ability to understand functions that don't alias their 
params at all. The remaining bit from #1640 is the idea of understanding that 
key hooks such as `useFragment()` return transitively readonly, transitively 
array/object/primitive values, and any `.map()` or `.filter()` calls must be on 
arrays, allowing us to optimize them. Without that extra step, we'll still have 
to memoize a lot of `array.map()` lambdas just because we aren't sure that the 
receiver is an Array. But this PR helps with some cases, and lays the groundwork 
for the rest of that PR.
Browse files
Changed paths10 files
First-parent comparison
M compiler/packages/babel-plugin-react-forget/src/HIR/Environment.ts ModifiedM compiler/packages/babel-plugin-react-forget/src/HIR/ObjectShape.ts ModifiedM compiler/packages/babel-plugin-react-forget/src/ReactiveScopes/PruneNonEscapingScopes.ts ModifiedA compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/array-map-frozen-array-noAlias.expect.md AddedA compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/array-map-frozen-array-noAlias.js AddedA compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/array-map-mutable-array-mutating-lambda-noAlias.expect.md AddedA compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/array-map-mutable-array-mutating-lambda-noAlias.js AddedA compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/array-map-noAlias-escaping-function.expect.md AddedA compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/array-map-noAlias-escaping-function.js AddedM compiler/packages/fixture-test-utils/src/compiler-utils.ts Modified
Patch

Files changed

Rendering syntax-highlighted changes…