-
Notifications
You must be signed in to change notification settings - Fork 47.7k
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
Warn if stringifying an attribute takes too long #12209
Comments
@gaearon I'd like to claim this. |
Sounds good! |
Could you point in the right direction for where the migration path starts for attributes? I've been looking at the PRs mentioned in https://reactjs.org/blog/2017/09/08/dom-attributes-in-react-16.html to try figure out where to start looking, but it's been a little overwhelming. |
@Swieckowski I think you'll want to look at react/packages/react-dom/src/client/DOMPropertyOperations.js Lines 164 to 166 in fb85cf2
Those two lines are where known attribute and unknown attribute values get stringified, respectively. I'm not sure if @gaearon intends to only warn for attributes that we don't recognize, but this should be a good place to start. Keep in mind that this warning and timing logic should only happen in the DEV bundle. This is handled by wrapping code in Hope that helps! |
I'm getting 'ReferenceError: Performance is not defined', does this have something to do with the files being in client? Date.now() works fine on the other hand. |
I'm also not sure how to reliably test something that involves a performance issue across different machines, so is this something I should write a test for? |
Make sure you're using
We should write a test and use a value that will practically always be an order of magnitude or more expensive than our threshold. For example, if we set the threshold to 2 milliseconds we should test it with something that takes ~200ms+ to stringify. You could try overriding const attributeValue = {
toString() {
// do some expensive work here, like computing a hash
}
} |
@aweary I made sure to use the proper capitalization, but I got the reference error in tests no matter what I tried. This is the function I made that's only used in DEV.
I got reminded of project euler when thinking about expensive functions, and decided I'd just insert a find nth prime algorithm to a suitable number. I get ~200ms for the 2000th prime on my machine. |
Short version: I'm guessing it's alright to just test non-primitive data types? Longer learning experience version: From my understanding primitives are briefly coerced into objects during the call, so there really isn't an instance method to override. I'd have to change the actual {Insert Primitve}.prototype to override them, and it rubs be the wrong way to pollute an actual datatype prototype, especially with a time wasting function. I'm just going to go forward with the assumption that it's not that big a deal that I'm not testing primitives. Sorry if I'm being pedantic! |
Huh, I assumed jsdom had support for We could potentially polyfill it in the test setup. That would let us also implement our own version of it that always returned times in increments greater than our threshold, so we could avoid having to actually wait 200ms+ which I think is a better idea. That raises the question, do we want to fall back to @gaearon your thoughts? |
@wuweiweiwu it stalled because we didn't provide any feedback. I just requested some changes, so let's give @Swieckowski some time to address those requests before handing it off :) |
Sounds good! Thanks for letting me know! |
@Swieckowski Can I pick this up if you don't plan to work on it? I can work on top of your fork |
@aweary @Swieckowski can i take it? |
Hi, can you help fixing this, #16315 |
@gaearon Hi ! I know this issue is a bit old, but can I take it ? |
@lmerotta Sure, go ahead, ok from my side, make sure its not outdated, my PR had some outdated code as its old |
With React 16 we don't have an attribute whitelist so both
src={obj}
andmyattribute={obj}
would be valid. The objects get stringified and added as attributes for smooth migration path because a lot of the existing code already depends on this behavior.There is, however, one pitfall here. Sometimes you made do
<div {...rest}>
and not realize thatrest
includes an object whose stringifying is unusually expensive. For example a deeply nested Immutable Map. Now, this wouldn't produce an error, but it would slow down rendering for no good reason.We could protect against this by putting
performance.now()
counters around the places where we stringify attributes. If stringification takes more than, say, 2 milliseconds, then something bad is going on, and we should probably warn.The text was updated successfully, but these errors were encountered: