React (and Vue, et al) was built with client side rendering in mind. It just does not seem to fit the server side rendering pattern.
What are the use cases? From my perspective, if your app is a rich web app with a lot of interactivity, you probably want CSR and don’t benefit much from SSR.
If you have a content-centric site, or a site with some interactivity but not much, you want a static site generator, or SSR. But in that case, a template engine with some smaller client side libraries (jQuery or AlpineJS or idk what all is out there).
Using React SSR for all of these seems like the wrong tool. What am I missing?
My hot take: Silicon Valley’s kids need to give themselves the illusion of progress with ever changing “best practices” and trends. 30% of my work was probably keeping up with deprecations that rarely truly improve anything.
The mere existence of the term “server-side rendering” illustrates this well. I remember the first time I read about that concept and immediately thought “you mean the way we’ve been writing websites since the 90s?”
Maybe I’m just out of date, but IMO web development has completely lost its way. I don’t do much frontend work anymore, but when I do my goals are always to see how few JS libraries I need to use and how little JS I need to write in general. The end result of that plus doing all/most work on the backend, sticking to standard HTTP conventions, and using only vanilla JS means super fast and performant websites with fewer bugs, less constant deprecations to keep up with, less security vulnerabilities in all the JS libraries, and no constant headaches from a complex Webpack-style build system for assets. It’s actually quite enjoyable when you remove all the bs of modern JS frameworks from your workflows.
I remember the first time I read about that concept and immediately thought “you mean the way we’ve been writing websites since the 90s?”
This is a poorly informed take. Your pop’s dynamic html server side rendering has nothing to do with the problem of rendering DOMs generated by JavaScript running in a browser according to the client’s state and leave it in a coherent state. Trying to pass off React’s SSR for the same thing that was done in the 90s is like trying to pass off an Android app as the programs written for DOS.
Is it not generating HTML on the server to be served to the client? What you’re describing is, in my opinion, an overly complicated form of dynamically rendering HTML on the backend. It’s exactly what I’m talking about: the layers and layers of complexity modern web development has added hasn’t really solved any problems but rather primarily created problems which are solved with another layer on top as a fix which has problems of its own, and repeat.
Anyway, that’s my opinion on the matter, I’ve toiled with modern web development tools my fair share and time and time again found that removing all of them in favor of vanilla JS where strictly needed and traditional dynamic backends is the most reliable and performant, and frankly enjoyable form of web development. I know others like those workflows and the complexity/power they bring and that’s fine, it’s not my cup of tea though.
Is it not generating HTML on the server to be served to the client?
No, it generates the code that creates the DOM, sets the application state based on the user’s setting, and updates the webapp to resume working in a consistent state.
It basically sends a frozen instance of a full blown JavaScript application.
What you’re describing is, in my opinion, an overly complicated form of dynamically rendering HTML on the backend.
That’s because you’re oblivious to the problem domain,and thus you’re falling back to the unrelated but similar sounding things you’re familiar with to fill in the void of your understanding of the actual problem.
Anyway, that’s my opinion on the matter
My point is that your opinion is a misinformed one,and really doesn’t hold up to scrutiny.
Alright, I’m not going to get into an internet pissing contest over front end techniques since despite being in the industry for over a decade I’ve been deemed oblivious and misinformed based on two comments. I’ll keep doing things my way and you can do it your way. I’m not going to lose sleep over it or resort to calling names over a comment on the internet of someone’s opinion I don’t agree with.
My hot take is that I find it so much more pleasant to write typescript and do most of the work in the front-end rather than deal with optimizing the response time of the backend day in and day out. With SPAs it’s so much easier to fetch just what is needed rather than have monolithic responses that take ages to arrive. Makes caching and cache invalidation that much easier too.
Htmx is a godsend for that. You actually write HTML while having AJAX easily.
Here’s my hot take as a dev who’s been making websites since before JavaScript and css were invented: modern web development is leaps and bounds better than how it was and the rapidly changing best practices had a big part for how we got there in the time we did. I think the industry is in a great place now and now that it is things have slowed down and the focus is now on stability rather than changing development patterns.
Hello fellow old person. I mostly agree, and I think we’re starting to see some convergence on the core patterns that will define the “best way” to deliver web apps for years to come. The various offshoots of React are really just evolutions to see what fat we can trim and tighten it up. But functional-reactive UIs as a general thing are here to stay and better than all the other ways we’ve wired up GUIs to date.
After experiencing ad hoc inline scripts, frameworkless jQuery spaghetti code, inflexible monoliths like angular, and overly simplistic micro frameworks like backbone, I’m super happy with where we’re at with react and react like frameworks. I really do feel like we’ve hit the sweet spot between power, simplicity, flexibility, and ease of use which is why I’m confident that things aren’t going to be as volatile as the past. React is already 10 years old now and still going strong with no new trends looking to usurp it. I think those old trends were necessary experiments to get to where we are now, and I think the old meme of web dev changing every week is no longer true.
I agree that things improved. React and others are amazing for CSR. We have static site generators which are also amazing and nice to work with. But SSR territory is in strange place right now. React is overused in places it doesn’t belong.
I’ve had a good time with react SSR and SSG particularly when using next.js which does a great job optimizing out of the box, but really SSR and SSG are functionally just glorified string interpolators so anything will do. What matters is ease of use and with the strong community and toolset available to react I’ve had no trouble setting up react for SSR/SSG.
Where things still need improvement is with hybrid apps that take SSR/SSG pages and hydrate them to be ready for the client to take over, but that’s always been a pain point, and while we’re still not where we need to be I do think it’s better than it’s ever been and we’re on the right track to cracking it.
Maybe it’s because I’ve seen how bad things can get that I’m appreciative of what we have. After experiencing frameworkless jQuery spaghetti code, overly complicated monoliths like angular, and overly simplified micro frameworks like backbone, I’m really happy with the frameworks and toolsets we have now, and react’s ecosystem is very mature.
I would say that react is overkill for SSR, but pure SSR is pretty simple so react is also able to handle it just fine and elegantly as react is even easier to use when you’re not dealing with dynamic state, and if you find the need to introduce some hybrid client side functionally, which pretty much always happens eventually, it’s a good thing to be on react.
Nextjs is pretty far with the hybrid approach with appdir. It’s not perfect by any stretch of the imagination, but it works surprisingly well
You can configure nextjs to compile as only client-side-rendering, so that it runs like before!
Another thing: NextJS is not only SSR. It’s hybrid. The advantage here is that it decreases the visible first load time.
First load pre-rendered HTML and styling is sent to the browser. So the page is already fully visible. After that all scripts and secondary CSS will be loaded. And even after that the bindings will be done.
Where as with pure CSR, all JavaScripts need to be loaded and executed and only then stuff will become visible to the user
I think you may be missing the concept of ‘hydration’. A server side rendered app will deliver the pre rendered markup so that the client has something to immediately display while the framework continues to bootstrap in the background. It makes for much quicker and more efficient first loads, or ‘time to first paint’. A SSR website will still be a CSR website after hydration completes.
In addition, many web crawlers are unable to execute JavaScript. So for many single page applications, or CSR as you call them, they appear as a blank screen to less sophisticated crawlers because the content is never loaded. This is an catastrophe for things like SEO. SSR fixes this issue by delivering the content without regard to JS execution for the initial load.
If SEO matters beyond a couple landing pages, I find it unlikely that you would be developing a rich web app with that much reactivity. You are more likely content focused, in which case a static site generator or simpler SSR frameworks are easier and fit the use case much better. Even from a performance perspective, why ship the entire react run time if you do not need it?
And on the other hand, if you are developing a rich web app with a lot of interactivity, then do you really need SEO beyond a couple (or one) landing pages? You should develop the web app in React CSR and build the landing pages as static sites to optimize SEO. That is a lot easier to me.
The biggest issue is flexibility. What if you don’t know if a page is going to need SEO or rich client side functionality when you build it, but then it does later? Do you want to rewrite the page from scratch every time that happens? This is especially true when you’re trying to maximize productivity for junior devs on a large team. Are all devs working on the site knowledgeable enough to make the static site vs CSR call correctly when they first start working on every new page? Wouldn’t a “Use framework X and we’ll figure that part out later” approach be easier for everyone?
Also, what about pages that need both SEO and rich client side functionality. You can choose to limit yourself to only one or the other on any given page, OR you could use hydration to have your cake and eat it too. Maybe react or vue isn’t the right abstraction, but if we can come up with a strong enough abstraction, hydration is a really useful general purpose pattern.
I suppose I just cannot imagine a situation where a rich interactive web app needs SEO that is not solved by having a separate landing page (and such solution not being way better and less effort than alternatives).
React has enough flexibility to be added later on to a project and not take over the entire web page, but only the parts it manages. It can act as a separate island or series of connected islands. So if you start thinking you dont need react but then later decide you want to add it to your non-react site, it should still be easily doable.
There are many scenarios you’d want seo and a csr. Let’s say you want a media player. Tons of interactivity, and lots of content. A landing page isn’t going to cut it.
But that’s the beauty of a framework like nuxt or next - you don’t have to choose. You can have your cake and eat it too so to speak.
I think it’s more a case of the tool being used, not because it’s the best tool for the job, but because it’s the tool the dev knows how to use. SSR allows frontend devs to become full-stack devs.
That’s exactly how we got Javascript on the backend in the first place. I remember when this was the new “weird” thing.
React and Vue already have lots of libraries, components, and know-how. You can also move from CSR to SSR and back depending on your requirements.
That’s definitely the best argument for it, I don’t deny. But I’m glad to see the web components space to be improving as well.
If you have a content-centric site, or a site with some interactivity but not much, you want a static site generator, or SSR. But in that case, a template engine with some smaller client side libraries (jQuery or AlpineJS or idk what all is out there).
React works well in this role too because it supports SSR. This part seems to assume that React SSR is inferior to other classic backend HTML SSR solutions, which is not my experience. Even for static non-interactive content, the way React has you organize your code into components is a much better setup than most classic HTML template systems I’ve used. And then React makes it very easy to sprinkle in interactivity where you want, without requiring you to bridge unrelated server-side html templates and front-end code (which can often blow up in complexity and require work to be re-done separately on each side of the codebase). The same React components can be used in server-side rendering and client-side code, so whenever some new page interactivity requires the client to render something that was previously only server-side rendered, you don’t need to rewrite the component’s code in a new system and maintain two versions of it.
SSR is a overloaded term.
-
There’s SSR to help improve FCP (first contentful paint). This is not really so much an improvement to the client side framework as it is a crutch to workaround the fact that the frameworks are dynamically constructed clientside. But the first paint would just be
Root
node which is essentially empty. Because React and Vue are so heavily tied to the DOM structure, it expects to be the compositor of the tree, not something written in HTML. For pure HTML to be the compositor, you would need to add some rehydration to React/Vue to take a pre-composed state and reintegrate it into what React expects. -
SSR is also used to dynamically build content that is presented to the user that is not necessarily tied to rendering. This is popular with PHP, where instead of putting a blank table and then having the client fetch content over JS and then populate that table, the server just hands you the precompiled HTML. Not all the data as sent over JS may be useful (eg: only 10% is used after filtering and pagination), so to save transfer size and query latency, it may be the server that gets the always data from the store or cache. There’s less client JS in execution, which may also help in performance.
-
Then there’s SSR for the purpose of improving SEO. This relates more to the first point, but maybe the first paint isn’t important. Maybe client-side construction is plenty fast. But because the root is just blank, search engines that don’t perform synchronous JavaScript can’t actually read the content being shown to the user after all the rendering is said and done.
Personally, I’ve moved to Web Components that solves almost all of this. You can author layouts in HTML and anything that you want in your HTML file for SEO is included in the source. I would only use SSR to target the second issue, where you want to save on trips to build dynamic content. It is somewhat wasteful to give clients instructions to fetch and render when the server can do that on the first trip. The issue is rehydrating, or picking up from that state, but that truly depends on how complex your Web Components are. If they are sparse and simple enough, then all states should be able to be expressed over attributes. First paint can be reduced with the template shadow root, but I feel it’s more trouble then it’s worth and has negligible performance gains compared to just doing a prerender JS to register components and the browser will only render synchronously what’s in the viewport anyway. That means time to first paint is not dependent of how big your page is. It’s only dependent on how many elements you want to register before
DOMContentLoaded
.From a financial aspect, I’m not about to ditch static CDNs to reinterpret nearly every single request with some server for SSR. The costs are nowhere near the same to try to reinterpret with SSR. You can micro-optimize to death with a SSR to CDN route and then hydrate, but I feel you risk complicating deployments to where you’re so vendor-locked you have extra hoops to jump to make changes. God forbid you want to change frontend systems. At that point the DX pain is too much to justify and wanting to get out is inevitable.
-
By my understanding on the matter, it depends on use case. Ecommerce websites benefit greatly from SSR due to the fact that they want to be able to show content as quickly as possible so the user have something to interact with. It also improves SEO.
Well that’s why you would render on the server, not why you would use React to do it instead of the many, many server side frameworks
Oh, I just realized I completely misunderstood your post.
But then you’d be sacrificing all that comes with React. Unless you mean having the page rendered by another framework and having React components loaded later, but I’d think that would be less maintainable than if the whole thing was just in React.
Cozx we went to a full circle. Back to sveltekit now until we find a better solution. Back then Virtual DOM was a feature, now it’s more of a bug.
deleted by creator
Technically base html, css, and js are client side, so it is easiest to continue that. If you want something node based that is server, use express with stuff like mustache.