The web app world changed a lot in the last years
We came to the PHP frameworks like Laravel, Symfony and others. This way to reused page takes a superpower. On these frameworks, we could create layouts and extends that to only add the content that we need to use it.
The concept of SPA is to create a friendly experience to the user with a flow very similar to a desktop application.
The best thing on this type of app is the experience because you don't need to request the page to the server and you could create an animation between a route to route because it is the same HTML page. But not all is great...
Not a friendly integration with SEO
Friendly SEO is very hard, because when you or a bot try to get the code. You received something like that...
Currently, SEO understands those pages but I think that it's not common behavior. If you request a page you wait to that page return structured information about what is it. Which brings me to the next point...
It's not normal behavior to the browser
If you, sometimes, had set up manually an SPA you discovered the 404 issues on AngularJS. If you want to remove the '#' of the URL to simulate the real URL, you need a node server that on all cases send the main HTML file.
All browsers expect that when the user uses a URL, that loads content. So if browsers received falsy empty content, it's so weird.
Having the same page loaded for a long time can cause considerable problems with your computer memory (browser crash, issues with the power battery, etc)
Tricky browser loading indicators
If the browser indicator says that the page completes the load, you would be sure that the page is ready. But is not the case to SPA pages.
So, we could use it to create better web apps. But.. could we run our beautiful UI frameworks form the server? Yep, we can.
If you want to render React from the server you have to use react-dom/server with a utils function, renderToString. Check this sample:
Easy right? Well, not.
This is only the first part, if you need to handle an event or change the DOM, this doesn't work. The function name says all that you need to know, this creates a string with the HTML and sends the initial view to the client, despite using React this app is not reactive.
If you want to be this App reactive, you need to use hydrate React function. Instead of using render, that creates a DOM, you should use hydrate, that matches a DOM with VDOM on React.
For more information, you could check on React documentation.
With all this knowledge on your head, let me explain what is isomorphic apps. If we see the app wrapper on a SPA we should see something like that:
We only change the common render function by a hydrate function. This code will run on the client. We create a little server with the following code...
In this case, the app will render on first time by the location that the server received on the request. This creates an isomorphic router, the first rendering populates the request URL as a router URL. But when the app is loaded, the route is managed by the client.
When you need to propagate the state from the server to the client. You could implement something like the image.
In these cases and others, re-hydration has a considerable cost. Because we need to propagate the data from all the VDOM.
Some people propose some solutions to solve these issues.
These ideas are about reducing the scope to hydrate the app. We could hydrate by events or only hydrate the visible part on the browser, like lazy-hydration (check that GitHub repo).
That's all folks, thanks for reading.