I have read multiple articles trying to explain server-side rendering vs client-side rendering and I simply cannot seem to get a grasp of the concept. To me, when someone says "render" something, I think of the computer parsing the HTML file and presenting this to the computer screen, therefore the idea of server-side rendering makes no sense to me at first, as the idea would be for the server to parse and present it on it's own monitor.
I have seen articles mention that SSR is better for SEO, but my additional confusion comes from the fact that Create React App is a SPA, meaning to be a SPA it must load the entire page at once, and not make requests to the server when changing pages. Should this mean that since the page is loaded all at once that it is SEO friendly?
My question is, could somebody please explain what the key differences are between CSR (React app) vs SSR (Next.js) and what is meant by "rendering" and "compiling" in this context.
Related
I'm currently trying to understand the concepts behind SSR in a ReactJS application and cannot seem to understand one of the key concepts.
The official ReactJS documentation explains that when hydrating, the content rendered on the client must be identical to the one rendered on the server.
React expects that the rendered content is identical between the
server and the client. It can patch up differences in text content,
but you should treat mismatches as bugs and fix them. In development
mode, React warns about mismatches during hydration. There are no
guarantees that attribute differences will be patched up in case of
mismatches. This is important for performance reasons because in most
apps, mismatches are rare, and so validating all markup would be
prohibitively expensive.
This is clearly possible by sharing components between the server and the client but somehow seems to defeat the idea to do the heavy lifting on the server side.
If for example a page requires loading a large amount of data from a database to be rendered and this is done on the server side, the client would now need to load all the data over to the client just to render the exact same page and hydrate it.
What am I missing?
My problem is that I'm unable to understand how server-side rendering single-page application frameworks like Next.js receive prerendered, full HTML on the front end without having to rewrite the entire page. For example, the nextjs website states the following:
By default, Next.js pre-renders every page. This means that Next.js generates HTML for each page in advance, instead of having it all done by client-side JavaScript. Pre-rendering can result in better performance and SEO.
Each generated HTML is associated with minimal JavaScript code necessary for that page. When a page is loaded by the browser, its JavaScript code runs and makes the page fully interactive. (This process is called hydration.)
I understand how this bolsters the responsiveness of an SPA on first page load. But after that first load, what makes server-side rendering compatible with SPAs? I think this arises from a fundamental misunderstanding that I can't catch, so here are some further questions I have that might help you to catch it:
Do SSR SPAs always respond with full prerendered HTML, or only for first page loads?
If the former is true, then on subsequent responses, how does the client efficiently render only the difference rather than rewriting the whole page?
Otherwise, if the latter is true, then how does an SSR SPA backend tell when it's responding to a first request, when the response should be the whole HTML, versus a subsequent request, when the bulk of the page is already there and all that needs to be sent is some relatively minimal information?
What am I misunderstanding about what makes SSR compatible with SPAs?
Many thanks in advance to everyone who tackles this question!
Welcome to Stackoverflow :)
Usually SSR is used for initial rendering of the page, so for the first question - for the first page load
This is necessary, so the SPA will be more SEO-compatible (there also might be some performance improvements with this, but it's usually secondary goal) and Search Engine bots will be able to parse pages without the need for JS
The SSR usually has several important steps:
Server render
Sending of rendered data to browser
Hydration. Hydration - is a ReactJS (since we're talking about next.js here) 'function' that binds the server-rendered HTML to the React on the Frontend. So basically binds server-rendered DOM to virtualDOM
After the hydration step you basically have a fully-functional normal SPA, which has it's own routing and able to fetch data on itself.
Usually you have different endpoint on the BE to fetch the data and to render the page. So basically the rendering process on the BE is somewhat similar to what you have on the FE - your application backend fetches the data from separate endpoints, applies all of the logic and renders the app.
Btw, to ensure that SSR works properly, there is a principle called 'Isomorphic code' - i.e. if you're using a library for data fetching, it has to support both node.js and browser APIs. That's why, for example, you'd have to use Next.js own Router when you have a Next.js application - it just works on both FE and BE unlike react-router, which would require some additional steps to achieve that
What is the point of server side rendering in React/Redux?
It would seem to me that another level of complexity is being added to the software, but I don't really see the benefit of it.
What are some common use cases for server side rendering?
React's SSR (Server Side Rendering) offers some benefits over CSR (Client Side Rendering):
1. Improved (Perceived) performance at the client side
Obviously, rendered components are shown to the user right away without the need to wait for browser to render. The website won't be interactive until all React code are loaded and executed, but the perceived performance is improved by showing content to users ASAP.
2. Better SEO
Since content are rendered at the server side, search engine crawlers can see the rendered content instead of just a blank page with JS tags.
Note: Google crawler supports JavaScript rendering, not sure about other Search Engines though.
Interms of complexity - yes, SSR introduced extra complexity but there's always a tradeoff for each technical decision.
The whole point of so called Universal apps or "Isomorphic JavaScript" is its "write once, run everywhere" kind of motto. Meaning that you wouldn't need to maintain a specific backend project and a specific frontend project differing in techniques and instead consolidate a whole JavaScript project into one.
It's not quite as dandy as you'd think because you still need to maintain a backend specific part that handles the initial GET request.
Furthermore you also leverage the Single Page nature of an application whilst getting the server side first page load making your website 100% crawlable by the Googs, even though Google now crawls SPAs quite competently currently.
As for complexity - it could be as complex or as simple as you would want to, I guess. Not everything is solved by doing a "Universal app" nor is everything solved by doing a standard web app either.
I am starting a new project and one of the requirements is potentially for the app to work when javascript is turned off.
I have been using reactjs for a while but solely as a SPA javascript app that runs in the browser.
I don't think I quite understand how a react SSR application works.
next.js is intriguing. Will a SSR application work without javascript?
If not can someone explain how an SSR application works or what problem it is solving.
SSR means the server will render the initial state of the application before sending it to the client on the initial run. This makes it so that:
Crawlers see actual content and can index your site based on it.
In most cases it speeds up your application since it puts the responsibility of the initial request on the server which is usually faster than most commercial computers
An SSR cannot work without javascript. It'll render initially but then subsequent executions and state changes will not be possible.
I suppose if your application doesn't require any subsequent state changes or provide further functionalities after the first load then it wouldn't need javascript.
Pardon my English, it is a second language. The whole point of an isomorphic app, as opposed to a regular client-side SPA is so the client doesn't have to download the whole JS file initially which results in really slow initial load time.
I've been trying to teach myself server-side rendered React, and after watching countless videos around the concept and following countless tutorials on the actual implementation, I still can't get my head around this (at least this is how I understand it):
Despite the server conditionally rendering pages and sending props to the client on url change, the client side still uses a router that includes all the entry points for the app (by requiring all of them, and then loading the file based on the url location). Doesn't that means all the files are included in the main client JS file anyways since it's already been required by the client-side router? Doesn't that defeat the whole purpose of server-rendered React? Or am I thinking about this the wrong way?
In short, how does an isomorphic React app really works with a client-side router that includes (by requiring them) all of the app's entry points?
I'm not sure that "The whole point of an isomorphic app [...] is so the client doesn't have to download the whole JS file initially which results in really slow initial load time" is necessarily true. I think the primary reason people do this is for SEO reasons and to improve perceived load time. You still get the benefit of showing the users the page before they have to load all the JavaScript (e.g. yes, they have to load all the JS, but it's OK because they already have most/all of the content). The app upgrades to an SPA transparently, providing a seamless experience for the user.
That said, you can implement a system where you don't have to load all the JS at once with something like webpack's code splitting. There's even a simple React Router example that does this.