DEV Community

Ivan Kaminskyi
Ivan Kaminskyi

Posted on • Originally published at jsjungle.dev

Client Side Rendering vs Server side rendering vs Server Components

When crafting a web application, you have a few tricks up your sleeve for rendering content on the page. The go-to methods are Client-Side Rendering, Server-Side Rendering, and Server Components. Each comes with its own perks and pitfalls, and the right choice depends on what your web application needs. In this blog post, we'll dive into the differences between these rendering techniques, breaking down when to use each. Plus, we'll throw in some examples to show you exactly how they work. Ready to jump in? Let's get started!

Client Side Rendering (CSR)

Client-Side Rendering (CSR) is like handing the keys to your web page over to the browser and letting it do all the heavy lifting. In this setup, the server dishes out a basic HTML file, and then the browser swoops in to run the JavaScript, bringing the page to life with full content. This method often means a lightning-fast initial load time and a smooth, interactive user experience. But there's a catch—it can lag behind Server-Side Rendering in speed and presents a few more headaches during implementation. Plus, it's not the best fit for content-packed sites or those aiming for top-notch search engine optimization (SEO).

Client Side Rendering Flow

  1. Initial request: The browser requests the HTML file from the server.
  2. HTML response: The server sends the HTML file to the browser.
  3. JavaScript download: The browser downloads the JavaScript files referenced in the HTML file.
  4. JavaScript execution: The browser executes the JavaScript files and generates the page's total content.
  5. User interaction: The user interacts with the page.
  6. Data requests: The browser sends requests to the server for data.
  7. Data response: The server sends the data to the browser.
  8. Page update: The browser updates the page with the new data.

Example of Client Side Rendering

In the example below, we're diving into React to build a simple web app that grabs data from an API and displays it on the page. This is a classic case of Client-Side Rendering, where the browser brings the web page to life.

import React, { useEffect, useState } from 'react';

const App = () => {
    const [data, setData] = useState(null);

    useEffect(() => {
        fetch('https://api.example.com/data')
            .then((response) => response.json())
            .then((data) => setData(data));
    }, []);

    return (
        <div>
            {data ? (
                <ul>
                    {data.map((item) => (
                        <li key={item.id}>{item.name}</li>
                    ))}
                </ul>
            ) : (
                <p>Loading...</p>
            )}
        </div>
    );
};

export default App;
Enter fullscreen mode Exit fullscreen mode

When to Use CSR

Client-Side Rendering shines when you need a snappy initial page load and a dynamic, engaging user experience. It's perfect for apps where SEO isn't a top priority or performance isn't under intense scrutiny. However, CSR might not be your best bet if your site is packed with content or needs to rank high on search engines. In those scenarios, you'll want to consider other rendering methods like Server-Side Rendering or Server Components.

Server-Side Rendering (SSR)

Server-Side Rendering flips the script by making the server the star of the show. Here, the server renders the entire web page content and sends it to the client as a ready-to-go HTML document. The browser then takes this HTML and displays it straight away.

SSR is a crowd favorite for its ability to boost SEO and overall performance. But it's not all sunshine and rainbows—it can be slower than Client-Side Rendering and a bit trickier to set up. SSR isn't as flexible since the server has to churn out the entire page content before anything hits the browser.

Server Side Rendering Flow

  1. Initial request: The browser requests the HTML file from the server.
  2. HTML response: The server renders the HTML file with the data.
  3. HTML download: The server sends the HTML file to the browser.
  4. Page rendering: The browser renders the HTML file and sends requests for the JavaScript and CSS files.
  5. JavaScript and CSS download: The server sends the JavaScript and CSS files to the browser.
  6. Page update: The browser executes the JavaScript and renders the page.
  7. User interaction: The user interacts with the page.
  8. Data requests: The browser sends requests to the server for data.
  9. Data response: The server sends the data to the browser.
  10. Page update: The browser updates the page with the new data.

Example of Server Side Rendering

In the example below, we're rolling with Next.js to build a straightforward web app that fetches data from an API and serves it on the page. This is a prime example of Server-Side Rendering, where the server steps into the spotlight, handling the heavy lifting of rendering the web page before sending it to your browser.

import React from 'react';

const App = ({ data }) => (
    <div>
        <ul>
            {data.map((item) => (
                <li key={item.id}>{item.name}</li>
            ))}
        </ul>
    </div>
);

export async function getServerSideProps() {
    const response = await fetch('https://api.example.com/data');
    const data = await response.json();

    return {
        props: {
            data,
        },
    };
}

export default App;
Enter fullscreen mode Exit fullscreen mode

When to Use SSR

Server-Side Rendering is your go-to for content-heavy sites or those that must ace search engine optimization (SEO). It's also a solid choice for applications where performance is a top priority. But if you're after a lightning-fast SSR might not be the best fit for an initial load or a super interactive user experience.

Consider Client-Side Rendering or the newer Server Components for a better balance.

Server Components

Server Components are the new kid on the block, blending the best of Client-Side and Server-Side Rendering. With this approach, the server generates the full-page content and sends it to the client as an HTML document. The browser then takes over, but here's the twist—the server can also push updates to the client as needed. This means you get the benefits of a fast initial load, top-notch SEO, and strong performance, all while keeping the user experience rich and engaging.

Server Components simplify your web app by shifting the rendering logic to the server, making development, testing, and maintenance a breeze. They also make scaling easier since the server handles the heavy lifting, not the client. Plus, they offer better security by controlling the rendering process on the server, reducing the risk of malicious code sneaking into the browser. And the cherry on top? Server Components can be more cost-effective than traditional SSR, as they offload the rendering work to the server, freeing up client resources.

Server Components Flow

  1. Initial request: The browser requests the HTML file from the server.
  2. HTML response: The server renders the HTML file with the data.
  3. HTML download: The server sends the HTML file to the browser.
  4. Page rendering: The browser renders the HTML file and sends requests for the JavaScript and CSS files.
  5. JavaScript and CSS download: The server sends the JavaScript and CSS files to the browser.
  6. Page update: The browser executes the JavaScript and renders the page.
  7. User interaction: The user interacts with the page.
  8. Data requests: The browser sends requests to the server for data.
  9. Data response: The server sends the data to the browser.
  10. Page update: The browser updates the page with the new data.

Example of Server Components

In the example below, we're diving into React to whip up a simple web app that fetches data from an API and displays it on the page. This showcases Server Components in action, where the server steps up to handle the heavy lifting of rendering the page, keeping things smooth and efficient on the user's end.

import React, { Suspense } from 'react';

const List = async () => {
    const data = await fetch('https://api.example.com/data').then((response) =>
        response.json(),
    );

    return (
        <ul>
            {data.map((item) => (
                <li key={item.id}>{item.name}</li>
            ))}
        </ul>
    );
};
const App = () => {
    return (
        <Suspense fallback={<p>Loading...</p>}>
            <List />
        </Suspense>
    );
};

export default App;
Enter fullscreen mode Exit fullscreen mode

Comparison

Here's a comparison table for Client-Side Rendering (CSR), Server-Side Rendering (SSR), and Server Components (SC):

Feature/Aspect Client-Side Rendering (CSR) Server-Side Rendering (SSR) Server Components (SC)
Rendering Location In the browser (client-side) On the server before sending HTML to the client Partially on the server, with specific components rendered on demand
Initial Load Time Slower (JavaScript needs to load and execute) Faster (pre-rendered HTML) Faster (critical content pre-rendered, dynamic parts loaded as needed)
Interactivity High (after initial load) High (after hydration) High (interactive content is progressively enhanced)
SEO Poor (content rendered after page load) Good (content available on page load) Very Good (critical content pre-rendered, dynamic content follows)
Complexity Easier to implement More complex (requires server-side setup) Moderate to High (depends on integration with existing setups)
Content Delivery JavaScript files and assets sent to the client Full HTML sent to the client, followed by hydration HTML with server-rendered components sent incrementally
Caching Harder to cache (dynamic content) Easier to cache (static HTML) Fine-grained caching possible at the component level
Data Fetching Typically client-side after the initial page load Server-side before sending HTML Server-side with specific components, with potential for streaming updates
Reactivity High (reactivity handled entirely on the client) Moderate (reactivity depends on client-side hydration) Balanced (reactivity preserved with less client overhead)
Bundle Size Larger (entire app sent to client) Smaller (only necessary assets after initial HTML) Smallest (only essential code sent, on-demand loading)
Use Case Best for highly interactive SPAs, where SEO is less critical Best for content-heavy sites where SEO is important Ideal for complex, dynamic applications with mixed content and high performance requirements

This table should help you compare and contrast the different rendering approaches effectively. If you need further details or adjustments, feel free to ask!

Conclusion

When it comes to rendering your web application, you've got a few options to choose from. Client-Side Rendering, Server-Side Rendering, and Server Components have strengths and weaknesses, making them suitable for different scenarios. Client-Side Rendering is your best bet if you're after a snappy initial load and a dynamic user experience. Server-Side Rendering is the way to go for content-heavy sites or those aiming for top-notch SEO. And if you want the best of both worlds—fast initial load, top-notch SEO, and rich interactivity—Server Components are the way to go. So, which rendering technique will you choose for your next web app? Let us know in the comments below!

Top comments (0)