You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
With React's concurrent mode expected to soon be released in production releases, combined with streaming SSR, our current approach of populating style tags in the <head>, becomes no longer tenable, since by the time a server-rendered component is rendered the <style> tag it is trying to populate may (and likely has) already have been streamed to the user.
This leaves us needing to find a progressive rendering alternative. Work on this has already been started in #337 and #435, but was later abandoned as the approach of of prepending additive style tags before components proved to be too complex and carry too many edge cases and cascade pitfalls, e.g.,
// ComponentA.jsimport{useFela,}from'react-fela';exportdefault()=>{const{ css,}=useFela();return(<divclassName={css({backgroundColor: "#00f","@media (min-width: 600px)": {backgroundColor: "#f00",},})}>
I'm blue and turn red in screens wider than 600px
</div>);};
// ComponentB.jsimport{useFela,}from'react-fela';exportdefault()=>{const{ css,}=useFela();return(<divclassName={css({backgroundColor: "#0f0","@media (min-width: 600px)": {backgroundColor: "#f00",},})}>
I'm green and turn red in screens wider than 600px
</div>);};
If because of streaming, server rendered html turns out to be:
<style>.a{background-color: "#0f0"}</style><stylemedia="(min-width: 600px)">.b{background-color: "#f00"}</style><divclass="a b">I'm blue and turn red in screens wider than 600px</div><!-- ... --><style>.c{background-color: "#00f"}</style><divclass="b c">I'm green and turn red in screens wider than 600px</div>
The second div will always remain green, because .c comes after .b in the cascade, at least until rehydration, when media query ordering takes place.
Alternatives
Other atomic css-in-js libraries are also faced by the same issue.
Styletron
Styletron has been tracking the issue for quite some time in in styletron/#137, which was recently superseded by the newer styletron/#334. Their current direction is to additively prepend <style> elements before component elements on the server, and then, during rehydration, remove them and append their content to the "canonical" <style> element(s) in the <head>. As I already indicated there, this is likely to cause incompatibilities between pre-hydrated and hydrated UI in a way similar to the case posted above.
React Native Web
React Native Web has also tackled this issue in react-native-web/#1136, although eventually from a different angle. A comment to this thread suggested
prepending inline <script> elements before component element instead of <style> ones. The scripts, when run, are meant to add relevant styles to the "canonical" <style> element(s) in the <head>.
Proposal
I feel the approach discussed in the React Native Web comment is currently the best solution available for a number of reasons:
Inline <script> elements are blocking in the same way <style> elements are, so there should be no FOUT involved.
Fela <style> elements in the <head> are sorted, so styles added to them will conform with the user's cascade expectations.
As result of the above, there should be not difference between pre and post hydration UI
It is critical, however, to check the performance implications of this approach.
The text was updated successfully, but these errors were encountered:
TxHawks
added
the
Type: Proposal
Proposals describe new feature ideas and additions with full examples and description
label
Dec 2, 2019
Let's discuss this over at Spectrum or WhatsApp in detail, but I'd love to see a working PR with that.
I lost track of the feature since I'm not actively using stream rendering at all.
@robinweser Hey Robin! I hope you’re doing well. 😊 Do you know whether streaming will eventually be supported by Fela? Let‘s chat on Telegram if it‘s easier. ✨
Type: Feature
Description
With React's concurrent mode expected to soon be released in production releases, combined with streaming SSR, our current approach of populating style tags in the
<head>
, becomes no longer tenable, since by the time a server-rendered component is rendered the<style>
tag it is trying to populate may (and likely has) already have been streamed to the user.This leaves us needing to find a progressive rendering alternative. Work on this has already been started in #337 and #435, but was later abandoned as the approach of of prepending additive style tags before components proved to be too complex and carry too many edge cases and cascade pitfalls, e.g.,
If because of streaming, server rendered html turns out to be:
The second div will always remain green, because
.c
comes after.b
in the cascade, at least until rehydration, when media query ordering takes place.Alternatives
Other atomic css-in-js libraries are also faced by the same issue.
Styletron
Styletron has been tracking the issue for quite some time in in styletron/#137, which was recently superseded by the newer styletron/#334. Their current direction is to additively prepend
<style>
elements before component elements on the server, and then, during rehydration, remove them and append their content to the "canonical"<style>
element(s) in the<head>
. As I already indicated there, this is likely to cause incompatibilities between pre-hydrated and hydrated UI in a way similar to the case posted above.React Native Web
React Native Web has also tackled this issue in react-native-web/#1136, although eventually from a different angle. A comment to this thread suggested
prepending inline
<script>
elements before component element instead of<style>
ones. The scripts, when run, are meant to add relevant styles to the "canonical"<style>
element(s) in the<head>
.Proposal
I feel the approach discussed in the React Native Web comment is currently the best solution available for a number of reasons:
<script>
elements are blocking in the same way<style>
elements are, so there should be no FOUT involved.<style>
elements in the<head>
are sorted, so styles added to them will conform with the user's cascade expectations.It is critical, however, to check the performance implications of this approach.
The text was updated successfully, but these errors were encountered: