-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
Example of an SSR RNWeb adaptive/heavily responsive site #1688
Comments
As for SSR media queries: https://github.com/artsy/fresnel I believe this is the only reliable approach. |
Rendering all permutations of our responsive breakpoints/orientations serverside isn't an option i'm afraid |
@elmpp Then you have no other option. |
There are plenty of options and it's kinda why i'm asking the question
I'm not looking for another discussion of the merits of each, just examples please (it's the reason for the question) |
Any React DOM app using those SSR techniques is an example. It's not usually a good idea for apps to do "full SSR". The new Facebook app doesn't even do that, even though it has chosen to rely on SSR. You still want to lazy load expensive assets that aren't needed for the initial render |
Yeah the majority of components probably will be lazy loaded (user-specific data) but we're finding there is another class of components that need to be adaptive and would be best rendered ServerSide. Examples would be a our navigation which hits an api for its items but looks and operates quite differently mobile/desktop |
I guess so but RNWeb's atomic CSS-in-JS means the media queries can't be generated and sent down initially - it has to "pick" which can lead to jank for those prerendered components Anyway, thanks for the reminder about facebook.com - it does actually render entirely differently based on UserAgent so it's just the example i needed (and stores it in cookies for subsequent visits) 👍 |
SSR techniques don't generate media queries either. The only good thing about CSS media queries is that a SSR response doesn't need to know anything about the viewport dimensions. The problem with CSS media queries is how little you can do with them in the first place since they have no relation to the DOM (unlike JS media queries). They're completely deficient when it comes to creating dynamic apps that adapt to their environment, supporting everything from a portrait phone to a widescreen desktop screen. Even using client hints it's pretty complicated to get a SSR web app to render as if it were in the browser. At the moment there is probably no benefit for SSR of a React app, because you pay the cost of rendering on both the server and the client. The initial response isn't even interactive. Plus, using a PWA architecture would let you cut out the server roundtrip for assets anyway. |
I have a similar experience at my workplace. We had a large RN codebase first and needed to do the web at a later stage. Using
2 was not easy to solve, so in some places where SEO didn't matter, we simply code-splitted some part and did CSR there because having SP and PC components separately led to so much duplicate code. I however later decided to ditch Next.js and SSR altogether because the added complexity of SSR hurt our team productivity and decided it wasn't worth it (responsive design, developing for both client/server, using lib limited to SSR compatible, not exposing credentials to shared pages, etc all added extra cognitive overhead). I migrated the app to create-react-app + hand-written small A bit off-topic: I faced one issue when I set up Rendertron though: CSS wasn't picked up properly. I believe it's due to RNW's optimized CSSOM? @necolas. I added a script to copy RNW style into a dummy style tag for HeadlessChrome UserAgent to solve this. |
Yeah - the I agree distinction is correct there for an app where the true value is after the client initialisation but for a more presentational site the more a site can be SSR'd the better (for example a movie details page with "related movies" sidebar). The difference in UX can be quite stark for this kind of audience Another big factor that isn't thought of so much is the ability to cache - if you're rendering large portions of the site during SSR and then caching in Cloudflare or wherever you're reducing load on both Server and API |
We have a similar situation whereby another styling solution choice (Radium) is incompatible with RNWeb leading to all the components needing to be wrapped. This definitely feels like you're fighting things at that point so i understand you choosing a different path
Yeah, the extra complexity really is a massive factor. Only thing i'd say in its defence is that it is getting easier (@EvanBacon @brunolemos have helped loads with the 100% reuse dream) and when it works well it can allow a very small number of devs create a product for all platforms with proven SEO + great UX (can you imagine facebook.com lazy loading the main feed now it's done SSR?!) |
Radium's styling implementation is incredibly slow and should be avoided. I think this question has been answered. There currently isn't a way to define static CSS media queries with this API, and that prevents certain responsive layouts from being possible via SSR before the client initializes |
@necolas Is it possible to expose the styleResolver as unstable_styleResolver this would help me a great deal to make some kind of library which would work on the server too. E.g.
To make this work on the server I would like to use the styleResolver to generate all combinations of styles as hardcoded classNames and add them later outside of react based on screen width/height with screen listener in javascript outside of React. |
I don't understand why you'd need that API to do what you're saying. Sounds like you can already do that now. But if you're using JS media queries that's not going to really work for SSR anyway |
It can if you load the script tag directly in the html instead of via React |
But that would require generating the classNames for all possible configurations so I know outside of React which classnames to add based on width/height. E.g. I would have a JSON in my script tag like this <script>
const styleIfLargerThan = { width: { 700: "rn929 rn 292 rn292" }}
let element = getElementbyUniqueID('CrossResponsive9293002')
const screenWidth = window.screenWidth
const applyClasses = Object.keys(styleIfLargerThan.width).filter(width => screenWidth > Number(width)).map(width => styleIfLargerThan[width])
element.classes.add(applyClasses)
</script> This would run before React hydrates the view so the user does not see any flickering |
Ofcourse this approach would only be done in SSR and client-side still in a normal way without any internal api's needed |
That's currently a very fragile approach. I'm not going to expose any internals to support that, so you can reach into the modules at your own risk. I happen to be working on another framework that could support this, but the problem space overlaps with SSR streaming and is something that should really be automatically handled by a framework that explicitly supports these features. |
You can also use dataSet to connect styles from outside the framework to data-* props. Obviously won't be compatible with RN though. And you lose the deterministic rendering guarantees too |
I don't think that's what I'm looking for, but I dont use SSR that much and our app had much of the same styling across mobile and desktop. Only one place where I needed this today. Maybe if I feel like I'll hack a together a small demo with demo of this approach so we can discuss it further |
I have the same Problem, but I'm wondering if SSR has to be full SSR. I think, from SEO point of view, a bit of client codes to fix rendering is not a real issue, as long as it does not create too much vertical and horizontal offset. Because Google SEO does execute JS for a certain time to allow complete rendering. I could just rerender the difference at client side under useEffect. But |
@necolas I really appreciate your thoughts on this, and I totally understand your opinion on the fragility of CSS media queries. With React 18's SSR + Suspense and Server Components approaching, it seems that the React team is investing heavily in SSR. Do you anticipate any changes to RNW and its view on media queries as a result? Thank you! |
Trying to solve the problems of SSR with responsive styles, I just published react-native-tailwind.macro which allows you to write responsive styles based on Tailwind that get converted to CSS media queries on the web. Under the hood, the macro extracts and compiles all the Tailwind styles and uses react-native-media-query to produce CSS media queries that are applied to elements with a generated Basically what it does is turn this: const Comp = () => <View tw="w-[100px] h-[100px] bg-blue-500 md:bg-purple-500 lg:bg-pink-500" /> into this: const useTailwindStyles = createUseTailwindStyles({
/* statically generated RN styles */
})
/**
* This gets added to the CSS stylesheet:
*
* [data-media~="rnmq-f324bd"]: {
* background-color: rgb(59, 130, 246);
* height: 100px;
* width: 100px;
* }
*
* @media (min-width: 768px) [data-media~="rnmq-f324bd"]: {
* background-color: rgb(139, 92, 246) !important;
* }
*
* @media (min-width: 1024px) [data-media~="rnmq-f324bd"]: {
* background-color: rgb(236, 72, 153) !important;
* }
*/
const Comp = () => {
const _tailwindStyles = useTailwindStyles()
return (
<View
style={_tailwindStyles["randomId"]}
dataSet={{ media: "rnmq-f324bd" }}
/>
)
} On the web, the View then uses the styles matched by the I'm curious if this approach works for other libs as well, but I think statically extracting styles based on JS objects (that might contain non literal stuff, like references to variables, etc.) might be quite tough (but not necessarily impossible 🤷 ). |
Hi there,
At my place of work we have a large RN codebase and have been working hard on the web platform side of things. We have a very high level of code reuse made possible by RNWeb (thanks). We're doing SSR (using Next) for SEO reasons mostly
Here's the rub - almost everyone approaches this web platform work as if it's a standard responsive website ("let's use media queries", "let's lazy load all components") and i'm not doing a good job communicating the differences particularly with regard to the RNWeb "atomic CSS-in-JS" styling of RNWeb vs standard CSS, especially with SSR thrown into the mix
Using the Twitter site as an example helped loads but as it's CSR it doesn't cover all bases and we're now stuck in the depths of lazy loading vs "full SSR" (with vary headers ) discussion.
Are there any good examples of an SSR RNWeb site out there? Bonus points if they go full SSR and perhaps communicate the client dimensions etc via cookies or other method.
Thanks
The text was updated successfully, but these errors were encountered: