-
Notifications
You must be signed in to change notification settings - Fork 68
RFC: Streaming SSR and it's impacts #31
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
Comments
This works for getting around +> style:first-child + *,
> :first-child {
background-color: blue;
} Now it's just a matter of figuring out |
|
It's possible to work around it in emotion too: emotion-js/emotion#1178 (comment) |
hi jess! yep but you need to opt into the SSR extraction stuff aka "advanced ssr" - instead of that we'll be extracting to CSS files as the "advanced" setup this is to solve the out of the box SSR problems where it compiles your css into your javascript but results in an inline style element using the edit: this doesn't solve if the element in question has multiple style elements associated with it. which it very well could. |
All sorts of patterns are problematic with style tags rendered throughout the tree (consider for example |
oh that's such a good point! |
With atomic CSS, this approach will fail in quite a few, much more basic cases than the ones mentioned above, and there has been rather extensive discussion of the issue in other atomic style libraries such as React Native for Web, Styletron and Fela. The Fela Issue is my attempt to try and sum up all possible approaches and pitfalls, so It'd start with that. In addition to everything mentioned above, <style>
.a { color: hotpink; }
@media screen and (min-width: 600px) { .b { color: red; } }
</style>
<div class="a b">Reliably hotpink until 600px and then red</div>
<!-- ... -->
<style>
.c { color: green; }
</style>
<div class="b c">Always green because @media doesn't add specificity</div> Worse even, is that this behavior isn't stable. If the second component was to be rendered first, colors would be applied as expected with One possible solution, initially raised in a comment on the RNW issue is to use inline Like anything else, this approach too is a trade-off, since it will not work with JS disabled. The performance implications of this approach should also be considered. |
love your work @TxHawks, thanks! like you said everything has its trade-offs, we will have to keep this in mind. another alternative i can think of that wouldn't need a JS solution would be to keep track if there are any nested selectors and always render them, resulting in some duplications so for example:
which of course is betting that duplication will be, on average, smaller than the javascript boilerplate but it's something we need to keep in mind regardless, thanks dude! |
Thank @Madou Duplication would indeed work in this naïve example, but in other cases, could also cause unexpected inconsistencies, because it still alters the cascade (definitions bubble up - This would be fine with the previous example, but would fail in this one, for instance (you'd also have to apply duplication to pseudo selectors, not just nested ones: <style>
.a { color: red; }
.b:focus { color: blue; }
.c:active { color: purple; }
</style>
<button class="a b c">I'll be unexpectedly blue when active because of the second style block</button>
<!-- ... -->
<style>
.a { color: red; }
.b:focus { color: blue; }
.d:active { color: hotpink; }
</style>
<button class="a b d"> * * * </button> Progressively rendering |
Another point is that size-wise, duplication doesn't save the JS boilerplate, it just defers it to a later time. You'd need it anyway to move the content of the different |
Q: is it any easier to deal with this stuff when creating just a single extracted stylesheet? My guess is not rly - but i havent thought about ot extensively. Definitely it couldnt rely on atomic classes for pseudos and would have to create „per component” ones, right? |
It's a lot more straightforward with a single stylesheet (extracted or in In Fela, we create a It's a lot simpler to reason about a single, predictable, source of truth, especially in a language that is order-dependent like CSS. |
Extracted single atomic sheet is what we are aiming for for the final destination in app, but for the intermediate state ensuring a workable 0 config story is something we must offer. When we look at trade offs I think there are the must haves and the nice to haves when it comes to streaming support (or in our case, 0 config support) Must haves would be ensuring that:
Are stable. And don't change before/after JS executes. If:
Until JS executes wouldnt be the worst I think. Are there other categories of edge cases you can think of? |
Feature queries ( I'm also not at all certain that the JS boilerplate required for the inline As an aside, regardless of how the server-side application of styles will happen, for the client-side |
Cheers will do 🙂
cc @pgmanutd had some good discussion today ^
…On Tue, 6 Oct 2020, 6:28 pm Jonathan Pollak, ***@***.***> wrote:
Feature queries ***@***.*** blocks) also come to mind in the same way as
media queries, but I'm sure there are other edge cases I'm just not
thinking about right now.
I'm also not at all certain that the JS boilerplate required for the
inline script based solution will be larger than duplication, especially
non-trivially sized applications.
As an aside, regardless of how the server-side application of styles will
happen, for the client-side style element insertion, I'd recommend Fela's
approach to style elements, as it enables a very clear separation of
concerns (global, fonts, media query), and by so eases the task of sorting
rulesets.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#31 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABT4PHNB5ORJWFLXC6ZH7TTSJLBKLANCNFSM4KCVWUBQ>
.
|
A solution for the
|
FYI @itsdouges; see above |
Hey mate. With extraction being the target for production there really isn't a need for inline styles anymore. Instead we can leverage the style hoisting behavior introduced in React 19 during development and then keep having extraction when building for production. And then the inline style elements become a thing of the past and we side step this whole issue. @kylorhall-atlassian if you're interested :-) |
Edit: Update 6/Oct/2020
Because we've pivoted to atomic CSS things now are made more complicated. We still however need to maintain this story.
Currently we operate essentially the same as Emotion's default config.
SSR rendered markup:
Client markup:
While this means SSR is 0 config and it just works (with streaming as a bonus) - it makes using any
nth
selectors annoying/shitty to use.I really want to solve this without re-architecting how things work for the default implementation.
We need to investigate if we can do some CSS magic to create equivalent selectors for the 90% case that:
Remember: The
style
element will move when JS executes. We need to handle both states.The text was updated successfully, but these errors were encountered: