paint-brush
How Does Server Side Rendering Workby@pradeepin2
New Story

How Does Server Side Rendering Work

by Pradeep Kumar SaraswathiAugust 1st, 2024
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

Server Side Rendering (SSR) is a technique used in web development where the server generates the initial HTML for a web page and sends it to the client's browser. Web Components are a set of web platform APIs that allow you to create reusable custom elements with encapsulated functionality. Puppeteer is a powerful Node.js library developed by Google that provides a high-level API to control Chrome or Chromium browsers.
featured image - How Does Server Side Rendering Work
Pradeep Kumar Saraswathi HackerNoon profile picture

What is Server Side Rendering

Server Side Rendering (SSR) is a technique used in web development where the server generates the initial HTML for a web page and sends it to the client's browser, which then renders the page. This is in contrast to Client Side Rendering (CSR), where the initial HTML is minimal and the bulk of the page rendering is done by JavaScript in the client's browser.

Web Components

Web Components are a set of web platform APIs that allow you to create reusable custom elements with encapsulated functionality. They are a collection of technologies that can be used together to create reusable, encapsulated, and interoperable HTML elements. These components can be used in web applications without the need for any additional frameworks or libraries.


This article will explore implementing Server Side Rendering with Web Component and Puppeteer.

What is Puppeteer?

Puppeteer is a powerful Node.js library developed by Google that provides a high-level API to control Chrome or Chromium browsers programmatically. It's primarily used for web scraping, automated testing, and generating screenshots and PDFs of web pages.

Implementing Server Side Rendering of Web Components

Step 1: Creating html page to define web component

  • Create a html page with body containing custom element
  • Define the custom element inside the script tag
  • While define custom element use the innerHTML than render method. This is a declarative way of implementing web component


Here is the sample code

<!DOCTYPE html>
    <html lang="en">
        <head>
            <meta charset="UTF-8">
            <meta http-equiv="X-UA-Compatible" content="IE=edge">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>Web Components | SSR (Server side rendering, doesn't need Javascript)</title>
        </head>
    
        <body>
            <custom-paragraph text="Custom Paragraph"></custom-paragraph> 
        </body>
        <script>
            class CustomParagraph extends HTMLElement {
                constructor() {
                    super();
                    const text = this.getAttribute('text');   
                    this.innerHTML = `
                    <template shadowrootmode="open">
                        <style> 
                            p{ 
                                font-size: 65px; 
                                font-weight: 400; 
                                font-style: italic;
                                background-image: linear-gradient(to left, #007f4c, #53e3a7); 
                                color: black    ; 
                            } 
                        </style> 
                        <p><slot></slot></p>
                    </template>
                    ${text}
                    `;
                }
            }
            customElements.define("custom-paragraph", CustomParagraph);
        </script>
        </html>


Step 2: Rendering Webcomponent in Server before serving the request using Pupetter:


  • Import the puppeteer library in the script.
  • Define the route to serve the html which contains web component.
  • Use puppeteer to render the web component during serving the html.
  • The browser will receive now the static html and renders just the html.


Here is the sample code

const express = require("express");
const fs = require('fs'); 
const puppeteer = require("puppeteer");
const app = express();
const port = 4000;
const content = fs.readFileSync("./ssr.html","utf-8").toString();
app.get("/ssr", async(req,res) => {

    const browser = await puppeteer.launch();
    const page = await browser.newPage();


    await page.setContent(content, {
        waitUntil: ["domcontentloaded"],
    });

    const fullHTML = await page.content();
    res.send(fullHTML);
});

Advantages:

  1. Improved Initial Load Time:
    • The browser receives ready-to-render HTML, reducing the time to first contentful paint.
    • Especially beneficial for users with slower internet connections.
  2. Better SEO:
    • Search engine crawlers can easily index the fully rendered content.
    • Improves visibility in search results, particularly for content-heavy sites.
  3. Enhanced Performance on Low-Power Devices:
    • Reduces the processing burden on the client device.
    • Beneficial for users with older or less powerful devices.
  4. Improved Accessibility:
    • Content is immediately available, benefiting users who rely on screen readers.
  5. Consistent Performance Across Devices:
    • Server capabilities determine rendering speed, not the client's hardware.
  6. Better Caching:
    • Fully rendered pages can be easily cached on the server or CDN.
  7. Social Media Sharing:
    • Easier to generate accurate previews for social media platforms.


Drawbacks:

  1. Increased Server Load:
    • Rendering pages on the server requires more server resources.
    • Can lead to higher hosting costs for high-traffic sites.
  2. Slower Time to Interactivity:
    • While initial content loads faster, interactive elements may take longer to become responsive.
  3. More Complex Development Process:
    • Requires server-side languages and frameworks.
    • Can complicate the development workflow, especially for teams more familiar with client-side technologies.
  4. Full Page Reloads:
    • Traditional SSR often requires full page reloads, which can feel less smooth than SPA navigation.
  5. Increased Bandwidth Usage:
    • Each page request typically downloads the entire page content, even for small changes.
  6. State Management Challenges:
    • Maintaining state between page loads can be more complex compared to client-side rendering.
  7. Slower Subsequent Page Loads:
    • While initial load is fast, navigating between pages can be slower than in SPAs.
  8. Less Flexibility for Real-Time Updates:
    • Implementing real-time features (like live chat) can be more challenging.
  9. Potential for Longer Time to First Byte (TTFB):
    • Server processing time can delay the initial response, especially for dynamic content.
  10. Environment Consistency:
    • Need to ensure consistency between server and client environments, which can be challenging for some JavaScript libraries.