Skip to content
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

fix: Variant build stylesheet for RNW #121

Merged
merged 1 commit into from
Feb 17, 2022

Conversation

dobrea-v
Copy link
Contributor

@dobrea-v dobrea-v commented Dec 1, 2021

This PR tries to fix a bug on RNW, which consists in incorrect styles generation for variants. The issue is also mentioned here by @chris24elias

It happened after #94 fix, which introduced use of StyleSheet.create in buildStyle, however for createVariant this is causing incorrect styles resolution.

It can be seen in this codesanbox

Checked this fix on the web, and variants are working as expected, with atomic classes being generated. And on RN everything works as expected.

I understand that this library doesn't have official support for RNW, but would be nice to have variants working on the web.

@ghost ghost added the cla-needed label Dec 1, 2021
@dobrea-v
Copy link
Contributor Author

Sorry to bother, but I wasn't able to tag Reviewers when creating this PR for some reason, so I will ping in comment. @drmas @JoelBesada is there a chance we can merge this PR, or maybe there is something more that should be addressed?

@linddominic
Copy link

@dobrea-v I can take a look!

@Yonom
Copy link

Yonom commented Dec 18, 2021

We also have this issue with text styles from variants and applying this PR fixes the bug for us!
Thank you @dobrea-v and @linddominic

I wonder what the root cause of this bug is? I think there's a RNW bug hidden here

@dobrea-v
Copy link
Contributor Author

Thank you @linddominic

@Yonom

I wonder what the root cause of this bug is? I think there's a RNW bug hidden here

Maybe there are some differences in implementation between RN and RWN regarding StyleSheet API, I will try to dig deeper.

To be more clear about bug, in description I wrote 'incorrect styles generation for variants', but that not actually true, more precisely is that we are loosing variants styles. This happens because we run variant styles two times through 'buildStyle' function (which now returns StyleSheet.create, the return is a reference to StyleSheetRegistry), and we get something like StyleSheet.create(StyleSheet.create(props)), which it cannot resolve.

@Yonom
Copy link

Yonom commented Dec 19, 2021

@dobrea-v ahh, thank you for your thoughts!

In RN, Stylesheet.create is actually a no-op:
https://github.com/facebook/react-native/blob/main/Libraries/StyleSheet/StyleSheet.js#L371

So my theory is that RNW compiles Stylesheet.create to a CSS class, it does not support nesting and that causes a deviance in behavior on RNW

Copy link

@Yonom Yonom left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I just tested this PR and it turns out that #94 is effectively undone by this PR. All styles are being applied inline using the style prop instead of CSS classes... 😕

If that is the fix, why not undo #94 to keep the code simple? (not a rhetorical question, this is an actual suggestion)


I looked into react-native-web's Stylesheet API and I think calling Stylesheet.create in the render loop for each component instance causes a ton of style IDs to be generated. This is a memory leak

Relevant code:

@dobrea-v
Copy link
Contributor Author

Thanks @Yonom for pointing to the fact that Stylesheet.create is no-op in RN, this confirms that the performance impact is negligible for RN.

Regarding your reply:

So I just tested this PR and it turns out that #94 is effectively undone by this PR. All styles are being applied inline using the style prop instead of CSS classes... 😕

Firstly this is not true, it can be seen even without testing, this PR cannot possibly un-done #94, just because the changes are just in createVariant file, which has no impact on all other parts, only variants. (if you don't have variants in components, it's not even run once).

Secondly I double-checked my changes just in case, and this PR does generate atomic CSS classes as it should, for both style props and variants, and there is not a single style property. More then that, having multiple instances of same component, they share same atomic CSS (which should be obviously intended, but I decided to mention it just in case).

Here is a screenshot from my storybook

storybook rnw

Just to proof that i'm not getting this out of the blue, here is another screenshot, where you can see the changes from this PR

storybook rnw

If you can show me your tests, so we can figure out what is wrong on your side.

Copy link

@Yonom Yonom left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dobrea-v sorry, that was a sloppy test on my part, I had another patch-package applied to my code (which reverted #94 🤦)

I can confirm that this test works alright. This looks like an improvement over the current situation. 👍

However, the issue regarding the memory leak is still there (styles are stored in ReactNativePropRegistry and a new style ID created every render, making the object grow over time)

@dobrea-v
Copy link
Contributor Author

@Yonom that's ok, I'm glad that everything worked out.

However, the issue regarding the memory leak is still there (styles are stored in ReactNativePropRegistry and a new style ID created every render, making the object grow over time)

When we will merge this PR, I will try to create some performance benchmarks between versions. I will need them anyway for our product, since we are planing to re-use our mobile app components (made with restyle) on web, and I don't want surprises there 😀.

Copy link

@Slvk-goparrot Slvk-goparrot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@dobrea-v
Copy link
Contributor Author

@linddominic @drmas Is there a chance we can merge this PR, as you can see in this thread we made some tests and it solves the issue. Also as i can see many are waiting for this fix. Thanks in advance

@RikSchefferOberon
Copy link

This fix should also be added to the useRestyle hook to also make that work on web

@edgaryp
Copy link

edgaryp commented Feb 9, 2022

I am also using the variants to build the UI library for native and web with NRW so this fix would be very helpful. Thank you for your time @dobrea-v 🙏🏼

@dobrea-v
Copy link
Contributor Author

Hey, @RikSchefferOberon

This fix should also be added to the useRestyle hook to also make that work on web

Not sure what is the use case. As far as I know useRestyle just accepts restyle functions, and variants is not one of them. Maybe userRestyle can be improved, but I guess it's out the scope of this PR. But even if it will support variant as a param, it would still fallback to createVariant so it will probably work anyway with this fix.

@edgaryp sure no problem, I am glad to help restyle because I really enjoy working with this lib. but I still I don't see any attention for this PR from maintainers, which is a bit disappointing. Maybe @ElviraBurchik can help.

@ElviraBurchik ElviraBurchik merged commit 5a9de94 into Shopify:master Feb 17, 2022
@ElviraBurchik
Copy link
Contributor

Thanks for your contribution, @dobrea-v 👏

@dobrea-v
Copy link
Contributor Author

Thanks @ElviraBurchik 🥳

@dobrea-v dobrea-v deleted the fix/variants-on-rnw branch February 17, 2022 20:00
@dobrea-v
Copy link
Contributor Author

@ElviraBurchik can we create a new npm version with this fix?

In change log I would suggest to write: Fix web support for variant's

Appreciate your help 🙏

@ElviraBurchik
Copy link
Contributor

@dobrea-v sure, I will do that tomorrow 👌

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants