This repository was archived by the owner on Jun 26, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
This repository was archived by the owner on Jun 26, 2020. It is now read-only.
Large amount of data in component props causes devtools to peg CPU #1200
Copy link
Copy link
Closed
Labels
Description
Problem:
If a React component has a large amount of data passed in props, even by reference, the CPU gets pegged after the component renders.
Repro
- Create an array or object structure with a large amount of data, for example 10-20MB.
- Pass the array variable as the props of a component.
- Render the component.
This produces the following error:
Uncaught Error: Message length exceeded maximum allowed length.
at PortImpl.postMessage (VM27 extensions::messaging:121)
at Port.publicClassPrototype.(anonymous function) [as postMessage] (extensions::utils:138:26)
at handleMessageFromPage (contentScript.js:24)
The bottom function is this:
function handleMessageFromPage(evt) {
evt.source === window && evt.data && "react-devtools-bridge" === evt.data.source && port.postMessage(evt.data.payload);
}
Here's the current implementation of postMessage which is currently stringifying all the props for the component. Even if they're passed by reference, JSON.stringify still has to process all the data.
PortImpl.prototype.postMessage = function(msg) {
if (!$Object.hasOwnProperty(ports, this.portId_))
throw new Error(kPortClosedError);
// JSON.stringify doesn't support a root object which is undefined.
if (msg === undefined)
msg = null;
msg = $JSON.stringify(msg);
if (msg === undefined) {
// JSON.stringify can fail with unserializable objects. Log an error and
// drop the message.
//
// TODO(kalman/mpcomplete): it would be better to do the same validation
// here that we do for runtime.sendMessage (and variants), i.e. throw an
// schema validation Error, but just maintain the old behavior until
// there's a good reason not to (http://crbug.com/263077).
console.error('Illegal argument to Port.postMessage');
return;
}
var error = messagingNatives.PostMessage(this.portId_, msg);
if (error)
throw new Error(error);
};
Notes/Thoughts
- A large amount of data in props passed by ref can be a legitimate use case, for example using Vega for dataviz. Usually this isn't a problem since they're passed by ref.
- Are there any other ways to serialize arbitrary JS objects instead of JSON.stringify, for example using Apache Arrow?
- If the props are only used for display to the user in the inspect or profiler ui, would it make sense to just send the first 10-20 elements in an array and tell the user that the data was clipped? Not sure how you'd handle this with arbitrarily large objects though.
edmorley, bvaughn, wmertens, mungojam, Fi1osof and 1 more