Comments (4)
I'm coming from #29580
Whether an object is cheap to compare or not is not a sufficient for deciding to skip memoization.
- Are two Numbers always cheap to compare? Yes.
- Are two Numbers always cheap to compute? No.
One of those numbers can be obtained via some very computationally expensive algorithm. If an app using correctly using useMemo to deduplicate those computations moves to React Compiler it may experience significant slowdown.
It is even worse for string template literals because if my understanding is correct each time we call foo()
at least a couple allocations will be performed.
const foo() => `/foo/${1}`;
- Allocate
'/foo/'
string - Call
String(1)
which allocates'1'
string. - Concatenate
'/foo/'
and'1'
which is a third allocation.
So in my understanding of how string templates work they will always be more expensive to compute then dereference from cache them and check whether the reference has changed.
In conclusion. Unless you are absolutely sure that given value is a constant requiring no additional allocations and expensive computations it should always be memoized. Especially since react compiler strips explicit memoization.
Additionally I'm not sure whether it makes sense to distinguish between primitives and objects. Javascript compares values only by references. {a: 1} === {a: 1}
evaluates to false
but 'very long string' === 'very long string'
evaluates to true
even though the second one can be much more expensive to compare due to potentially requiring many dereferences. But I think it is a topic for another discussion.
from react.
Thanks for posting. What’s happening here is that the compiler infers that expensiveFunction() returns a primitive value, which can be cheaply compared for changes. The compiler tries hard to only memorize what is strictly necessary to avoid cascading updates (parent re-renders, child re-renders, etc) and avoid memoization overhead in other cases.
In your case, is the function actually expensive enough to be a problem, or were you just surprised that the call didn’t get memoized?
from react.
I see, interesting.
In your case, is the function actually expensive enough to be a problem, or were you just surprised that the call didn’t get memoized?
I'm mostly surprised that it didn't get memoized. In the part of my code where I found this behavior, it isn't actually expensive to compute.
But I still find this behavior quite surprising. Just because a function returns a primitive value doesn't mean it is cheap to run, for instance we could have something like:
const expensiveFunction = (value) => {
return someLargeArray.findIndex(v => JSON.stringify(v) === JSON.stringify(value));
};
which feels pretty reasonable to write but should definitely be memoized. But maybe it happens rarely in practice.
What I find the most surprising is that an explicit useMemo
gets removed. I thought the compiler is designed to try to preserve existing memoization, or did I misunderstand something?
from react.
The compiler preserves existing memoization except where we can prove that the value being memoized is a primitive.
from react.
Related Issues (20)
- Bug: useCallback doesn't work sometimes inside memo component HOT 3
- [React 19] React compiler & eslint plugin giving an error to mutating values in refs that are used in JSX HOT 7
- [spam]
- [airline spam]
- [airline spam]
- How can I get in touch with Qatar in the UK? <<QATAR^_^Helpdesk>>
- [airline spam]
- [airline spam] HOT 1
- [Bug] : SSR Suspense renders dollar sign ($) in the dom HOT 4
- [DevTools Bug]: CVE-2024-29415 (`ip` dependency) HOT 2
- [Compiler Todo]: (BuildHIR::lowerExpression) Handle `MetaProperty` expressions HOT 2
- [Compiler Bug]: ref passed as prop cant be mutated in effects/events HOT 2
- [Compiler Todo]: Handle TSSatisfiesExpression expressions HOT 3
- [Compiler Bug]: Runtime error with Higher Order Components HOT 1
- Refs merging/combining HOT 5
- [React 19]
- How to access impure values during render (initially labeled as compiler bug) HOT 2
- Bug(react-hooks/exhaustive-deps): lint rule does not recognise typescript satisfies operator HOT 2
- DevTools Components Hide components filter should hide the component it owns HOT 3
- [React 19] eslint-plugin-react-compiler: “Writing to a variable defined outside a component or hook is not allowed. Consider using an effect” HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from react.