-
Notifications
You must be signed in to change notification settings - Fork 48.8k
[Flight] Remove back pointers to the Response from the Chunks #33620
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 o 10000 n GitHub? Sign in to your account
Conversation
It's the only one that needs it.
The reason field is free to be reused for this purpose.
One thing we could also do is in idle cycles, warm up any remaining lazy references by initializing them. Which could save future CPU work and release memory by figuring out which references will end up being used. |
@@ -625,6 +609,7 @@ function initializeModelChunk<T>(chunk: ResolvedModelChunk<T>): void { | |||
initializingHandler = null; | |||
|
|||
const resolvedModel = chunk.value; | |||
const response = chunk.reason; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I hate it. ... I vote for evil, by the way. 😉
@@ -486,31 +472,31 @@ function createResolvedModelChunk<T>( | |||
value: UninitializedModel, | |||
): ResolvedModelChunk<T> { | |||
// $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors | |||
return new ReactPromise(RESOLVED_MODEL, value, null, response); | |||
return new ReactPromise(RESOLVED_MODEL, value, response); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A comment like we have for createInitializedStreamChunk
would help avoid confusion:
// We use the reason field to stash the controller since we already have that
// field. It's a bit of a hack but efficient.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's all over every access in this file and indeed every Fiber field too. At some point you just got to add a doc for the whole repo.
This frees some memory that will be even more important in a follow up.
Currently, all
ReactPromise
instances hold onto their originalResponse
. TheResponse
holds onto all objects that were in that response since they're needed in case the parsed content ends up referring to an existing object. If everything you retain are plain objects then that's fine and theResponse
gets GC:ed, but if you're retaining aPromise
itself then it holds onto the wholeResponse
.The only thing that needs this reference at all is a
ResolvedModelChunk
since it will lazily initialize e.g. by calling.then
on itself and so we need to know where to find any sibling chunks it may refer to. However, we can just store theResponse
on thereason
field for this particular state.That way when all lazy values are touched and initialized the
Response
is freed. We also free up some memory by getting rid of the extra field.