-
Notifications
You must be signed in to change notification settings - Fork 48.8k
[Flight] Serialize functions by reference #33539
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
Conversation
const processedChunk = encodeReferenceChunk(request, id, serializedValue); | ||
request.completedRegularChunks.push(processedChunk); | ||
const reference = serializeByValueID(id); | ||
writtenObjects.set(value, reference); |
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.
There's a problem with this set today that it's not safe to write into this from renderConsoleValue
because renderConsoleValue
has a different serialization logic (e.g. it can serialize functions like this and can cut off properties at a certain depth).
That's why we don't actually dedupe objects neither unless they also appear in the actual RSC payload elsewhere. Currently we only read from it and assume that if you're sending it across anyway, then whatever serialization happened in the production path is good enough also for the console value path.
We should really have a separate writtenObjects set just for the renderConsoleValue serialization.
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.
ah that makes sense. Thanks for handling the follow up!
…33583) Stacked on #33539. Stores dedupes of `renderConsoleValue` in a separate set. This allows us to dedupe objects safely since we can't write objects using this algorithm if they might also be referenced by the "real" serialization. Also renamed it to `renderDebugModel` since it's not just for console anymore.
On pages that have a high number of server components (e.g. common when doing syntax highlighting), the debug outlining can produce extremely large RSC payloads. For example a documentation page I was working on had a 13.8 MB payload. I noticed that a majority of this was the source code for the same function components repeated over and over again (over 4000 times) within
$E()
eval commands.This PR deduplicates the same functions by serializing by reference, similar to what is already done for objects. Doing this reduced the payload size of my page from 13.8 MB to 4.6 MB, and resulted in only 31 evals instead of over 4000. As a result it reduced development page load and hydration time from 4 seconds to 1.5 seconds. It also means the deserialized functions will have reference equality just as they did on the server.