The Dynamic Web
Tags: webdev, beginners, ssr, tutorial
Published: 2021-07-30 04:46:33

In my previous post, I introduced to you the [basics of how websites work](https://dev.to/sapinder_dev/web-development-the-static-fundamentals-6do). But that was just the *static* form of websites. In this post, we'll learn what that "static" actually means as well as other important concepts that are used in modern web development. And you'll also get the answer to that question I left you with in the previous post. 😎

We learned previously that a website is a collection of web pages, which are just plain HTML files. When we visit a website, we receive an HTML file that is rendered inside the browser. These are *static pages;* meaning that the same pages are served to a client each time. Those pages are present on the server in their entire form. They never change no matter what request is received from a client. But this is not desirable at all times.

## Server-side Rendering
Suppose that I have a page where I ask you to enter your name in a form. After you submit the form, I want to render your name on the page with a message, for example- "Hello \<your-name\>". If you remember from the previous post, we (mostly) make a `POST` request to the server when any form is submitted. The server is supposed to do something with the submitted data (your name), and send a new page to you with updated information.

We can't do that with static pages, because the new page is supposed to be different each time we submit a different name. We have no fully pre-coded page on the server, because the data to be rendered is not static. This is why we need to **render/generate our page on the server each time a request is received along with necessary data**, and then send it to the client. This is called **server-side rendering** where the pages are *dynamic*. Here is a [live example of a dynamic page](https://apipaginator.herokuapp.com) if you want to check out, where you have to submit an API endpoint to receive some response, (or just enter anything to receive an error response).

The concept is pretty simple- wherever some data is not pre-defined, we use *template* values as placeholders; wait until a request is received along with the data; and then inject it into the page before sending to the client. There are [template engines](https://www.pabbly.com/tutorials/template-engine-in-expressjs/) like [EJS](https://ejs.co) and [Pug](https://pugjs.org/) that ease our job to generate HTML via template pages.

### Drawbacks Of SSR
There are two major limitations of SSR as listed below-
- **Slow Navigation** - You know that when we navigate through different routes (<b>/home</b> to <b>/about-me</b>), 
the browser makes a new `GET` request to server asking for associated page. This makes navigation really slow because a whole 
new request is initiated for each page transition. This happens for both static and server-side rendered pages.
- **High Server-Load** - Because the required page is rendered on server for each request, the load on server increases with significant traffic; 
resulting in high [latency rate](https://en.wikipedia.org/wiki/Latency_(engineering)).

But wait a minute... if we can generate pages on server-side, why not try doing that on client-side instead? 🤔 Yes, meet CSR!

## Client-side Rendering
If you notice, this site doesn't refresh when you navigate from one route to another, and the pages load instantly; meaning that it doesn't ask the server for any other page once the website loads *initially*. This is called **client-side rendering**.

In this technique, the client receives a single HTML file only, with a bunch of JavaScript code. Based on what page/route was requested, the content for that page is injected into HTML via JavaScript. Hence, if you navigate to a different route later, only the *necessary* page content is re-rendered. No request is made to the server, and **all of the routing stuff is handled on client-side** that makes navigation super fast! 🚀

Websites using this approach are categorized as [Single Page Applications](https://en.wikipedia.org/wiki/Single-page_application). 
But we need not be too happy with this approach because it has its own downsides.

### Drawbacks Of CSR
- **Poor Search Ranks** - Because the client receives just an empty page initially, there's nothing to read on the page.
And hence, search engines aren't aware of our content. Even though Google claims that they do crawl pages generated using JavaScript,
the search ranking can be really poor for these websites.
- **Slow Initial Load** - Because there's a lot of JavaScript code coming along with HTML, the initial load time increases significantly. Furthermore, the time for the page to be interactive also increases as it is being generated by the browser.
- **JavaScript Mandatory** - Many of the users keep JavaScript disabled in browser settings for security reasons. But this also
blocks JavaScript from generating page content, and therefore, their browser renders nothing but blank page. 🥴

Now, you guessed it; we have another approach to take over! 🥳

## Pre-Rendering
This approach is simply a blend of both static and client-side rendered sites. Before we go further, let's first recall a few points-

1. In the simplest approach, that is Static Sites, we have manually coded HTML pages on server. One of the page is served when a request is received for that page.
2. In server-side rendering, we have template pages. When a client requests a certain page, we first render it on server by injecting 
the received data into page content; and then send it to the client.
3. In client-side rendering though, we serve just a single template page. All of the routing & page rendering stuff is handled on client-side.

Now coming to Pre-rendering or *Static Site Generation*, the development process is similar to CSR. The only difference is that **we pre-render/pre-generate all of the static pages on server**. This is done during [build/compile time](https://en.wikipedia.org/wiki/Compile_time). So we have the entire site pre-rendered on the server. 

Unless it reaches client-side, it behaves just like a static site where a certain page is served on request. Now in order to understand what happens on client-side, you should first know about the term **hydration**.

> [Hydration](https://en.wikipedia.org/wiki/Hydration_(web_development)) or rehydration is a technique in which client-side JavaScript converts a static HTML web page into a dynamic web page by attaching event handlers to the HTML elements.
<cite>Wikipedia</cite>

Once that static page is rendered inside browser, the only job left is to transform it again into a dynamic SPA page so that all further navigation events are handled on client-side. So we *hydrate* the page by attaching event handlers. This is really powerful as it takes benefits from both Static Sites and CSR approaches in order to remove/minimize their drawbacks.

But there are two huge limitations of Pre-rendering-
- **Unsuitable For Highly Large Websites** - The reason for this limitation is that because all of the pages are pre-built on server-side, the build time goes on increasing with the number of pages added. A few hundred pages are fine for this approach based on server resources.
- **Unefficient For Too Frequently Changing Content** - In addition to large build time, every change in these sites, even if it's a minor one, requires to re-build/re-compile the entire site! This consumes more time and resources. Thus this approach is not suitable for websites where the content changes too frequently.

So, this was all about the approaches adopted for dynamic websites. The use of each of these methods depends on the scale and requirement of a website, and therefore, a thorough comparison should be made before choosing any of these approaches. 

Now let me shed some light 🧙 on a few other important concepts used in modern websites. 

## Frameworks
We all know that humans are compelled by their nature to combine simple things to make crazy stuff; then take that crazy stuff to make even crazier stuff, and so on. This is how we got things around us that we see today. The same is with *libraries*. 

There's a large number of brains in every programming community that work together to create re-usable and life-saving libraries for the benefit of their community. In Node.js world, these are interchangably referred to as *packages* because they are hosted by package managers like [NPM](https://npmjs.com/) and [Yarn](https://yarnpkg.com/).

Frameworks use multiple libraries to take the game to the next level. **A framework is an extra layer of abstraction that makes building applications easier in a certain way**. For example, [my blog](https://blog.sapinder.dev) is built with [Gatsby.js](https://gatsby.dev/) framework instead of plain JavaScript, which follows SSG approach. Then there's Next.js, Angular, Vue, Svelte, and many other frameworks that follow one or another approach.

You don't need to rush toward these frameworks unless you get comfortable at building websites with plain JavaScript, because foundational understanding does matter before stepping up a layer of abstraction. Frameworks have their own place in today's world, but they are *not mandatory*. With this, let's head toward the last section of this post!

## Progressive Web Apps
I have nothing much to say on this topic except, "They are an attempt to make websites act like a native app on your phone". Try visiting [twitter.com](https://twitter.com) in your browser; close the tab; disconnect from internet; visit the site again; and boom 💥, the *web app* loads without an internet connection! Twitter.com is an example of a Progressive Web App.

[Progressive Web Apps](https://developers.google.com/web/updates/2015/12/getting-started-pwa) focus on things like- 
- Caching pages for offline availability.
- Caching other resources like images, etc., for faster loading from the server.
- Handling things like "Add To Home Screen" by providing necessary amount of information about the website.
- Utilizing APIs like Push Notifications, etc.

PWAs are getting much popular nowadays because they provide an app-like experience to websites; hence, justifying the title **"web applications"**.

## Wrapping Up
So that's all I wanted to include in this post. If you like my writing style, you can follow me to never miss any of my future posts. And you can also check me out on [Twitter](https://twitter.com/sapinder_dev), [Github](https://github.com/sapinder-pal) and [LinkedIn](https://www.linkedin.com/in/sapinder-singh/).
<b>Peace!</b> ✌️