The easiest way to do this is to not use javascript for everything in the first place and to actually generate html instead of expecting people to run your code, then having to do it yourself in a convoluted workaround when they won't or can't.
This is probably the worst possible takeaway from this article.
> not use javascript for everything
Using JS for frontend + backend has significant advantages. Your developers only need to know one language/codebase. You don't need to hire/maintain separate frontend/backend teams who need to figure out how to coordinate with each other.
> actually generate html
That's what server-side rendering does.
> expecting people to run your code
This is how the web works, for the vast majority of users and markets worth serving.
> having to do it yourself in a convoluted workaround
Running your frontend code on the backend to generate HTML is an elegant solution and extremely easy to implement. These days it works out of the box. Not sure where you got the idea it was a "convoluted workaround".
> Running your frontend code on the backend to generate HTML is an elegant solution and extremely easy to implement. These days it works out of the box. Not sure where you got the idea it was a "convoluted workaround".
Oh boy, this must be the overstatement of the decade. I've done SSR with a few frameworks now, including Meteor, Nest, and Next. Saying that "it works out of the box" is so disingenuous, it borders on fake news. Even ignoring the trillion edge cases involving authentication, cookies, localstorage, dynamic components, promises/futures, async components, and so on, it will take dozens of man-hours to get properly-rendered server output that works with server-side routing, hydration and looks good on Google's SEO crawlers.
From my experience, this is not the case, not for a long time now, at least.
With proper architecture, all you need is plain React (no frameworks) with `styled-components` for everything - i.e., server rendering, client rendering, and hydration.
The architecture I'm describing is a fully top down approach, with concerns separated into API, UI, and App components, where the route dictates the data to be fetched, which is passed as a `store` to the layout to be rendered, with each layout being a composition of the UI components, App components, and occasional API components. I've had a lot of success with this approach and it is, in my opinion, the simplest way, incredibly easy to follow and maintain, and extremely minimal for what is actually being achieved.
With this architecture, switching between server-only rendering and client-only rendering and/or some combination of both becomes a matter of minutes, or even just seconds if you have some env var switches in place.
Simple example: I worked on an app where I wanted to use the @elastic/eui UI framework[1]. That framework (a fairly popular/vetted one) used some DOM manipulations somewhere deep for some thing or other and Next broke with some bizarre error. Had to find this snippet in someone's reported (Gatsby) issue and stick it in my next.config.js file:
/**
* We have to force the bundling of @elastic/eui and react-ace
* as Gatsby, then all loaders below will match and avoid HTMLElement issues
*/
config.externals = config.externals.map(fn => {
return (context, request, callback) => {
if (request.indexOf('@elastic/eui') > -1 || request.indexOf('react-ace') > -1) {
return callback();
}
return fn(context, request, callback);
};
});
config.module.rules.push(
{
test: /react-ace/,
use: 'null-loader',
},
);
And this was just my first SSR issue. Definitely not "out of the box."
> Isomorphic rendering is a huge simplicity booster for developers, who for too long have been forced to maintain split templates and logic for both client- and server-side rendering contexts. It also enables a dramatic reduction in server resource consumption, by offloading re-renders onto the web browser. The first page of a user’s browsing session can be rendered server-side, providing a first-render performance boost along with basic SEO. All subsequent page views may then fetch their data from JSON endpoints, rendering exclusively within the browser
Aren't you back to the scaling problem when you generate the HTML on your server? As in, you now have frontend code to run on your server, which is more or less the same as SSR.
Addendum: That is, if your loads are large enough of course. Small projects will not have scaling problems either way.
One of the bigger problems these days is that people don't bother assessing whether their use case is actually complicated enough to actually need any of this stuff, they just want to use it for the sake of using it.
People are allergic to actually profiling anything. I think, some days, that it is intentional, because if they had real data, the stories they tell themselves to justify what they are doing would fall apart.
The issue here is nodejs, react ssr is costly, taking all you cpu time, blocking the event loop and slowing down your app. On a multi-threaded (async or sync) web server this wouldn't be a issue most of the time.
Some add additional nodejs servers specifically and only for SSR, increasing complexity.
That's exactly the point he's making. If you use a frontend js framework and you have to do SSR, then there's no longer any reason to use a JS frontend framework, because the reason they were made was to offload to clients the rendering, at the price of more complexity.
Back then, the cloud was not a thing yet, there was no Docker, no Kubernetes, no nice APIs to start instances, so it made sense to offload some computation to clients. Today, no longer.
JS does add some capabilities around avoiding full page refresh/refetches. See e.g. Turbolinks or PJAX for libraries that help with that.
Frontend frameworks do a hell of a lot more than that, though. Much of the time, they're doing things that are either the result of shortcomings in browser standards and implementations or things that are just stupid.
The reason React was made is because it's an easier way to reason about apps at scale, with many components and people working on them. As a result, there will be less errors and your team can move faster. It has nothing to do with offloading rendering to the client.
Amazon could be a server rendered web site and it is. AWS's and Google Cloud's consoles are borderline. Google Docs must be a client side app.
I worked on 3 projects this year, using Rails, Django and Phoenix. Only one of them has a front end that requires a client side app. The other two are within the bounds of server side rendering. That saves time and money to the customer.
Exactly. It is pretty amazing how developers went from server side rendering to SPAs just to get back to server side rendering few years later. The projects I have been working on never went down the SPA path so there is no need to do SSR in JS and doing it in other languages like Rust, Java or C++ gives you significantly higher base line performance (that you can optimise further).
Are you advocating for avoiding dynamically generated pages altogether? I agree that would be simpler but try winning that argument with the bizdev folks :)
I think he/she advocates for websites to be generated on the server (if they're dynamic) and not passing on that burden to the browser. Specially if the browser language was created to add drop-down menus and cool snow effects, not to generate a complete html website.
That's why I'm confused, that's exactly what this article is about. You're using React SSR to do the same thing you would do using RoR or JSP... unless the gripe is specifically with JavaScript as a programming language.
How many such web pages to you hit daily? I think the only one I seen in the last month was some solar system thing, and some work related stuff that are actually apps.
Most news sites are not apps and recently I am starting to turn off JavaScript on this websites and I am considering instead of blacklisting pages I maybe whitelist stuff if things get even worse, we ended up like in Flash days where you had an extension or a setting to Allow flash on this page.
Indeed. The whole point of the web, as the name implies, was to have a simple portable HTML frontend, with a wide choice of backends that could be easily bolted on top of existing data and code bases. There never was a lack of native frontend frameworks for sophisticated interactive apps.