-
Notifications
You must be signed in to change notification settings - Fork 48.8k
Begin replacing propertyInfo.* access with functions #11733
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
06037ea
to
0c067a0
Compare
// different attribute names (see DOMAttributeNames below) | ||
// different attribute names (see `attributeNames`) | ||
// TODO: this doesn't seem great? Probably means we depend on | ||
// existence in the whitelist somewhere we shouldn't need to. |
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.
I remember when we hit this adding custom attributes, and it didn't feel great. It would be awesome to get to the bottom of this.
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.
Yea, definitely will. I have another set of commits that dives into this but it turned out to be a rabbit hole and I decided to do these first.
multiple: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, | ||
muted: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, | ||
multiple: HAS_BOOLEAN_VALUE, | ||
muted: HAS_BOOLEAN_VALUE, |
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.
I think this is probably fine, but why the change?
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.
Not sure what you mean? I removed the flag.
c9ca797
Easier to read as individual commits.
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.
Got it. Thank you!
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.
@gaearon at this point it looks like there aren't any properties that contain more than one flag. We could probably stop using bitmasks and just use an enum, remove checkMask
and use a single property in propertyInfo
instead of 6.
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.
My plan is to get rid of propertyInfo
completely (maybe). This PR is just very iterative.
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.
This is a good observation though.
var attributeName = propertyInfo.attributeName; | ||
var namespace = propertyInfo.attributeNamespace; | ||
var attributeName = getAttributeName(name); | ||
var namespace = getAttributeNamespace(name); | ||
// `setAttribute` with objects becomes only `[object]` in IE8/9, | ||
// ('' + value) makes it output the correct toString()-value. |
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 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 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.
Maybe only IE8?
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.
(Regardless, don't want to change the logic here, only the structure :-)
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.
Totally. It's just nice to look at this code again with a fresh set of eyes. I'll file an issue.
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.
|
||
export function shouldUseProperty(name) { | ||
return usePropertiesFor.has(name); | ||
} |
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.
Could this just be inlined in DOMPropertyOperations
? Doesn't look like it's used anywhere else. Also, we could then just do check the set directly instead of a function call too.
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.
I want to consolidate all property/attribute stuff here first, then refactor it to make function contracts clearer, then possibly spread it out. I'd rather not spread it out yet.
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 just easier for me to deal with it if it's all in one file. Easier to see patterns.
var attributeName = propertyInfo.attributeName; | ||
var namespace = propertyInfo.attributeNamespace; | ||
var attributeName = getAttributeName(name); | ||
var namespace = getAttributeNamespace(name); | ||
// `setAttribute` with objects becomes only `[object]` in IE8/9, | ||
// ('' + value) makes it output the correct toString()-value. |
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.
Internally they're still implemented as flags. But this is now an implementation detail I can change.
Now that all propertyInfo access is internal to DOMProperty, we can stop exposing the property info. This shows the code paths that are different depending on whether something is whitelisted or not. These are bad because ideally our other helper functions should work just fine regardless of the whitelist (they just should have correct defaults for things that aren't in the list). We will need to start getting rid of these calls.
8479472
to
2423bd6
Compare
This removes the existing duplication.
9e29763
to
495297f
Compare
My previous changed caused it to access the fields multiple times. Now that it's encapsulated inside DOMProperty, I can implement it efficiently again.
c4a6ddd
to
650d731
Compare
Instead, keep a Map of name to type constant. The only real mask at this point was positive numeric + numeric, so I used switch fallthrough.
@aweary Indeed it's much nicer without masks, thanks for the tip. |
// An attribute that can be used as a flag as well as with a value. | ||
// Removed when strictly equal to false; present without a value when | ||
// strictly equal to true; present with a value otherwise. | ||
const OVERLOADED_BOOLEAN = 5; |
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.
👍 💯
@gaearon glad it worked out, it looks great! At this point, I wonder if we could just get rid of We'd lose out on the |
Yes but we'll need to see what's more compact in terms of bundle size. I'm not sure. |
@gaearon I checked this out locally and made the change to compare bundle sizes. By inlining the config the |
Nice. Please push to my branch? |
209ff28
to
63703c2
Compare
These changes seem to make the results neutral again (after a small regression).
propertyInfo.hasOverloadedBooleanValue | ||
); | ||
if (propertyTypes.has(name)) { | ||
switch (propertyTypes.get(name)) { |
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.
Is the overhead of the switch greater than the double lookup of has
and get
?
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.
I was trying to avoid making it polymorphic (number/undefined). Maybe that's silly, dunno.
'multiple', | ||
'muted', | ||
'selected', | ||
]); |
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.
I know microbenchmarks are dangerous, but would indexOf or object property membership be faster?
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.
I bet in the long-term checking set membership will be faster, since that's the sole purpose of the data structure. If we're still getting 25 million ops/s with a set it's probably fine to use it since its the correct data structure for this.
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.
Ya. I hesitated to say anything. Dan just mentioned the extra look-ups were slowing things down a bit.
Feel free to disregard.
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.
If it's a non-trivial performance regression we should definitely consider changing it. It's just so nice using Set
and Map
instead of arrays and objects 😍
Meh. It's too slow. I need to rethink this. |
The goal is to remove the "injection" step at initialization. I find it confusing because we always have to look in three places: the configs, the initialization logic, and then the use of those properties. I think this is partly why the logic got so tangled by now.
I'm starting by removing the
propertyInfo.*
properties one by one, replacing them with function calls. There might be better implementations—happy to revise them. In some cases it may seem like we'd have to repeat an attribute name a few more times than before, but I think it probably gzips well, and in any case I'll make sure the size is smaller or the same before merging.Note I'm not changing logic yet. There are a few oddities in how code paths differ based on whether
propertyInfo
exists—which ideally shouldn't be the case. I'll looking at that later.