Some years ago, when I started doing web development all the dynamic pages were rendered on the server-side, you know multi-page applications or MPAs i.e the client requested some content and the server responded with a ready to render the page. This approach is pretty simple and known as server-side rendering.
That was great until the more interactive content started being displayed on web pages. As the whole page was re-compiled by the server-side and the browser rendered the complete HTML page every time the client requested, so even updating a small portion of the page was a pain.
Table of Contents
Client-Side Rendering (CSR)
With client-side rendering, web applications made it possible to create a dynamic experience that we came to know as single-page applications (SPAs). It’s structured as a single HTML page with NO preloaded content.
All the HTML generation is done on the client-side. Whenever a link is clicked instead of sending a request to the server for HTML of that page, HTML is created on the client-side by mounting a new component.
Content is loaded via API calls housed within a single HTML page. URLs in the browser are changed via history API which doesn’t result in browser refresh.
<!DOCTYPE html> <html lang="en"> <head> <title>CSR Example</title> </head> <body> <div id="root"></div> </body> </html>
Can CSR be a Nightmare For Your Website?
This bundle once loaded, allows the web browsers to render a meaningful web page for the user. Page navigation will be fast and there will not be any additional loading time between different parts of the application. It works pretty well and provides a seamless user experience, but these client-side rendered applications always need to make an additional round-trip to the server to render.
This means your application loading will always be slower than the equivalent server-rendered application and it will become an issue if:
- the application grows in size and complexity
- the end-user is using a slow internet connection
- the end-user is running an underpowered device
In the above-mentioned situations, loading the initial bundle can take a significant amount of time and make your site slow. It’s not surprising that with the significantly increased load time and not having meaningful content on the first render, CSR can lead your application to some serious problems like
- Nearly impossible to maintain good SEO because of a lack of initial content on the HTML.
- Deterioration of user experience due to massive increase in initial load time.
The solution is something we used to do a lot but forgot in favor of client-side rendering and that is server-side rendering but with a modification of using it with client-side rendering.
Server-Side Rendering (A Hybrid Approach)
At the end of the day, we want a hybrid of new (client-side rendering) and old (Rendering on the server-side) approaches. We want a fully rendered HTML from the server for SEO and performance, and at the same time, we want the speed and flexibility of client-side applications (SPAs).
Now modern web development is kind of coming back to the approach of rendering on the server, at least for the first page and it’s not exactly like rendering on the server discussed above, that’s why it has a new name Server-side rendering.
Looking for a Web Development Team?
Share the details of your request and we will provide you with a full-cycle team under one roof.
What is Server-Side Rendering (SSR)?
Here is an example of the initial page in SSR:
<!DOCTYPE html> <html lang="en"> <head> <title>SSR Example</title> </head> <body> <div id="root"> <h3>World's happiest countries</h3> <ol> <li>United Kingdom</li> <li>Pakistan</li> <li>South Africa</li> <li>Australia</li> </ol> </div> </body> </html>
How it works:
The browser then displays the ready-to-render webpage. This entire process of fetching data from the database, creating a renderable HTML, and sending it to the client happens in a few milliseconds.
The process of rendering your client-side code and attaching event handlers to already existing HTML is known as Hydration. After hydration, it works like a usual client-side rendered app.
If I summarize the working of SSR, the process usually happens in a few steps:
- On the server, fetch data for the first page, prepare the HTML, and send it to the client.
- Then, the client renders the web page without having any dynamic features like event handlers.
In simple terms, SSR works by preparing the HTML with user-specific data in advance to reduce the load time as the user will see the fully rendered webpage at once.
So, you get the display from the server and interactivity or functionality from the same code running on the client-side, and from that point, as you navigate through the additional pages on the client side then those pages are client-side rendered as you do in the CSR.
Here is the flow chart of working of SSR with SPAs:
Benefits of using SSR:
Search and Sharing:
The single biggest benefit of SSR is to maximize your reach. It plays an important role in SEO (search engine optimization). In this modern world, every app needs to have users and the best way to get traffic on your website is through search engines and social sharing. Both rely on non-browser agents called “bots”.
Search bots crawl the web page and populate search indexes while link bots visit links and produce visual snippets to encourage sharing.
Many of these bots don’t run client-side code, so if meaningful content is not served then your webpage will be invisible to the search engines.
By using SSR, initial page rendering is done on the server and complete HTML of the first page with all of the meaningful content is served. So, most of the bots can easily run this code and this aspect of your app is optimized for SEO. It’s a huge benefit over just using CSR/SPAs.
Is SSR Needed For The Performance?
SSR helps to get something as quickly as possible on screen but does not guarantee that performance will be good.
So whether to paint quickly or get interactive quickly depends on the nature of the app. If the app has more static content then it’s not a major issue but if the app is user-driven then it should be a huge concern.
Besides fast interactivity, it’s the fact that SSR is viewed as a magic bullet in loading performance.
So, we don’t need SSR to achieve excellent performance. If that’s the only purpose then using patterns like PRPL, great performance can be achieved without SSR.
Challenges and Pitfalls:
SSR is super elegant and is a great choice for building apps but nothing is perfect, SSR also has some complexities and challenges. Of course, workarounds are there as well.
- SSR for smaller applications can improve performance. But, for complex and large applications it may degrade the performance due to increased time between first print and user interactivity.
- Any state generated on the server will not be passed to the client. The HTML generated on the server has user-specific data. And it will not be placed in this.state that the browser can see. That’s why, when it’s hydrated on the browser, the component renders with an empty state. And so there is a mismatch between the server HTML and browser HTML.
After all, SSR has definite benefits over CSR and it addresses the concerns in CSR by creating HTML on the server. Search engines can index your URLs. Visitors can share them on Facebook or Twitter. But, using SSR depends on some factors like the app’s complexity, user experience priorities, and the scale of the project.
There are some libraries/frameworks to help implement SSR with modern technologies like React and Vue etc. If you want to work with React then Next.js is a great framework with a great community around it. Another one is Razzle, a project by Jared Palmer. Also, for static-sites GatsBy has exceptional user and developer experience. Nuxt.js is a server-side rendering framework for Vue.js and is popular in the Vue.js community.