-
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
Unperformant Stringify Warning - WIP #12263
Changes from all commits
b294360
969268e
d4c1c5f
ce53b1d
9500ee4
2f4dad4
bce68be
23ea3d2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,6 +15,7 @@ import { | |
BOOLEAN, | ||
OVERLOADED_BOOLEAN, | ||
} from '../shared/DOMProperty'; | ||
import warning from 'fbjs/lib/warning'; | ||
|
||
import type {PropertyInfo} from '../shared/DOMProperty'; | ||
|
||
|
@@ -132,8 +133,13 @@ export function setValueForProperty( | |
const attributeName = name; | ||
if (value === null) { | ||
node.removeAttribute(attributeName); | ||
} else if (__DEV__) { | ||
node.setAttribute( | ||
attributeName, | ||
stringifyWithPerformanceWarning(value), | ||
); | ||
} else { | ||
node.setAttribute(attributeName, '' + (value: any)); | ||
node.setAttribute(attributeName, (value: any).toString()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. isn't this will throw on There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, @Swieckowski please revert this. We were intentionally not using |
||
} | ||
} | ||
return; | ||
|
@@ -160,10 +166,12 @@ export function setValueForProperty( | |
let attributeValue; | ||
if (type === BOOLEAN || (type === OVERLOADED_BOOLEAN && value === true)) { | ||
attributeValue = ''; | ||
} else if (__DEV__) { | ||
attributeValue = stringifyWithPerformanceWarning(value); | ||
} else { | ||
// `setAttribute` with objects becomes only `[object]` in IE8/9, | ||
// ('' + value) makes it output the correct toString()-value. | ||
attributeValue = '' + (value: any); | ||
attributeValue = (value: any).toString(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why was this changed? The comment above no longer reflects the actual code. Aren't we concerned about IE8/9 anymore? If not, then the comment should also be updated, I guess. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. https://reactjs.org/blog/2016/01/12/discontinuing-ie8-support.html Just IE9+ it seems There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Swieckowski please revert his back as well. |
||
} | ||
if (attributeNamespace) { | ||
node.setAttributeNS(attributeNamespace, attributeName, attributeValue); | ||
|
@@ -172,3 +180,17 @@ export function setValueForProperty( | |
} | ||
} | ||
} | ||
|
||
// Only used in DEV, stringifies a value and Warns if it took too long | ||
const stringifyWithPerformanceWarning = value => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For consistency let's move this to the top of the file, and then only define it in DEV let stringifyWithPerformanceWarning;
if (__DEV__) {
stringifyWithPerformanceWarning = function(value) {
// ...
}
}
`` |
||
const stringifyStart = Date.now(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We want to use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks a lot for the review, I'll get on it sometime soon! |
||
let attributeValue = (value: any).toString(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please use |
||
const stringifyEnd = Date.now(); | ||
|
||
warning( | ||
stringifyEnd - stringifyStart <= 2, | ||
'Stringifying your attribute is causing perfomance issues', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Typo: pefomance => performance. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The messaging here isn't clear enough. Let's also pass the attribute name to Lets make it look like: warning(
stringifyEnd - stringifyStart <= 2,
'The attribute `%s` took more than 2 milliseconds to stringify. This usually means you provided a large object ' +
'as the value for a DOM attribute, which can lead to performance issues.%s',
attributeName,
getCurrentFiberStackAddendum(),
) |
||
); | ||
|
||
return attributeValue; | ||
}; |
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.
IMO, We don't need actual implementation (which will slow down the test suite). I think better do polyfill
global.performance
in the test setup and implement our own version of it (like @aweary mentioned in #12209 (comment)).For an idea, we can take a look at
react/packages/react-dom/src/__tests__/ReactDOMRoot-test.internal.js
Lines 49 to 53 in 2cf9063
or
jest.mockImplementation
might be helpful.Hope this help :)
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.
Yeah, let's go ahead and go with mocking
performance
instead of actually taking too much time.