-
Notifications
You must be signed in to change notification settings - Fork 47.4k
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
Add support for using !important in inline style values #12181
Add support for using !important in inline style values #12181
Conversation
@necolas is there any way you could publish the benchmarks with this change? I'm curious how it performs on lower-end mobile devices as well. |
No problem: https://necolas.github.io/react-native-web/benchmarks/react-patch/ I've tested on a Moto G4 and a 2011 MBP so far. The React implementation is React 16.2 + this patch. The The |
Do you think this feature will make it into React 16.3? |
Updates the 'setValueForStyle' implementation to support style values that contain "!important". This allows the 'flex{Basis,Grow,Shrink}' values created by the style resolver to be applied. They currently use the important priority as a work-around for browser-inconsistencies in the 'flex' shorthand. Upstream fix: facebook/react#12181 Ref #798
175599b
to
7cc1ff4
Compare
Updates the 'setValueForStyle' implementation to support style values that contain "!important". This allows the 'flex{Basis,Grow,Shrink}' values created by the style resolver to be applied. They currently use the important priority as a work-around for browser-inconsistencies in the 'flex' shorthand. Upstream fix: facebook/react#12181 Ref #798
Updates the 'setValueForStyle' implementation to support style values that contain "!important". This allows the 'flex{Basis,Grow,Shrink}' values created by the style resolver to be applied. They currently use the important priority as a work-around for browser-inconsistencies in the 'flex' shorthand. Upstream fix: facebook/react#12181 Ref #798 Close #813
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 change looks reasonable to me.
I wish there was a way to test it, but I jsdom doesn't seem to support it properly as you say.
I'll defer the final decision on this to @sophiebits because I am not familiar with this part of the codebase. @gaearon has expressed concerns that this could be considered a breaking change. (Personally, I feel it's more of a bug fix but I also see his POV.) @sebmarkbage may also have opinions about this wrt future CSS APIs. (He's on PTO though so I wouldn't expect a response from him at the moment.) |
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.
The benchmarks and implementation look good to me 👍
To clarify what I meant a little bit. A bug fix and a breaking change are not mutually exclusive. Sometimes we release a breaking bugfix in a patch. But this is rare and we only do this when it worked just a minor or a patch ago, and we know we recently messed up and the cost of not patching it up is high. In this particular case the updates never worked, and the initial render worked for the last time in 0.14. So this hasn’t worked at all for about two years. At this point I am confident there is code in the wild that depends on this being broken. For this reason I don’t think we can consider it a non-breaking bugfix. It doesn’t solve anything that hasn’t already been broken for two years. So in my view releasing this in a patch or minor (and definitely breaking people) is more disruptive than our usual workflow for breaking changes (add a warning that behavior will change, then change it in the next major). All of the above assumes we actually want to go with this API. I think this might be a good candidate for an RFC first. It’s not clear to me which alternatives were considered and why they were rejected. The DOM API doesn’t search a string—perhaps there is a good reason for this, and we shouldn’t either? |
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.
See above
The primary hesitation according to #1881 was performance and IE8 (#1881 (comment)). We don't support IE8 and @necolas' benchmarks look good so I think the main question now is whether this is the right API. The only alternative I've seen proposed is using an object like I'm 👍 for saving this for a major release.
Can you clarify here, what DOM API? |
I think using an RFC feels like overkill for what is a fix to an old regression. I understand the reasons why it could be considered a breaking change and delayed until React 17, although I'm not sure if the argument is that styling bugs are a special case or that fixing old bugs is always a breaking change (ref #6411). I'll look again at work arounds in RNW or leave it broken and flag the surface where this is an issue for the library. Thanks :) |
For #6411, the surface area is vastly smaller IMO. But it would be interesting to first add a warning, and then see how often it fires at FB. |
#12179 is a patch to add a warning. Would you like me to reopen it or would you prefer to try it internally on www dev? |
Closing this due to lack of maintainer interest |
FWIW I don't think we're opposed to supporting this feature per se. It's just that it's not clear a string-based API is the best one here. |
For such a little feature, designing a new object API seems like it would introduce even more overhead in the areas you are concerned about - DX, bundle size, render time. It's the browser API that's the slow part, and any React API is going to have to use it with the current way styles are applied. And if React doesn't want to support |
The part that feels wrong to me is that everybody has to pay for an |
The string search perf angle is valid. It can become significant for many large URLs. The XSS issue is another one. I don't see an immediate problem but the overlap of SSR and string manipulation is a tough space and might require an even more expensive validation. |
Yeah I was concerned about that, but there was no indication of an issue in my tests, and you've already introduced a cost like that for custom properties. Everyone would also have to pay a cost if you introduced object values in style. So if any kind of cost in unacceptable you may as well say that this feature will never be supported and add a dev warning to the library. My 2¢ |
Type checking again a value is really fast though typically have to be done regardless at some point in the optimization pipeline (even if this was native/wasm). I felt like the custom properties thing was motivated by that we probably actually want to change the API to only support the setProperty path which is a major breaking change but more likely to be in line with future direction of CSS such as Typed CSS OM. So eventually we'd get rid of that. |
IIRC,
👍 hadn't thought about XSS |
In our measurements setProperty has been significantly faster, which is another reason to do it. Do you have a benchmark in mind? Perhaps it's something we're doing. |
At first, I looked into only using When running the RNW perf regression tests modified to assess this patch, I noticed that using |
Ah. The plan was to not convert every property to the hyphenated form but instead require people to specify the hyphenated form in their code. That is the breaking change. |
Updates the 'setValueForStyle' implementation to support style values that contain "!important". This allows the 'flex{Basis,Grow,Shrink}' values created by the style resolver to be applied. They currently use the important priority as a work-around for browser-inconsistencies in the 'flex' shorthand. Upstream fix: facebook/react#12181 Ref #798 Close #813
Updates the 'setValueForStyle' implementation to support style values that contain "!important". This allows the 'flex{Basis,Grow,Shrink}' values created by the style resolver to be applied. They currently use the important priority as a work-around for browser-inconsistencies in the 'flex' shorthand. Upstream fix: facebook/react#12181 Ref #798 Close #813
Updates the 'setValueForStyle' implementation to support style values that contain "!important". This allows the 'flex{Basis,Grow,Shrink}' values created by the style resolver to be applied. They currently use the important priority as a work-around for browser-inconsistencies in the 'flex' shorthand. Upstream fix: facebook/react#12181 Ref #798 Close #813
Updates the 'setValueForStyle' implementation to support style values that contain "!important". This allows the 'flex{Basis,Grow,Shrink}' values created by the style resolver to be applied. They currently use the important priority as a work-around for browser-inconsistencies in the 'flex' shorthand. Upstream fix: facebook/react#12181 Ref #798 Close #813
Updates the 'setValueForStyle' implementation to support style values that contain "!important". This allows the 'flex{Basis,Grow,Shrink}' values created by the style resolver to be applied. They currently use the important priority as a work-around for browser-inconsistencies in the 'flex' shorthand. Upstream fix: facebook/react#12181 Ref #798 Close #813
Proposed solution for supporting the
!important
priority for inline styles (#1881). I couldn't write a test for this change; it looks like jsdom doesn't fully support the browser APIs being used. Please let me know if you've got any ideas.I used RNW's early-warning benchmarks to check how this change affects the
inline-styles
timings in Chrome. I couldn't see any difference when styles don't use!important
. There is a 10-15% increase in time taken when every node in the tree (>600) has at least one style value using!important
and going through the new code path. Overall it looks like it avoids introducing a performance regression for existing using ofstyle
while enabling use of!important
if needed.A micro-optimization PR for
hyphenateStyleName
infbjs
helps a little too.(This patch is related to #12179, which adds a warning when
!important
is used.)