SSR allows developers to pre-populate a web page with custom user data directly on the server. It is generally faster to make all the requests within a server than making extra browser-to-server round-trips for them. This is what developers used to do before client-side rendering.
For example, you build a web page with PHP, the server compiles everything, includes the data, and delivers a fully populated HTML page to the client. Every time you navigated to another route, the server had to do the work all over again — Get the PHP file, compile it, and deliver the HTML, with all the CSS and JS delaying the page load to a few hundred ms or even whole seconds.
SSR strategy can be stateful or stateless. Stateless server is more easily scalable because there is no per-client page data kept in the server. Stateful server is hard to implement, the server simulates a web browser, receiving events and performing delta changes in server state which are automatically propagated to client.
Getting server rendering right can involve finding or building a solution for component caching, managing memory consumption, applying memoization techniques, and many other concerns.
High performance on a wide spectrum of devices. The client browser receives the finished website with all the data that belongs to it — all logic happens on the server, hence the client’s machine really only needs to render the HTML code, a task that typically isn’t too performance-intensive — will eventually improve performance on mobile and low-powered devices.
It is compute intensive. Every page a user visits needs to be generated on the server, so if you expect high traffic, be prepared for corresponding server load and wisely employ caching strategies.
Less interactivity. You’d have to reload the page completely at each user interaction, which impacts the overall experience.
Handling multi-tenant context is hard. Client context is inherently single tenant, while the server context is multi-tenant. Techniques that work easily on the client side like singletons or other global state will result in bugs, data leaks, and general chaos under concurrent request load on the server.
Steep learning curve. Developers building dynamic pages need both frontend (HTML + CSS + JS) and backend development knowledge. At least to a certain degree. Decoupling and splitting work is certainly possible but there is a slightly higher dependency.
Less flexibility in deployment. A server-rendered app requires an environment where a web server can run.
SSR is not a silver bullet, implementing SSR properly is hard and time consuming, before using SSR for your app, the first question you should ask is whether you actually need it. It mostly depends on how important time-to-content and consistent SEO are for your app.
If you are building an internal dashboard where an extra few hundred milliseconds on initial load doesn’t matter that much, SSR would be an overkill. However, in cases where time-to-content is absolutely critical, SSR can help you achieve the best possible initial load performance.