In my previous post, I introduced to you the basics of how websites work. 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.
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 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 like EJS and Pug that ease our job to generate HTML via template pages.
There are two major limitations of SSR as listed below-
Slow Navigation - You know that when we navigate through different routes (/home to /about-me),
the browser makes a new
GETrequest 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.
But wait a minute... if we can generate pages on server-side, why not try doing that on client-side instead? 🤔 Yes, meet CSR!
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.
Websites using this approach are categorized as Single Page Applications.
But we need not be too happy with this approach because it has its own downsides.
Now, you guessed it; we have another approach to take over! 🥳
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-
- 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.
- 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.
- 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. 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.
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.
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 and Yarn.
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 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 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".
So that's all I wanted to include in this post. If you think my content is worthy enough, Don’t forget to check out my blog where I have a Newsletter that you can subscribe to!