Web apps - my mental cheat-sheet
Tags: webdev, javascript, beginners, programming
Published: 2023-01-20 19:49:10

---
title: Web apps - my mental cheat-sheet
published: true
date: 2023-01-20 08:15:01 UTC
tags: webdev, javascript, beginners, programming
canonical_url: https://costica.dev/posts/web-apps-my-mental-cheat-sheet/
series: Continuous Delivery - from Html to Kubernetes
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lbax2bnvba4yzcxd37ki.png
---

## Intro

This article is part of the “Continuous Delivery: HTML to Kubernetes”.

While I can’t wait to get into the nitty gritty details of distributed systems, I found myself in an unpleasant position: I think its best if I start by writing about _frontend_.

That’s because **web apps** are _the_ standard nowadays. And it doesn’t matter how many 3000 microservices you have in your ArgoCD-Kubernetes clusters deployed in multiple clouds; those are all irrelevant if users can’t or won’t use your product.

## Why in a browser

To say delivering software in the browser has grown in popularity would not serve it justice. Heck, it is nowadays more or less the default for everything. [Adobe’s moving frigging Photoshop in the web](https://web.dev/ps-on-the-web).

Ok, that’s an extreme example. Nonetheless, web apps have grown in popularity even if we still have the joke about JS' world changing weekly. _Despite_ Javascript’s ecosystem state of the art, we could say.

So the default is now to deliver software over the internet, piggy-banking on the cross-platform-runs-everything-silver-bullet aka `browser`.

## With great power comes great complexity

But what does that mean, exactly?

- What’s the difference between a “simple site” like Wikipedia and a full-blown web app that can be “installed” on your phone and even send you notifications?
- Or apps that _you can interact with_ while you don’t have an active internet connection?
- How does it differ when it is server-side-rendered or client-side-rendered?
- Is it plain, static html? Or was it generated by a server and just returned?
- Does the browser flicker when you change the page inside the same website?
- Does it behave the same when you access the same URL from inside the web app versus when you hit enter in the browser’s URL bar?
- We can do PWA with SSR… just do it, right? Right?!

A lot of questions, a lot of options. Here’s my mental model - it could serve as a “WebApps - associated complexity & when-to-use cheatsheet”.

 ![image](https://costica.dev/posts/web-apps-my-mental-cheat-sheet/images/table3.svg)

The “overall complexity” that you saw in the [table](https://costica.dev/posts/types-of-web-apps-wip/images/table3table3.svg) is the sum of how complex I think it is to build, maintain, evolve, test and deliver such an app. Not only for the first 3 or 6 months - but in time:

- when requirements change
- when evergreen browsers get updates
- when libraries stop working with the evergreen browsers
- when you need to update said libraries
- when security patches
- when X
- when Y
- when…

The list can go on.

I think there’s no reason (except for CV inflation, maybe) to create a PWA with offline capabilities for an admin interface that needs real-time data anyway. And that’s just one example.

While there are different pros and cons for each of the types of apps, I think it is worth looking into how complex delivering an app is versus what it can do. Versus what it **should** do.

> Please note that my list builds upon itself: the simplest “web app” is a static HTML file, while the most complex is a full-fledged PWA.
> 
> > WASM is a beast on its own - not detailed here.

### Static HTML

![img.png](https://costica.dev/posts/web-apps-my-mental-cheat-sheet/images/staticHTML/tableSummary.png)

The first one on my list is the classic `static HTML`. It is how the web started: a simple `html` file that is served by a server when a user hits a `URL`.

 ![image](https://costica.dev/posts/web-apps-my-mental-cheat-sheet/images/staticHTML/StaticHTML-ReqHandling.drawio.svg)

The process is quite simple:

1. User enters `site.com` in his/hers URL bar inside a browser. The browser (after some `DNS` fun) will make a request to the server.
2. Server receives the request, handles it, and returns a response: the `html` file.
3. Browser receives the `html` file, maybe even requests others (`css`, `js`) that were referenced in the initial file. It reads the whole file(s) and displays the contents.
4. User sees the information in the browser. Simple, elegant, beautiful.

Behind the scenes, developers working to write & deliver the files to a server looks like this:

 ![image](https://costica.dev/posts/web-apps-my-mental-cheat-sheet/images/staticHTML/StaticHTML-Dev,build,deployment.drawio.svg)

The dev process is simple too: just write your `html`, `css`, `js` files, “link” them together and then deploy to your server. No fancy IDEs are needed, and no compiling is necessary.

✅ **Pros** : easy to develop, no tooling needed, loads fast, compatible with all browsers

> ⚠️ I’m considering `js` to be light or non-existent. For js-intensive sites, please see my definition of **SPA**.

❌ **Cons** : no code re-usability (for things like header, footer, etc), user agnostic (displays the same data for everyone).

> ❗ Not that cross-browser-compatible if you want the js & css to work the same everywhere :)

### Static site generators

![img.png](https://costica.dev/posts/web-apps-my-mental-cheat-sheet/images/staticSiteGenerators/tableSummary.png)

For things like code re-usability where the plain `static HTML` runs short, the static site generators come in and save the day.

❗The caveat: an extra build step is necessary for the developers before being able to deliver the site.

While request handling looks the same as for the `static HTML`:

![Image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nosxqnouzo1cvf023nvj.png)

The dev process requires an extra step:

 ![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lmr88u0crngcw5vprtf0.jpg)

While this is not the most complex scenario, it is still worth noting that now a simple refresh of the browser would not allow the developer to see the final result. Not without a local server with _hot-reload_ or by running the build manually.

✅ **Pros** : loads fast, and is scalable in terms of re-usability for static content workloads.

❌ **Cons** : user agnostic, requires an extra _build_ step (compared with the `static html`) before the site can be deployed.

### Server-generated HTML

![img.png](https://costica.dev/posts/web-apps-my-mental-cheat-sheet/images/serverGeneratedHTML/tableSummary.png)

What about sites that need authentication? And to display the logged-in user’s information?

Pure `static html` or `static site generators` are not going to cut it anymore.

We are now moving to the “real-world” web functionalities, where `server` is no longer just a dumb _content delivery_ mechanism.`Server` is now going to refer to a full-fledged machine, that is also capable of **processing** requests.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r8acf9qqvy3s7uzo9grl.jpg)
(Click [here](https://viewer.diagrams.net/?highlight=0000ff&nav=1&title=ServerGeneratedHTML.drawio#R7V1Zc6O4Fv4t98GPcbEYjB%2BzuVO3untS05m5PU9TMsiYDkZukLPMrx9JSBgtONiGxO7rTtUMCCG0fOfT0TlH8sC9Xr58ysFq8QVFMB04VvQycG8GjmM7jkX%2BR1NeyxTXGbllSpwnEc%2B1SfiW%2FAN5In8xXicRLKSMGKEUJys5MURZBkMspYE8R89ytjlK5a%2BuQAy1hG8hSPXU%2FyURXpSpgWdt0u9gEi%2FEl22LP5mB8DHO0Trj3xs47pT9Kx8vgSiL5y8WIELPtST3duBe5wjh8mr5cg1T2rmi28r3pg1Pq3rnMMNtXvieer%2B71%2FE%2F08cfE%2FD88Edy9%2FnPC17KE0jXUDTDT0l5V3NEinX8mF7bIpGUXk%2FnDcOvojMXeJmSK5s8Yz0DI34XrvMndmORmwKt8xDewzxZQgzzbysQJlnMH2KQxxA3PCzIU8wx5JN7mEW1uwUIF%2BscfgIrkjDibZiCZZJScF7m4SLBBEIFqfMNWJMhhTnPxAuxaSkZuo0IQnijaOVRjhcoRhkQbSM9nr9%2B53ViN3%2FRm6HnjUXCzUv98c1r%2Fa5qnGiVQAa9eYI5Tgg8L9MkzkjaMokiWhNWz2uUopx1tRtY9E%2FUn%2FUoebDAmMiN47mX5D8ECvQ%2FNEMxjBGKUwhWSTEM0ZI9CAuWdTovu4hcSp3kOVe1bioeIQ4X9eGcJhiXQ0OTfiRxzHrMqYBRxyYHWiEq2ghILi0lDLZkdMp8MJLEm0P%2FE0Skg3PSJoszlTW07NG4fIdTlT0qb3OYApw8yXwAOK3EVUlV4fcooSIgSrYnllQsaYLlDD25GA758s26kCqFOSOtMNeSi%2BICohZ1mefgtZZtRTMUzdV2PO1LtkQg5KIs0%2Fz%2BhdyZI7mSaD4vIFaKq43LJomx1A6MNdIYa%2Fzr0FD%2FYrwH20n0BF8S%2FL12LYiP325oj9681m5U0muis3fiGbclzQg%2BepNnDmSRkSr4E88dOvuRiOc0iXbvJBKMrK1Vc1z1BX8L6XTFGWONMwpIgJVrxEGgvqKX4XpGp9xnKkRU9Gnac04F%2BqrGLbOSWz7PqoRKJfxtjdMkEyIVgfzxN8ogmEnE0PLkRIelMlnDOXqEQi4iOAfrShvbWZNRRMyyxlQ7JelJmuqfiHMQJXDzRoZo%2FTfSbx%2BprqEqTBittjEDzQ5fBttEWYjRWBUjW6D3ebNSqAR3UVsluBNF3uoEIM2Iu0I5MCjsCogpAlfKMJPhn8%2BhH4YaxsQwd0K7WudW6zYwE9Wztna67dhD31Wo0Pe0bp8Yet3vq9Mn%2B3W66Noe%2BnsrNvYfhI%2FqYDE9bethNhfB%2FPYJ0inJoJpEoFhUyl2NpuX%2BJ5LghwGczXUJiQAM5lRCUjCD6T0qEpwgSikhzEpiElzzWckwQxgTomsiI8DvqnJQOT1cVzYNvgxkk8%2FyJaa2luEThGA5TMGqLORU1EqnAy1uqxS2JnBFpbJ1FvFM3N0byHVjC4EJGZgmLWS9TC9DjA4AXk0KjJA7KUwp6sx0ekVn6Pel0kasObpm4L4rgzoGBq1b8moA83%2BukXhwUbAeJoNn2f7qhfWQeM4mDtHfm0R3wv7Vk0pz4O%2Fw5xoW9Ft3IItSOgK8CrN8YzJsZ0kk3Y5lAGsk2mgpyyFpFJ%2FrKED4KoaU610NvBta1hqjgmvKTTO0YSavK9iTXaTFpIX3pHE1InTia4qVbQf2cORoyLVNOu2oN%2Bi6GnS%2FseXZRQwzmANMJnUCqYcvn1ugpO1QtkeTaRG4sSqdHIu%2BN%2Bx8dRFFRMCEOcfzdMyNe8OcbkZ0NXTBmmVsYxWr2csUHEhdq4FC6lhDx2%2B%2B8BnRybscDYjxKx8%2BSloy2IUxTlyXxjjnDWNcg%2FPCtr3BHs6LI8W6vc3G2Ajrt90T3JT0tnuCl9id3fAwvHsa3v3TxbtsfB63xLs9JHOvjHlvYp8x3xnm3eOC%2FD4A%2FzhID706qLci%2BhThp5haoB15cKzpa3Rx4Y9d4A9qvjrZ4z60bFmGJ5O95i3mw7ukASSDmqWOpE0TijP%2BYqTkICm155XFyeY39wCTL2QsxbEO9IS3Fju%2Fa7kz%2B27Glq0uH9TlbINbqSs%2Fjq07cnZe5FraIrdcgUYALlFGcqRJgWHGFq%2FWnKCS9htb11IBI7nBkpn0lqWXgTzE65xnJwvPFcoKWOy%2F7n3D5XQYPx0pcTj7EUQnixPNUxrohpwq5EsyE6ou1e4mLt3Ho1vDj15XO1Ks2X59Nrkg04krTycu6f7t00nTFGecZvbnf6cl%2FQtSbBsJRdtMFWH20r5TQv9xPvbk9DBfrceHljOW1ii2u9ea%2FC3N5liFrCnoR1KYDhANu6VsCOI8kiWJo7s5R6eLcnnJYrcE%2BAbTf0mQPimAC%2BO%2FMYBtt4VFmIKiSMKHRZJJ64t3khB3svvsYXsHRs72P3s4uq81QlQvt%2FAC0hqEeA1oKaschZAMANPf0bzKkAtf1lk%2F5wv7hliJ5uiKDvTzsR6kPB4N20UDEZSqUdjdEbnubSWNSuYJgxihzAVpcxIC5qWvNoCcUdQFJgI93t6wZjMhYjTpCw66BzMCGMxAAc%2Bj3%2FvoG%2BJ63nf0dV9iQeZx2uVwCZKUXFyXpiPFJrQErzTMeHrGSM8YmXgfDRHd%2FVZglLPZoiDfoGZHFBdnFPSJgiCYfDAKTssjJRkw2vpYZfvF%2BEQNGIb1Hd%2Fb2%2Bn6Tl7Id2UcOdEQBUd37iTZPMnIYNGeQEUyS1Jyc2bJflnS8VousPrjyWAPnjxlo5jCmidKmnaXJNZ2f6ZQvo%2BFxE7Ya3GGbjfQbeu4Exg%2FEui6%2BiL0DN3%2FM%2BiO2kLXOy7o2mfoboOuBI9jxvEB0PXaQrdtuMQ7QVf3JGhY3pxKkKevVzkIH2kL3zqdQD75ZJ4mqzt%2BrW5vzUudvnGTYbUVRmyaSeG8nl%2FbMnNecW3bh6VbsMe%2BYcll26aoM6uvqDNX92FghEFKu8hCKwoF6jA1W7IjuOIWb%2BbvUnysev5kuUrhkvRh6SFjgZTNMZM1iznrCceawbILiJiwooyvs%2Bf18Ewp6LPMLPLeJVXTyshO9viPAuZfATXP8lQ1lHNWq%2Bpm06QmwEe%2FmbG1fnO4ZL%2BD0HYgpEQmVR%2FC2GQXqSKg60La2%2BEfru5pOk8WxztZtNwLcX196zHLco4EH95MOpps%2FEA17410X3lgwHB%2F231dgy%2BMkjiNnojKxhVl2AQLxwEScYtzmzZse6baE6daXwBCQNQ3heCPjcpQXxD1NYh%2BjZPspdQRLgmLUgWHXj%2BgZQhweU2GS1FaWmxHsRu2oygazUEllcVEydNB5bCtMGXIAg1smMEoYvIqRLLr%2BpKRY1XuthXwZYUKVu%2FZq9BUzd%2FbNEyKEUxBFq%2FpmcK7eqGU031moEjCYZiidfQ3ISPyf%2FzLToa2Pum12N%2FTyNNMJbmqztpTyLY2i16wLe1ldpRHMFcP4SpP9XxgJhvqdurm3LhJMFQozSadM3QDjdYcezIMdGKzR0TX7M3ioPtZv6IIDn8Y4pQOELT7u%2FtOy%2FsveAKdFvgJdVocZf8mXfws80yyW8QMdyXzimRbMhebqLqZJTqghMAaDW2NE3Y4CMXuzwCp7zb0NCCfjjV9sM9JKPRkCGUbYFDtE%2FwFDoY4%2Bu0qYhdKd5sd38l6r58M%2BgDJWhawmCWYxQlnEGP072MZ%2F0lkg34HV9bKop5fZJ%2FRn7pgS1%2BD8dEiCFmR9s7Scu9KuQ29nLG0kpjYGIs5x1UZ97rM53PHcHIundH8me91tBd97Fmq2hgYVsLBZGiaH3rbjS7sQDWI36%2FjTlUndlogvAJ5txroLddoVcF7eE5i5UHHet95KbiLWthCvA5XC5lYc7O2uP5TjEddWWQ6Qxcqn3qg%2F3hsMGuZ3AfaqSr7yHLgfF7ny5%2BLT1%2B8ZTT%2F7ebv8OLR%2BGs%2FCnTLc6xbN3%2Fn871d9cSNwNQtJou03Z%2Fr09AtNWuTbIDiB80YD0adTgPLsnSOKIhclKLTcAjMmxavw%2Buww5E05to0rG3Xy3SaUx%2Fpmz6mUzkmk53VoEX%2F88OGBUopjkmTBD5dy8BS5RnMBx64uVWQ32ajj5Mq3YbeBr43t%2FTPCN%2BaY56rsJJTXvHdz1D0avbb1yVAeWnV6OmXJcQS8QLsAO%2F%2F1HSWw9tGPtZQjS0Vp3q8ocF6LlPP%2FSInMgux3f1EZvqviaCO7edOOmeI6qd8pHnZNcQ69HWgubEBzjHoKqrJzng62PvSqqlfzsrKWVmpEZrrTiYsoOQ4lBWnQR6PSVnRY1Jk%2BJa4%2BorwovarBm%2FNmOS7yar4xcF2y%2F4G%2Bqreo3%2FaVE7f8OnfQPn1nqafH%2FtQQAqPrjwPjPS50RSeMtr99Blyu%2FlB4PIspM3PLru3%2FwI%3D) for higher-quality visuals)


From a user perspective, it is exactly the same process as for static websites. However, a more complete description of what’s actually happening is this:

1. User enters `site.com` in his/hers URL bar inside a browser. The browser (after some `DNS` fun) will make a request to the server.
2. The `server`, listening for connections, receives a new request.
3. [Optional] Depending on the application’s logic, it might call other services: database, emails, authentication, etc.
4. The server passes the required information to the `templating engine`, which transforms the `templates` (defined by the devs) + `variables` (“passed in” by the `server`) => into an `html` file.
5. Browser receives the `html` file, maybe even requests others (`css`, `js`) that were referenced in the initial file. It reads the whole file(s) and displays the contents.
6. User sees the information in the browser, not knowing anything of what happened under the hood.

A lot more powerful than the static websites - but also more costly. It requires way more resources than a simple content-delivery-only server. It is also more expensive in terms of _dev costs_: while `static html` and even `static site generators`’s only requirement is to understand `html`, the “knowledge bar” is now higher.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x27e46yu2ubtmq9yytfq.png)
(Click [here](https://viewer.diagrams.net/?tags=%7B%7D&highlight=0000ff&nav=1&title=ServerGeneratedHTML.drawio#R7V1Ze6M4Fv01eQwf%2B%2FKYpVw106np6i81M1VP9ckg23QwogFn6V%2FfEiAQSCxOjINj%2FJAYgVmkc%2B6590pCF9rN9vlzDKLNV%2BTB4EKVvecL7fZCVVXH0PE%2FUvKSl2iqYeUl69j38jKlKrj3%2F4ZFoVyU7nwPJrUDU4SC1I%2FqhS4KQ%2BimtTIQx%2BipftgKBfWrRmANuYJ7FwR86f99L93kpbYhV%2BVfoL%2Fe0CsrcrFnCdyHdYx2YXG9C1VbZJ989xbQcxXHJxvgoSemSPt0od3ECKX5t%2B3zDQxI5dJqy3%2B3aNlb3ncMw3TID27M%2B8f%2Fbu93yhX8I4lvU%2FQ1%2FHVZnOURBLuiPhIYP8K4uOX0hVYTvvuIfHV3S%2Fzv%2Bmnjp%2FA%2BAi4pe8LQwGWbdBvgLQV%2FXZJqgd7dsiwoK%2Bv3XRr4ISzKPRA%2F%2FI5P46cEP7IkG%2FVCNSslRyZpjB7gDQpQjMs8uAK7AD%2F39QqF6QJs%2FYCc4Cp2yY25aYLv%2FhbscLPhZ8kPKqCn2MU2PRVuN1m2SLvhcj8I%2BEusY%2BD5sPpFiMj9X5cNqtAroF2cVcgmTTF6VUO7wn9wg5A%2F5IBEWiO0DiCI%2FERy0Tbb4SbZoYtV%2FhD4a%2B0xDPWaeZDkAabuprimu8NNtfDT1A%2FXRdGf%2FnqdNRmuuGseIbS5YZzCZ6aoQMxniLYwjfFNyHSvphXwLfh9qRhkk5Q8VXRR6FEblipWUQgKiq7L01cwxV8KpO6BWpVD7X2G2ss1DGEMUujhvV%2B%2Bf73jYIwfO61DtY6romlZHBRFIPDXISEArsysKUgl%2BtiOXBU7tr7nBW3ciHNCEDSTywN3s4vhZ7LrVt8LxONDjOGKKr8L5JqIs2kJgzjVMHjEjQY4jQPcLXy8UPHJ5OudjxUn%2B3oLowC9bMmj9%2BNuOJ5imPh%2Fg2V2KtIgEfJxO5PzGtcXxi051y5FSWHe9oA0axWdfVDImE4n%2B%2BwLkwAsYXBdakLjvvK9KPZg3NhzEHjZkqI1EGY5AoSpApumHwBhf4Af35Pof%2BElePrt3893ycu%2FfpmXOq%2FEHIhIZUXDq6D0mQrs1PwOUdVYTeKZgmoxFEG1GNoB6uWbHzp%2F%2FefpN0f5tYVfbr97v758ETgoXLVUtlXp90xqMOXscA2kAhBP2U6zBMfE9AC0Vy5nDfAe07XhciVkUzc0%2Bzl2FJwIb9JSOFxADzv6xSaK0w1aoxAEn6rSvIW9gyCjusAdQhG1eTBNX4o2Ija6DkX47Kc%2FCptOvv9kvt%2BSejbKrRdm1zcY%2B7jOCAaysolikvOzK386SUGcXpHYjXGmSdnCJ42eP2no0SPcACSJ7%2BaFxSHK%2FvBN6OO3HagVpgXfyRp2nbFQD4KvTjbEMACp%2F1gPNEXIz36KHxe8MAcUMl%2Bd%2BRspqKy12vCTlEb41zhc17sOx1%2Fy61cMLB%2Fk9aSkNcpY7wBhF4fkC%2BAjDFCUO0vyhw86zTMOOt8qKnSvXQewqkq4qPqYOh%2BWilw4RTFG0iCNDxOG%2BnD71dHenp3S4L5jSjIO7csPH9Grms1XHfYdJMWsPpY%2BUrylD63I1lCC4aqQXnWnsT3iAEmUZx1X%2FjM5%2FBrXfAqwLaHyO7AtS2y8vi1p4zWaQDWGNt4BcC9sLYNrLR%2FX7bOURgHXbJMPhPdyqQS%2BzZvjiyMY9LdittXOqE4NnKZt1uyOZUuOzZgdHrmmwGAfImYQ4tbstzJlc5Z4g%2FGnR5jDTmH1WM58iGRTJfnacowkODOXpmHyQdtqtVJdlxqkbxjLqY%2BE5LhrHLBEaYqhwLMnJdHINcodoJuyE0UWMY%2F6W9vnNentkdBq5bsQYyx0YYRx5yF3Rzy2X8sAhA9DjG83A8jT0wgtQYHvnVTUrRzC%2FLdSSbMko0YeXZUcg%2FF3dJ49miZptY8pYBOW%2FtoxI5HL4si1gQDr66wKZ6cKtiMZrNm39hQF65iiYM%2BiMIvCVEVBkVVJbqfSiUmEw1FthVA6S8QZSoRidAJ7YhpB0ymzSMwiMUGRMPUuf%2BvERELhe4DJmLxLbIBnnTg7nVBliUW2pug1bJPBHTKbgeKxbR9VKPgOsFkoZqGYiFBwKSZFVvr8rElJA9%2FflklD%2BoRmaTg7abANSWdNvzNtZRjQxTkrw6wMk8wznZpO8B3UWS%2B%2Bm84ycXYy0ZNpGqATx001zZ3Us05MVye6U02nphN8nzWIIunPZJaIs5II05asemCsyoZks%2BOaOBwbRxWF9%2BukttWlZgpEwTOg7emzKMyioFqq5HQE4qZTS%2BHqPJcmpQl8J3VGMtwIyawL56ULitqJ7H6ROGrkoL5fJ%2FUsErNI9E7DrqdrrUZH3mmpBKVWjWtmBpEl%2FrLOZpyAp4tqplu%2BE1%2Bs3H9BCNv4DUYQTPoOjmlhCrdRAFKIdxY%2FJAeBLWFI%2FjdjP8AEqg45NwVjDVovv%2FfQO5bsxVxfAdfzJ6YvGlI%2FgCjq4sG97Cw8UWx0iBcpiKk4vzHgNW8MKKdhv%2FFlAXsAaJ%2F5bGVPdX1G21hvE1B5r58D0fvM5CxnSNWmcvI1puuS4XSLY3mqw7%2FMZGjtncz0zRIQr2%2FAGp4bRlMXgXusacp8b5gH4BaFl%2FhJVv76%2FFyCDxTUtuK0I6iVZCZqNWy7Zl8sWbJZ%2B8xZGmekmFb4eO%2FXGeaYlgYEIS1UcFBrzSHtSXg9%2B4S0%2BzOJn7GpSBZr5acSwgqfl%2Fd4YvjXDibpJbbhEQoTOAvDeQlDiws5VBjKF%2BUeRRnecUqOpuiaofPSYOqWac%2FScELS0HhD0yr7jC0ZMm%2FcaWynWJhj1U51MklQMQX5zAu24RtcZxjCGbJnATknAXEkxWJCXLkBbkOTbN2pPu8bWbzjTJ0yxdb2Bs9ZP05EP8bzxSxLclSGLIJAg%2FHFph1pzBn6d83Q74E%2BuqaHZLPYUy2Vw9fxM%2FTtPa6e%2F1h1kx6uE1bQ4So%2BQ1kmuBGmiN6EnPhe1mW7C11iv7EhTl%2FaznJuDtTcW3tYITE6x2tfDuiLU%2FSRenPFT8hP8TyWWzZPf5jdst5pctgtUxhprKfITir%2Fq%2FKdtsV4ItLIZyc85x25y5IsM32C9WijN%2FM71jBX8dPx3dnHUog58ftRFOLoid9cOT5I4lflu%2BU9kIIlmPsMz004uqeD9qZ8x3r9t%2Fjx%2BOmes3LMyjF15chSwR9FOfiJrHAL%2FOAM5yWctW6Q6T4dY036hWOs6dfiMe4OB8%2F%2BtebqK8BOb7E5q9wilU4WSTqt5eaUC84YLxbXRvZYtQXniuXkvm%2F8kO5iFpXj150rDpzI2nPURznc4nNvG%2BkvnzAVJKONDDUuZBshrq0f7MZPdoNhULbJUIhszxw6MIc6Z371r984LQ7xPZnZ4tLNSKTwzXfb4MpN0RtiAYYKwrDgtFYn71ihcfhii9NY4VBrrHCoO5LZs8KhJvB7RpvWNaAv7oRHRXHxhJAczRD5EUKwlQIQ5SeZKFU61x%2BdBvh1uQ5%2Box%2F8omzReAu086GqB6MAvZyeAzRVkDZXjK6B9FVrRgv9Dur%2F0e8%2Fa76g2P%2FjYT%2FUK6E5UNYrEb9paKBTUvBFlhSzsL%2FjrjOtqA1mXipGceW2taYFP9HNjvWmqxPQm0KrVYJrq0na%2FdakFnuJAyYnz6MPudGHrPJ2azU1fW6MkuRyA7LKaSfQHi%2F4Nkm3dPVRmqi0DUnw7gDTkGyNFwrVHGs5XI3vV1hiPAV8Z1jpTCBvlwkD9UECuMrcUrIeebi%2By7byNunNeuZ%2ByCsHzgnd%2F9ek7MUj5yYI9E7R2Wtl9gMg3DE4SyvEtHBqnW5Jmqroqm1Y%2Bd%2BxHCHj9DweccqH7tkr5UNeDcpmfepJnw%2BR3XmjeyXKeA3ynzpnC%2FRmdYyDZ3XEzo1pcb5Ns38sv9fid29yYcQMNM%2BbgerMwJEY%2BLa86jsy0BrGwL1jH9rVWF5JUWpxDH9vXOSz%2Fy%2Fo0whjpUMZEdpYnaNfCv80yzb3hUEDPM4C1u2va%2FqQsZSI9kIXE5ff3HwysvIDeJOmzQHL4cegi5Jo9lhJNINPIS93fuC1Im8VwOfC5AmsXx2Bh1S4qUKpK1p5TV5L1MPfJrt9qvt6H4%2Faot4cGU3e9CpMz9AQWvZGIbIcjmFGgzr5s3NCxJ3K1rnQT26camSv0hgwkD5jCs2LzXzs5mMrH%2FodKXNSMLd5D%2BW1MLe4DAfXXXkg183inETN6XbE%2BMfUtO5fCJ7G7khzH4ypotfgcfOLb2GEGUooQno%2FrwbPSy5fGR0uk%2BhCMIc6f1ukeO4zfiC5%2B0pLbv5zAML1DmCkt52xbdp1eRQ7UU2G4doPW07WMGf8oNKhIz%2BHDz4Vuc0Nyzh7zkPNa5WEPYB%2FbCkce6kIs7lW0bKgSlObD%2BchD1jap094zwMLNde3dFkrL5UfoMe7rDV%2F5vX%2Bq3miwu7IjqSbjqPJtmMomt6gg2YakqXKpq7L%2BIrlm2H31XxFVjmiWeOIvs2FvJreI%2FrcL%2Bi9jSrhFDFDsi%2F%2BlohjjeHiTr%2FegU8t4sLOW8kudkXfmp31ODZfoV3cT0F7QnpM%2BYXrharkZ6%2BQxtoW53xfkHmA%2BB8px822ePCJQ7LAbtKzQuZ%2BLLYk8nyJyPtVFrvwIURPoRQRUyRSxVn3Rs0X8VQwFMFqDnTOTk0P1YZtONwbn%2FdIU85EmYlyDKI4%2FICoCRBlyILyM1FmohyTKBSDVeLIFkRYRybKkBeGzESZiXJMophchtXmJ7kemyhDVtuYiTIT5ZhEcaxyNO9xvC%2B8GSOUsuE%2FmfjzFXmQHPEP) for higher-quality visuals)

You now need a `local dev server` so you can have a feedback loop and test out your changes. Ideally, it is kept in sync and works just as the production one. This adds a ton of complexity.

The _build_ step might seem similar to the one from the static site generators, as you still need to copy a bunch of files in your deployment process; for some server-side languages, though, there’s also an additional compiling step.

Add configuration for the daemon listening for requests - congratz, you now have a complex setup to maintain.

✅ **Pros** : re-usability (due to the templating engine, similar to static site generators), **can return user personalized responses**.

❌ **Cons** : significantly more complex than static responses in terms of dev - deployment - maintenance, requires additional resources for processing requests each time.

### Single Page Apps


![img.png](https://costica.dev/posts/web-apps-my-mental-cheat-sheet/images/singlePageApplications/tableSummary.png)


For the `server-side generated html`, for each request, the server needs to do extra work to process it and return the entire `html` that will be rendered by the browser. That means extra work on the server **plus** a huge response (the entire `html` markup) being sent over the (possibly unreliable/slow) network. To top it off, the users see a blank page while the browser loads the new page.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vg0s2f1zkgj58exuhmy8.png)
(Click [here](https://viewer.diagrams.net/?highlight=0000ff&nav=1&title=SinglePageApplication.drawio#R7Vtbc9o4FP4tfWB294GML9iQxxJCO9sbXXbS5mlH2LLRxraoLDeEX7%2BSLN9lY1ISSLcwk1jHuvno%2B47OOTID8yrcviFgs%2F6AXRgMDM3dDszZwDB0w9DYPy55SCWGPjJTiU%2BQK2sVgiXaQSmUDf0EuTCuVKQYBxRtqkIHRxF0aEUGCMH31WoeDqqjboAPG4KlA4Km9Aty6TqVTiytkL%2BFyF9nI%2BuavBOCrLIUxGvg4vuSyLwemFcEY5pehdsrGHDtZXpJ281b7uYTIzCifRrcvH83nerayNgNkxFE1uxy%2BW0oe%2FkOgkQ%2BsJwsfcg04BOcbJqDZS0hoXCrWgqwynoonpbhBOIQUvLA6slWl1I%2FEiHDsS0F94W%2B9YmUrcu6zlQN5Br7ed%2BFGtiF1MQBWjEUWrEDNuzURd%2FZpc8vM5GHmUr4UweYiMr2twSnFcz5fKLxWRaitG2MKLxwcJj1wWaZdlPtmokVAx5pDlnbFVEM22c2NZwwfG%2F4ZRIGcwJCdjm9X7PnXG6Aw%2BX3zEIw2ZqGbC1mOr8Ezjoh8A2Xz0byMeYgRAHHwmvi8OYOjdk4M5CwdYdEVlrihIhO15QyQ2BY5mv2h605%2F8MrxBc%2Bxn4AwQbFqaLZDScWVedeOgS7rAxiGdP6MKk50k1Zvsr1y7Q6tcYaf0aJUlPjpRyfJi9xciBmS14HyI%2BYkGKugfgOUmctdeAk5DucI0pR5EvRv8j3hVKNXM1l4nXyuM7GJutOxyqzlVVd8J2KrxK%2BIOTqFD0IVGUSeV%2BrVllhtgnVqjQZUGu0aXT6Fg2Mq7Te3rlr4tNBvUzAAMLgXPBstYeSrxoTZRUac937dHwkhVaatVTqbbEVNavA4JivTwpvIMngMEQLptVZEiLX5c2nBMZoJ7cRTqcNRozZvF9rOrBmvK%2BE4liSlDOLEnwHM5ZGOOK9eCgI6iIFt3vZnZIBkGvbYsWewUCd1ozIu4ZV2bxNq7l1mwojYz%2BVjRl179xaBr6CkwH0aDtDu9g90fi32fYvGG9wFDM%2BawvwEGDg7tlYC4YuKWBU4Fbm7w%2FvBREZYrRcumRIYP%2FewAgSQDGJiyqQrT8p7kG33EnHRt%2B1oze525dgmZqFcjsYrnIQmLsZudCVnK%2BgvEG1CsYVHDhTh8LQlJQ8mH2Tmut8edl0nW1bwb%2FxU%2FHPOr94YjI5eTxh%2F4onfsUTLyqesFrYeKJ4YmfdfBoN3avd29GX5d0Q3V9bsTJ3UYZviquPmK65Lnr6q2xctIl%2FcrBdi29t62Zyz%2BLfxj7PW9j8y%2B9kWSyOR58AF8Gia7n7nxaQ8q5V9UxHzU1grEDryDrCFkDQn0Z8e%2BNFw8U7Y7ZbfNYWwyyfWUJrc2uErg%2BXsogJXWMfRyC4LqRHdY6KEd5jbkjStYGUPkjo8OiqCnq4RfSrHJxf3%2FLrC0uWZtvSrdmDLJwrL7QmL6RH3%2BGbxdkcWfHvhfvpr89f0C2%2BuXm90Nzp152fBSAUEB924VkuPl%2FxTjQTGDDn%2F3s1G318dDbAGcuAomVTdpJVDxu5StH6fpULgHPnCwx%2FSmiAoixwdwG5%2B8S6QVSg5kKzqkJDSJsRiAs9kOQmvx%2FK5PLbqpB%2BPJ%2FPa2axGKLN2mUWUX8%2BHB9kYdeYoB0bFmSroHYjjhCPWHY9INEUvrcqIWBYx%2FC9VdBu971%2FJHP3mLwAXcNSNN7uFKvE3Q65yT7N8YhIAoSMRTzeenT37arolQNt0waKRYswxFEtR1GyN1kjPsAwTfQxLmm6ttmmXbUsz2HKPTAAegpsAIdgbgCYvf%2BWwFgYrt8baWIPc%2FWkOIp5SGRoScytdDNx%2FIfIUj9GG%2Bog8bkVwuqvEirAgATJYyg6ESo4ElY0yFwmbnMiThTI7By3Zdyqs79equkeIfW55r%2FLDs2eJPhBflolapVJ8B9P0z3DrumCeC18Z%2F04292onn%2BzFPm3%2FE2Go%2Be%2FVbvd5PT5N3M0qmrFVmhFtw1FqkB%2FKrW0HwtI27TfjFgNM3LYbjw47Xlln%2B3%2FOZRw2nPTIzzw2R%2FA9tuX9kRuWZwXbn3%2BYtfFCsTIuXCxk4TCYvzE5zJtEaYiUdVlgQ%2FLnD6vORw%2FKiZqc9VIcd652XPeeT7OUb%2BXAx7rF6Wfl%2BIXPSmyNYX7Yz4VsPVmIktvoO78s6wR00WeZuWFUp6VF4tEqyj99JnWrkPVcqZVmZHtm2mVkB7y7KNec2F1eSzQOxsru19wo1Sqgj0vZpOtwzyfRS%2FkK5%2FSfoEwzw4T8gOE29Id9WFCQY2CDbcVMqip0REZvxDSdDkifQ8njJ6UMXtS5uiHE12zLtl0vH6Vp760RlDwVR0QZKk1cRisocjDg%2FzV%2FII1BSc4EPd4yQFYwWCan2l0HYMeTKgGYm3xeUGILftBbQfNR8jCWI0XfhRnvZcKL2R0BC9ECdjx%2F8MW%2F7KpJVu516aOzsqmNt%2FF9zgAeTMqcxtFlNc%2F51KkhX4Z1p%2FPsI7HJzase97uTmEYQPobXzNKQBR7mIQC1GLLp3zLl29Fvxp0vRn9mDzI7xSGG05e4WDAyEcR%2FGNPmu7gd7LPl0auvbKts6dRjS6eZzjOU9FFfz66OBCB8cfk6zX8SHdk8s8WvMuN%2FCP9EP2kqQ8ehmtmNf9h25d7wjxRWkCCmAL5%2Bgth5diPFxaAsrs8mzhh6pl0ujLpneynv2ecu9atjiwLjLKfVtu9cy4d52iVt9s6Xrp5cmeHFYsfUKeplOJ36Ob1fw%3D%3D) for higher-quality visuals)

Wouldn’t it be great if we could tackle all of these problems and reduce:

- the time users need to wait for a page to load (not applicable to the first-page load, that might actually be slower)
- the load on the server - by removing the templating and just returning the `dynamic` part of the data
- size of the payload that is sent over the network
- the size of a deployment quanta

That’s where SPA come in and solve all those issues mentioned above:

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/unnmno56e9jjbqbgz8qn.png)
(Click [here](https://viewer.diagrams.net/?highlight=0000ff&nav=1&title=SinglePageApplication.drawio#R7Vttd6I4FP4t88Gzn%2BzhRVA%2F1lqnO9vZ6Rl3z3Y%2BRojAFIgNodX%2B%2Bk0gASERsNXWzlTPacklb9w8z703l9gzL6L1ZwxW%2FlfkwrBnaO66Z057hmGMrQH9xyQbLtGtYS7xcODmMr0UzIMnyIUal6aBC5NKRYJQSIJVVeigOIYOqcgAxuixWm2JwuqoK%2BBBSTB3QChL%2Fwtc4ufSkaWV8isYeL4YWdf4nQiIylyQ%2BMBFj1si87JnXmCESH4VrS9gyLQn9JK3m%2B24W0wMw5h0afDncBD257P45v56ikz%2F8urLOuzzXh5AmPIH5pMlG6EBD6N0JQ8mWkJM4Fq1FGAheiifluIEoggSvKH1eKsx1w9HSH9oc8FjqW99xGX%2Btq6FqgFfY6%2Fou1QDveCa2EMrhkIrdkiHnbjBA7302KUQLRFVCXvqEOGssn2foryCOZuNNDbLUpS3TQICzxwUiT7oLPNuql1TsWLAA81BtF1gxbBdZlPDCcX3il2mUTjDIKKXk0efPud8BRwmf6QWgsp8EtG1mOrsEjh%2BiuFnJp8O%2BGPMQBSEDAvn2GHNHZLQcaYgpesOMa80RynOOvUJoYbAsMxz%2BoeuOfvDKiRnHkJeCMEqSHJF0xtOklWdLfMh6GVlEMuY1IfJzZFu8vJFoV%2Bq1Yk11NgzcpSaGisV%2BDRZiZEjoLbkPAy8mAoJYhpI7iBxfK4DJ8UPcBYQEsQeF%2F0MPC9TqlGoeZt4jTyus1Fm3duxytzJqib4TifTiTVSwhdETJ1ZDxmqhITf16pVFog6oVoVmQG1Riup06ugZ1zk9VrnrmUfee4UDxS9arZ9kuZAK0jTaJ04baR6YLmWSnM7zECN8BRphepz5AKOc4eCNSNRnQBR4Lqs%2BQTDJHjiHoIxZYUCSlrWrzXpWVPWV0pQwvnHSEMwuoOCgDGKWS%2FLIAzrIgVtO5mULW7zZdthoF7B9rythRDBm1Xxy6Yle2VTYT%2FsY5mPQbNT1gT4SrqFcEl2%2B70m4o409pXbfofJCsUJ5a52AzYhAm6LzywZOqfLF%2BYNPfbvfLWiVgCQgPa3ZU6U3rjJ7cos7EoVobBMTQ1cVXlxGhPGLnQ5eyt4lUhTQasCzSfq9Q1NSa69eTSqxbfjsRzf2raCScNjMck6vaB%2FNHrzoN%2F%2BCPo%2Fgv53FfRbO9h4SkH%2FsCXoz3H1NyI%2B00XHyJOOG6ySXxxsl9m35rqpfGmxr%2BTnWQubfdkdkWpiePQwcANYds29%2F9sCkt%2B1qjHmQHYCQwVaB9aRwDqWwJpAqhi80%2Bw56aIDChd5sHS9KATAufOyEOpbSsIgFpscF%2BC7b7SbgDCFaGeaVRUamVSO8Vy4BGlBqm745sCzVduf4Ww2qwGvHGIXngTm9Ndj0F4YVtvlAwR4ll0PZhQRnnKvVAD%2B4EgW6XMFlDUUM8VqCYzdRJlJID7MdyQ8eHA3MV0NZzua0IJ4iXCUbV96RYb7JHID5fatNUGgPTNBUPT%2F8o3PK7DEBYmfbdX0w%2BB9UMe7bSjwPlAZ7qPBXU4O6HLU4HpwzosIEx95KAbhZSk96K62HOEaMUuTGyRIyIajj4G4ShG6JHhzy0fPCj8yg2%2BJ4nS9fXO64aVTDWqsBubsxGEi5tiyTyMAe5A3NdPH6PbSgaMQba6vJrMv6PO%2FIuHFVr0LqvvM3QocCWTrPNLAMKSm7qEKLRWKefc3zGRtVUHLZUInW4d5MYtOyI%2Befi7HqXG9%2BSu8f7o0DZsMrhteVT0nqZ5b%2Fg0dl7py9g4T37E0wI6ovFMOfFcqLUhyT4NhlrvDELBstdZX5sLyec1vzjMjk2mFe7EYUr4Kl1V3SnI3gM0zYH9cBJP4D3blg4ddyfjfzK8Vie%2Ff0q%2FpluTX5Jy3oSn8mnUAv6a0YYMXOTH9TZzYOiC3pduipR9bd0oPxgrCgZWOr%2FR1PyquTu34Ggjyq7rEJlfX6hKNji6xs7t7EbjlsyfIZ28%2F0yTbphTmWxjj2y0jvdjyQhjepzDJUJu7ANWGpMqKlg17CBYwnBSb9KbMyd6UkjBrZ58TxqwmYzb%2F9Hbnpg6xrZbeESjSQ%2BMj7TKUgLU%2BrPGHNW63xkZHa2yelDWWNxJLBt0sXP5USQdJhrl%2BnGXLOG9ljFSppg8j%2FasZ6aHiRe6rGmn5lBmGJMVxBcICsQU63w0Qx%2FbQBCcPxCrgoO5acHgswOmvBzhlPmokAU4%2BTnH6qUcRJ2xFCWXMoI4TThWBx%2FHqpuzVm86Od007sqzjaFSFtMhCPjfrKIhUZcqg2v4gKUl1Mv4EflRg1k9dDTXZTOi6wk4c7fyi3pqqLfUjHBO70c8zgiz1qVurdS2saj9QLOm%2BxZ2Jd9vR2mO%2F6TlbgCRwzlzkpFG2Tr%2FVab9mgO938OZ10dZ62r4VbSMJbPtl%2BHF5WHbVclj2dLLsnU6Wj%2FbBsSoifxf59cOzQcRwFdMs59hV4ZtxAKI8fjfwz3S87D%2F5X4fXzj%2BPF4bXf9l74veT1KGFG4gDqjS2uNVED3v3qRm96kvnwbAl35OV6n1WXsqwwg0g9G6csYbalMY8UX5H%2FM7yhL1FY4wJY%2FE7VrtrxNkYMLSGnMKxvH4mScmol21%2F3oRRH6itobY0Mfp4vG1kzjTdeKGhMauGxh6MnmNons8rBa2ajlYcjlU7tmmGXd2q2GbN1%2BUz5c322a%2FRYvn78rx6%2BTN98%2FJ%2F) for higher-quality visuals)

However, that’s not for free. We get extra complexity: in dev time, of course, but, we now have to start considering the implications for the request handling as well.

Let’s look at how a usual SPA gets loaded and is able to process the requests and display data:

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fr9wwsnpv9jjsqg2sbov.png)
(Click [here](https://viewer.diagrams.net/?highlight=0000ff&nav=1&title=SinglePageApplication.drawio#R7V1bl6K6Ev4t%2B8G1n3RxBx%2F75sw5ay69p%2BfSs1%2FOQo3KDIID2N3Orz9JSICQcFNQ7FHX6pZwC8VXlaovlWSg3qxf3gT2ZvXenwN3oEjzl4F6O1AU1ZI0%2BA%2BV7EiJoptxyTJw5nGZnBY8OL8BKZRI6daZg5A5MPJ9N3I2bOHM9zwwi5gyOwj8Z%2Fawhe%2Byd93YS8AVPMxsly%2F95syjVVxq6VJa%2FhY4yxW9syyRPVN79nMZ%2BFuP3G%2BgqBP8iXevbXotcny4suf%2Bc6ZIvRuoN4HvR%2FGv9csNcJFwqdji8yYFe5N6B8CL6pww%2BWwth%2B%2Bvfj9N7V%2FfJrsf%2F36%2B3Qz1%2BCpPtrsl8ni4v%2Fo7xLIFSJx2GKGNRQQCtOkEeNv17fkgebBoR4UJn3GDfsJa2a4LXH8Z2OuBer0BgbMG6Bq5fffpjuvnlROBh409Q1d4hnCDZato7cItGf5cOC%2BA4gdtu%2FYUuNfJS7jxXR9dfg4W9taFErkOf4JotiJHr%2BzZahuAN%2Biqtxos%2BOEsl7ja8EVcz7bBE5g4UeR4S3JCGAX%2BT0CvCl%2BupUxVw0AV8b1oYq8dF0H%2BKpihas8iJLNbewuBgh8GHfTgbwP8MKsogmhWdPUK%2FoEvCP1BB4Sjpe%2FDWtgbJxzN%2FDXeMQvxoZNFfAv4k7mJrlznb0NkomAhuS6ts%2Bd7sPz6CQSRA%2FF%2B5TpLDxZP%2FSjy0UvhAUQwhc4AL5kiAqg3wIfvKoB1ksjeoU61gaj%2FUFVJwXOqTLI6JoWrjCZpFim0iQYvk8unKIY%2FCJAbgNqoAHXoQj2E1%2FCcyIFQRM9jezGejV9bpI%2FXYL2Jdukmep4V8NA%2FMEXGKLCfXRCgS8byiHx0XYCuHq1AbK4iJFdF8hdIPBAK8B%2BsB7yovUbQ9qbhJr50v9WI0xxOM6aWrkF7efaaEfmbvNkQGAbGcGCZAQRG9PyJiZdaUq9ER6h6yUm7WalfltGVfqkyh1gwh40q2fSDaOUvfc9279LSWJJzalwPMs3pDd756JXFrwVE0Y68cHsL9ZFBPYfZa%2FztMWYtsp2ps4Q%2FsHxuh6tElmjj3o7gFRCGLVhxdCoEXbB7RFAcySrd%2Fg63h9JIUnRacvtC0Bpv7bJbGaNSDuiQSqYQMCpx7OxgCci5N9Hd88RUH2Ebcq8%2Fgq%2FBzRdjqMTHITSV6kcAXDtynlgX7hCcP7r6J%2FVm%2BXvy88fYfv78xXn77uvQ4toRDvfIaG5y1gW%2BqcUCGLMZhztidxpZmPpmJPGR7SmtniQWHzUvat68JM5qxrqIbEsbpkUo8vF%2BIqeC7UDapcjY%2FxWcSsC0%2BSiT8MZ3oPMS3D1BIYTUgGabtsT%2BSBVW1phZYLrg9WNuA2sxo97HvR9CT8xH5msGvNgU0rb5Xe6AxHsVN9422Uqu428j1%2FFgnWj0SNpp7F%2BtX5Yoqh09AWCvR669iS%2FCNUg9bSMUqSN4jwvgXWhJNNaOyDpnRXQByNXOQC5zIIcwgS%2BmyNHert2rWeQfALyMFgghd1aYyvkdk8m1bnaFtSJTWog1QROlHtWCKgILauBQCcmNARiNH9GOYYglDF%2BeJBubFyyhTHw5S%2BSdFqpj%2FMkWGUv0%2FxP4tQWYiXkLI1cXvQFShWlAj6ElgxglaXFOB6DYIxbAnBHNQ37tzOfYqQ8AfCjS1iGA4JYDC1y%2FHui36FrQFQ%2FTaFPYQgta8qwnPG6iLYy7bCI2rjN%2FqyRsU3TWr9Il6HVnPjIfw2kiiqQzDKschh%2BgPFzEXNwjwlSRrjYbaDJtZP3CGpip%2B2LrY0vEY7Dh9lnZ1OODMNcoD3Wdt5yKrvOwM1uAnaW82wbrX6s37%2FX1fPHx9n%2Bz4c%2BhyHIKvfvuYh5ZzammZQkIFUugjAnx37o2Fjcoc%2Bcpb85JGyNsLiYTCxEEXHMBnRgQo7igSUiKBTdsqQ4NGihxbYpdt0lgr4ssRsZEnYu5kCktlWnLVOgK4LaMolTFRFCCT1Uq9EwPNDylilxtjU6nVXzXFgvfGFcf%2FGiVcZ%2BqnCV4X2cTvnKw3eEvH7UvdPQVxfl3BvrmaQIYXM8dkF66HULmQECSvTrbDGh8xGqKHDL9cLBOzSflq%2FFJ2n5%2F%2FOfu027%2B8ct3d6hxYOWbxmqOPXWPTkKyZzhnSWJIZ2kEETjYg3PmkJZw4H3VJ53XJ0tC3zK3Lsugl7kIWQJdiCNyvUoCnTqJ6E1ZGqMKNL6tzbHjq18Fgb3LHEAiwfTm96ggwxgZVs4PU3PpC1UnyDKpaap3cSVy59Ma%2BYtFCGWX19REKPsrr6ilObJbayhSXjqmwK8VsXCt0HBlYMzIhfSKD%2BfAhcjCDxACaHqCQvdutp3WaG2nseF7N00Kkg7tjzEbN6CdZcHPj%2FAyTrSL7ZTOFiq4lA9o0%2B7w%2BnaHGASDNwgJM5FtYNNbFLWbtG2Vj2fZGrXVYv%2BTR32pEjVzKY8LaAFrghM64Ct9ucKPKk0h5Nxionntz7dulgdxwQJHaAh%2B3vId3ooJg0qmhLj3WY%2Brfk6UkD9h3ibCJnU3Qt9FginOk6Kpc0qPW2ZBjzoJVjsAadIxMpI1zVQNS4Ohjq6wbRgsGVnlvKBljMiphirr5piHu66PlMPxLuyO70HDxvE1poD%2F7y6yFIqFzy%2B78DUXvqYnfE2pIveErxHW0SzUqgtfc858zYGAPDlfI6w%2Fn6ek8tjrPV%2Fz4kSUrtHIdszW6CrdTskatLHLbLxuqibhsuSRJOe4LFU19%2BGyCr2kLPtTFkhXpk8Sx6S99MkCKibfs2jkI664puS0VNWakkQGrVvCakjjcpaIG4%2FQ%2FAzDMnLmIUMr7UEZCd%2BUIA1PO0MDQpUEJxVrrJbo1l5Zxq%2FLjNTS%2BTJdbo3x7ZbO1Y28FpkVapc%2FQZZIpNet3vGc5OlDWl1A1SbjPBhmqzPnm4qhOKlNGDwSnHPB4xSNy0Ssbj0vnTVjFZ56x%2BP%2B%2Bmxl6hKs5dCvn0IkazmkCgb3qZ1RsGKgVnXr18i%2BVLjsyxiXX1YDBdZK%2Bq%2F9ZIezwNlEfw3woMA9MysvsK4H6w4BnDe1Ch83yooAwG1kD4vxyw8qCrZoYKkTXfDTe%2FzIotHNx8VP7RFSBwqluVuTE5VAUoZAUnIbw8DFj1bs01x4%2BgtP30eePtHuZkT9cfVKEcVQF6b%2BlTL1DSCZMGpMQyAIbo9K1ct8d63Oo6%2F3VFshV29qdP%2BfytXzSG6bWKdOVtfMeuJfctRQ28w6z5NL5YQdd4bOMnwd8XWiXmGhu8vCpdkELI19XZ3rAZFqWrnOnN0ak1VUNKz5UfFTO3Rmo7k%2F266xBF9nBKmIoVKOxvr5XyPVrNlV3RUyVD4Msjeb0Y86ozr7NRLYaoIixslHn1YAfARsdoZFWRop0nisaMmXsWHIs1AyH0kRpCOKRikrnQUaNeYq6bqzRjWxXMz0yxp%2BcyziOcaj8ThzisoLrbs8qsqenP0J8kO6hJJ579zExtASsl9iD5n6813%2BkFJig2dApuKbY%2FqDCpHWE9pEptJlVUsoFHHlptU1O%2BBVNKaHMhWPezXQjYNZ%2Fulxi1AkgIaC3w8gvJRFGOCPEoGpigIr5SIujtKBjlJiuWs3TmKLWUlydWZF%2BaEeDgz%2FX0Yx1i6O0%2Fk6Tg2wmfGM1MxHUiXqfWUAKsJnZ67RXlNw9obC0gcpgVVBXqVDipNssu%2FZfQWpZedHcCm8%2BrWQRUbd1WqGi%2FAHx596s7TejP2FQtsEaAjvDfYt1hsHjbRDG%2F4mctZIkHgL4jrz49Kp3lKnev3u84QiFI3VOmp3OeVTX7udvNg7Nj2s2t6ZvbJ3Wg%2BoDpmmbKTJUicfaqkV9zVfcjguORwkSulVDodWP744oV7xEw4xmK7BTFn1SMJ9LiTWHtKkcTd859tz%2BMpGo9FhWtP3KF7eN4xP2tXXFMY3UDPaF5cbQso3bsJlajpTQZ5iMi7Oaj9bnVojRaEIpGRUXJybI2E3t5uRoqVhfKX%2FSx2rRjOF6bnOL5rye2jWSy5jbKjmebOCrJeOJvkSC4wfeHKOHFx2xGacSJaiVbP2Gtd8fupctrZOLd0rXVojq3tlk%2Fk1Uj1DZVSEKki3ozqHecVUKkZ1cidYhKg%2B5hx9YvXls0DJkhBo2bYQv194j2zGchqN2YN4yUO8UwpnAQAedjfPTf35BVrwp8eqKqCJUvNSkERdY3ms%2FVvYPRpOxbBY7U1MxYEN5zDxWBMFlU%2Facn6Q3nybgMlE%2BhAMzec33uON%2BkE4sc%2BRqS1uekxVkK8pi9LyWvH%2FhWIRrFFz%2F5%2FBZULMP3BCzFK1aUYjHRfDfAjrr9CY6S0e%2FJ8OnaYN6aM4SwraQbyeTdy%2BOt7CHwhWRW2j5040UObwpYF734pKvMoluR1FrWjrMKUZleMRVHjTGJO%2FlPUgplnU5yCbo%2BRw9NfiMd4ZxPmwb4HX%2FEYjtsn0ACkfyaKdOJjCvMCU6xSR%2Fxfk%2F4HIl0VDpk8Jfd5P632Ac9Ico4QS7KsyNBtEVwb6bJhU5hlkuZAy83r8bnhhbXiSIADRNvAYO0%2FNemLCz8Zajw1TtXtvrVmrDOS5DswTWmXR%2BmCntMrnOE%2FgxSr3wyoLsqPK7GBPrDI%2FtNU8Qx3I9rzIJgPpkWIaFbB%2BJT0vAqwndaZWQh5JkpyxE9JIlZRyWyGY4oDXnKYMb6WWNGSC4XvXTHatJYLsQ2lgNrFBYc9vhdh99q7vt9adrTuz8W63%2BecWLB8FDCanlkfPWZRFxG5nuVVCsSgCsVxSFi8pi6IV1Y%2BesliqyD3JWBTWkaea68D39vr2Wrc6HY2c1YDcSRvuom%2BdeGRKnboX5TvmacWstv3F1QEewFWjsuJdDL3NKXzvsy2p2jZfdp74M0ID1bcuqtYtBNmrsD6JKph3VRXYjzYGAgkfgGd2xucXQ7wuf7%2BWh17mYVUmWlHnsL6HriSVSDIqWkrVkLlUjXxT2dLUXumFk2F4FUlb3Akyu2bGUbK2hC%2Baj%2Fyt89NaGtemi2Qkga2lNo5rswvTJMnF8dUMI1mo5s9lEWpZlbJwPmtVyqzPqVfcyNsTmU215FftyedmylUrLnNp2VqxVdhD4yefreXw%2FdXvp6n969tk9%2BPfz7ebPnAKWj5ZTLSSsmh5jjacF6FQihmF2oOs9ILRWmXBBCf5y7w49efFKUV3s0D7qFirjLMrsVZ3PF%2FRRFAwutv4XgiwQHco7%2Fq1xJR%2F6jw8B%2BoCbfEYq8wHlKLRe21MwCOsPZ%2FUHK3wYALEXdbld3DSK4f%2FB5IALBXCPs%2FfzGyUoTBHWZNTPyKr2Dw76JcgvSyuaICFhNKNI9SaCimhSvXiXMdr%2FBUrQn1dFLUzqROPtPMPnZhFMHApkTgz6qG%2Be1Sobma%2Ba0UTTXUpUrpkPF%2FrWrdP9Hd6liZVivOBFdcrK4208ZgJXtNe2vrRa42hOfgl0EPSLBA21K1aWrLVKLCsAeh6RnjTymthzbVW2wrI9qFJLyp3kMo1VZJaYK%2B7%2FsFJwZ7nNLR8Fl1byx8U3ahTbkPlY6uH%2ByvsuYHQ%2BxvVD9rMEFOr6M%2FCCfDGUOjGoQXjJAch2fdc%2FPDICQTrTYQ2cF97f8KjCtewjVlOkuuzniKzbg6jWUfwIU8SbTVf5k7luETRWARFtNJndzzEPov0MGaRe2OHZO3lslCTfU2I9hp2%2FVU0ZEmdsxl9FuM7WkZHGX1iLGk127nWqf3DVGCfcKdDFWjmgh%2BE9njPN2J8zjUkB96cHGZkIylGE9D6MKfVhCPNB7xfZ7aWW2nJqujLzh8%2F1ORjeHb8dHqfMcv2vPLRHMUSXl0i9tZsNwA2yq3ih0cHW89jl0zMDpJ2vNCZo4vFBF6yxrpwBGmRwxhThWS8NXYasbdoR2iOE3yEB8Ac1XMRINUgNyuYlODiUV48SrFHKeXYet6d1EQT5u%2BxaCncDHxEoKcKjXof3%2FtzgI74Pw%3D%3D) for higher-quality visuals)

1. Alice enters `site.com` in her URL bar inside a browser. The browser (after some `DNS` fun) will make a request to the server.
2. The server receives the request, handles it, and returns a response: the `html` file.
3. In this case, it is safe to consider the initial `html` file returned by the server as an _empty shell_. It is usually a blank page with an **empty** `div` element that will be used by the actual app.
4. The `html` file references the application code, so the browser will make a new request for the `app.js` file.
5. The browser receives and **starts processing** the `js` file. Depending on its size, it might take a while…
6. Only now do we have a SPA loaded and run by the browser. It might give a clue to Alice that it started to do some work for her (in this case, gather the information needed to display her name).
7. `Client-side hydration`: the app will then make an _asynchronous_ call to the `API server` (might be the same one that served the static files too, for all we care).
8. When it gets back the information (“Alice”), the browser can hide the _loading_ indicator and render the page.
9. Alice can now interact with the loaded app.

A few notes:

> Steps 1 to 6 need to be completed only when Alice _first enters_ the app.

> I made a clear distinction between the `dumb content-delivery server` and the `API server` for clarity - nothing stopping you from setting up a server to serve both static contents and respond to API requests.

> ❗ Not all SPAs work the same - while this example covers a lot of the work that is being done, it is by no means a complete & accurate example of what happens in a SPA: simply because **it depends** on how the SPA is implemented. Not to mention the browser cache, the fact that the `app.js` could be split, etc.

Now, for the development & deployment process, things get tricky too:

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/756vv8xej3thjatya5b9.png)
(Click [here](https://viewer.diagrams.net/?highlight=0000ff&nav=1&title=SinglePageApplication.drawio#R7V1rd5s4E%2F41%2BRiOLiDEx1yadt%2FtdrOb7rbdLz3YyDYtNi7gxOmvfyVuFkj4ktgJruVz4hhxl56ZZ0Yajc7w1XT5NvHnkz%2FigEVnCATLM3x9hhDyHJv%2FEyWPRQlGjluUjJMwKMrgquAu%2FMnKQlCWLsKApY0DsziOsnDeLBzGsxkbZo0yP0nih%2BZhozhq3nXuj5lScDf0I7X0Uxhkk6KUOmBV%2Fo6F40l1ZwjKPQN%2F%2BH2cxItZeb8zhG%2FyT7F76lfXKo9PJ34QP0hF%2BM0ZvkriOCt%2BTZdXLBKVW1Vbcd5Nx976uRM2y7Y54Yrc3f8zvVvAC%2FZXmlxn8R%2Bzr%2BflVe79aFHWR8qSe5aUj5w9VtXEn34ufg4XA%2F7v8mESZuxu7g9F2QOHBi%2BbZNOIb0H%2BcyCqhQXvB3VBXVl%2FLrIonLGyPPCT73%2Fyy4SZwA%2BwgNMsRHmpODLNkvg7u4qjOOFlARv5i4i%2F9%2BUonmU3%2FjSMxAUukqF4sGGW8qe%2F9he82fi7FAeV0IO03K4uxdsNAFe0Gy8Po0i9xTjxg5CtzpjF4vkv6waF1R3iRZJXyCTLOHqRgy%2F4F28Q8SUOSK1xHI8j5s%2FD1BrG03zHMM0PvRkVL8F%2FNl7DQZfSi6TfWTaclPccLnhT3YRZFs7GZdG3cDzOm4xX3KWKkKq5WZKxpVRUIuYti6csS%2FhDgGovtJ3inFK%2BzyElrlWWPawEBuIS5hNZWNyy0C%2BFdFzfYAVU%2FqPE6g64RQpu73gl8DdH4FYIPAIX83kUDv0sjGcCDAqgeQVkTdA2EVY2soyIssiPwvFMiAKv1rxRRHXyW0UX5Y5pGARRl5QkhWgIXIvb%2B8PJImFvxa5reyc4Hx5sktQg8Argo6AJPQSrdpSAhxxHBd7BcIcV3F2z%2BzPELwYuFyGnnvznNZtH8eNUvPlm2G0Pp4Sl4U9%2FkF9KtMc8Dnkzi%2Bs6l2fOtbjWIovTUs%2FtgGhZPXq7gFDSoV7%2B2RUlkT9g0WVNDq3nKvbGScCS1p59oItaELcABqgGYEij2ew9AOwv%2F%2FPHdP7v7Nx%2F%2BP1%2Fy%2Ffp429fyblNFYQFOZoUJLGA2zHlZpxkk3gcz%2Fzozaq0pWoa7aLonUaraFptdYf3cTyvmpJl2WMJHAG9JrB7qsrWGgBp5ifZhTArJZ4XZTehaMe8ItksqI4YRn6ahsOPk3BW7CgPE6%2FPlmH2Wfr9JTdlnHLrelldTWw8lhudsE6rKupUTKXVzZ91zLLNFp9AzzZSwo0vUpJtwiJOp%2FdNu1knAPnFeBX5j9IBpbJa3etWFEiWBrCRhby2seHB0ti42ek8l3rN8%2FiP4olaV6keLx6NUpYp4ltXyDNMFVuRaEWWV5IKNxvXzxPknkplbmDI1MSlMvAZHQ0VHuN7yJCywag8o1KCwyRO0%2FOJn1fOPhjCBQJZoP7AFsg8qNrBiDgWxSph8PJDmSRupw%2FHSYrw2lpeCA%2BMI0zYxx1%2B3TQOFpFs3UZsJAyVVPhhs%2FH7fKtopY0GSyYIYuUegW6eX%2FlYNai1VnED1HKbp3EkKkcH9AI0lU%2BP%2Bgv9%2FXmk%2B8C8p9GmOqDX%2FSAyyp09gFxrFjmq4T0o7O0OPI8itixZWkPYTYW6TzvpGDHG0ZI8fq6tG77xRd5YmSr5lngx7FSbtywJeROL%2B9XmTG71WADghuUD7coS0ts%2BYqN9ta3sIS1g6r7ETfZQpT63NYjOgYUIIIo8ODpxAE%2BxnBQTx6FaCwdZLWkrKqU8eY3JRHTXo8hrX6%2BoO%2BV6u1p2xG758ZAQuP4BlTMobXRuvog1p8UVUXtMO3VQOM37nmVVo6fKqvS9YMlb7sGLXiu%2BdxBnGRf8TvrkQjzKP%2FyQ%2FGYX6bzoI895utoYhUuh3S7L5yk1jtA3XNvcDIMZssJhPBuFXAsmhaq5CfzM5%2F9EOW%2Fam%2B9hIP5BRJf8T9SckNPHOROli9n3Wfwws%2BZCC%2Bp4X%2BfBn4aalfqpm7bt1dUbJ1e%2B%2B%2BBspJNnm%2Bi6aRFV1VRduHfarlxHIy1GWnojLdp%2Bhl5IyxY9BUZajLS8qLQQWyMtwOuBtDhGWoy09EtaKNBxC6Q9kBZipMVIS8%2BkxQYWRK9sid2GM%2B%2FHh4ffPfh1yt5dfwy%2BvnunCYtShMUM2TxxyGYPwHHagSFAExji2JoeOUIPNXCPda4uqUPUzkQEY1UZ5MdCRP1d5iGDFIie9FURGYv%2Fd7e86UAUc%2B3K%2FwfsnkXxvIgoAdXwTnH1s6JpqxM7tfrxR%2B6RlpIykXs7BE9xxepZnvShGiWri%2BGDhxrTqQyldVpWIG%2B%2BfW3UYcJllNSZHGqrqyWMXcttVZQLNEFAtm05nlo76GD6ZIu%2BgKJythhc1QtHk8G6LR7FHuN1nPlcE3SP0qxv76e3mtwimPugXHcSyn1Ux3OgrWkdbHPIE9dzbeAgSA5lXKueKOfBaTw7z63TsdJwvQ8CBLuo5zWD%2BU82d15AIT8Xtd0x08gClDgAejalENWD56WCcYmFiA0BcopvRdd4Gi2MD6VmtnEL5dCMHG4seXPPCtTBtucU%2BOlkFd7cFV0tAkaJi32impAMBg5zK40keZWKbHS6nXpvNS7sl6t6Iok2mKUOiFmOxYwXKx6NwiHjEJsN2ZzDLoiHC2GHfR1E%2Fuz7Ntp3L9EsPfUB4D70fzc7u5btCSnybJfYoDJZSkGyhXJ3bezQ4rvqPpdECWMLY0RdDxDbIZ5LNJJFLQoc7kqi4vtAcqbaOgn7sWBpds4V%2BjyepWpolmGJX5olcosSYsJNSMJ1vtuMRd%2FIEtr4q4PRRDVb7xV4AkMu3LbKE4TrBGp44oh4ouW7113Ah%2BQPB3Cdzn85js1Jwm7IGETEom5FH55bhYL1kkCg2ifJVfiEV1k5y83wx0nxh2dBFyNAMaQcmIQ0ezEgcSxCbQIdnH8jtbfnRd2Mqpv%2FFfijMVdA11Vt%2BONI%2BONwtpjrWh5yHdeBDnWJMCsajoZjAbAyxXTRv%2F3hCWTGrp4ydlXP9dt%2B2Oq54KvQZUG0UtRYA67CDyYuwRg7wPE0E56R7VrE4%2FrbLb8P1dWJdIq8GIgKwvvVIFRRNKgKEv9BN3A1WJ0AlHN487BU3pG0L9%2B8Ql2meRCpqJ4clYaBSBQwWsyGQrFzDZ09dl3l1Eyrp83d2qwhZBYqZwxvPXXrmK01hzv7FHEnwyaUkwVoRz1YNbnwb4xdT%2FX3dcPZB5uGjrYJrjP%2BvrHXeuXvQ8DtOAgpQYRigilohuIdlb%2BP1JEZEds28E1P8al5%2Bjl3ANvGtuNC4ja5YwtPn7ykp4%2FU6eiGOQxz9J058h4A4AHKRc1zsEeOmDnUFEJs6odRanjjpHgDEk%2BMMII8R44LKWiNfmwmDt2c9n0Qx%2FuP%2Fwz%2B%2FO9dNvo9%2BQm%2Bffnw%2BdPijSal38Xtb7zg7ldPSGnCWncAtY3UuFY1XPNwkaxa6MKtgzW3roCdI1nddr1ow1ixawH5o2OpfXQqaKvJJMLaume6qQ7KSQIak%2FfmxvMw1orWeqRuFrgmbA6EE21KFrXvSczwWlrZPDImzHGYMM8FX22WW8gmq09zXM6llkelvS%2Fn%2BWph%2B3qhtAEZEEcTSsudJjQ0Q9zHofg7hrj3JEkYWI4rz%2F5pOgM2srjXu%2Fq4HUPc8kdnOxALNI45kKipfUwT5otJwIYiTo0iKLYcGXPNLv%2FNFOG%2BJEWoPTOGIgxF9IQiPM%2FCSJKk1myL42IIdb7FKI4zwxAnyBDQwRagMnT7TBGvONPCcIThiI0OObRsqKr44yQJzZwKsd7XOVfAhidOjidcC0nYRS5uztuGmFoArk2gQV%2BUKNQBM0MUhih6QhQb%2BpsggJusrl4RBdYTRfYQG6I4PaKglgOkQQnUb57YJquw4QnDEz3sdDo2mlBHrvNcWcPMsMTJsUTe7eR2Q3szTbxsv5MZvjY00VuayPudgKrlj5Qn1PHrMtNre6ZrMVnVMnkET5BAkIVsiR%2FsZoIo6FGLqotTbkjwcbCYPfh6Q9smkaChj216oyR6cNpTIURq5NVudfZ1r9hDHdvOhYw3Qmrm%2BJwWRxROhozsBrAR2EQSL%2BpjoNcb26ZogImGJDhF0MA2JGFIovQxuoLNj4sjKsHSpOkZNJaY0KbiKbL1lPl3To1PTOqbPY%2BWtAJ0m24MEOtESx%2BAAVQnVx8qV6H2FdVO3HkSB6pvni9AblzzUzS7KLKII%2FnmcEfXXGd1HWzapUnxb4yu%2FhpdAFoUSw7MkXjm2tdXu3WLiavfTtCMOml%2BgJ7lyqBuDv0hKvAo7cYKql8088brdd2a3MyGIDaNglALEHnduqb%2FwCWl5UH0miHUrtsoHofDPOLcsMSJsQQFlsjeUX2als8WJHGovlv9671e361hCcMSm8IIiUXlaUnNWeBHRhIdS70Ygjg1goBEjFtLgOu3H2EWeTEU0V%2BKgIRaXncI4bFxxBa9uodOOYjc1tLZCEC4YY1x3UgO2YNC0udMVeromt2rKqkU0sU0uhhm8TOUgqShtPpBEd6eCiJScw0285tun6r0mflB12N%2FpySG%2BCWRp84XVGB3xOSn8JwW7W3yu2fMn1qRPy8u0lPsr03H%2B8poXjaRXAe%2FK1pWl%2FfwYOOL1Xi9hG0WjFllh8RJNonHYn2lN6vSy1WiV%2FBsM391h%2FexgFbRFCzLHss2LcMtJBk6IvDVyV87mTytnnGDNsr8ZMzWQbFUUqL11uIwYZGfhfes8RT7xxU1uOo3rpCKKz3%2BegYs7%2FiAxdsmefws7m65TrX9pXyafON62dh6LLdOC5Hbajp734DMT71IEv9ROqDsUVtd%2BVYUSESuJrPHUIa3cgay6foz%2BI%2FiKVbiUb%2FO0yWmes4jlRhkJGYXiVm7ruxri4yjigxYKzLYc9efcSCR0a3DS2oPOu9tqdqR%2FFjEReh1ldBfKiqCTUUeAd625wGLeN3mFd01W1QK6i7u1LGI6a%2BzggrduVvihFdQgdB2WgLhENWFhLr%2BEujuwYn8%2B9N%2FqX3%2F9vO%2F3z4A98PN3w%2F%2FgPS8W1qkdXjziOstl%2Bit0D2K2JKLt2hVrueD8uf1MPLTNBw2Mb5Pxuori2hkpV5EhC3DTDAmFOudl9s5Y1rUJeX2ijTFxqO0ccuSkINB3HHFqp%2FljU3si2uebl9rK35bZ%2BnJ%2FIZ%2Fji6vyM0l%2FOJ%2BmH%2FC%2FvzfDz%2B39n1LKeIajBDYkiNVinTjb1XZbkSp8JorJoh7druvvX4Y7FHLlqLQUfMGRcWV11xDn8RuE64NWkqgqFvlUrtSO8HqndD6Z1POcNw11L46v3qkeDRKWXbWVl670b8WTmoHcMDmUfx41HY0J9WGKFsugWvEGXRJc191o9bCbuvGhl501mrFrbTWOm20uceuH1Y59dB6QVTOgMBpm%2BVPOMXes%2FOrbQudadISYrNsWbFsWTt%2FEyN5%2FiY145PrDUB1RqX9hkmcpucTP6%2BcfVi6LhAMqczDqtFDgGs5CmUj4lgUq7SNyB6WD1wn7BLA8qm5wsHjdbW8yC3fmQja6jJyp3GwyLmiGpmL2Ch3CIXLNRu%2Fz7eKNtoYH1aMzj1xGqx2lPspISr6ebA9BP5ag3on53MfiPcE4hWYqyCHQDcafiiAb5Mc6AVVaPcqij3FmH5NyM6VH3eHjXBnFAbHSKcdkWdRqmIHtp2C%2FYFHnTNRzKrL8dCGkQmI7WVA7O6QxK6F5Ix%2BbcvPFRn%2F1kXrHWp2hJ7CzaotJvR1%2F6Gvu4uN41hEzirbVupAZJ1Vcty8fpCrXqpU14tX9DyMWGBynf3Cyp8Kx22t8rct210XZnyoDPt6mKoO3Espf5PWzCh%2FKSuNUP5dWQe48odiIKd%2FExz0QqX2oPvzuZkD9wtrfW%2Bz1qf2CnhIwe%2BhZrvpAfp666qY2W5G66%2BmPgOw3uTPtb4iVi%2Bu9vlmEouYptXYjEDJH3HAxBH%2FBw%3D%3D) for higher-quality visuals)

For the local dev process, the _frontend & content delivery_ `server` is most likely handled, along with the build system by the framework & setup of choice.

> Just in case I wasn’t clear enough with the extra complexity: there’s already a build step in place for the simple process of having a feedback loop between the files edited by the developer and what the browser displays.

On top of that, more often than not, an additional `API server` is required so that the developer can get data for the SPA.

May be still on the local setup, or it may not. The fact remains that it is kinda necessary and another thing to maintain.

Oh, there’s more! Since you are working from the `local development server`, additional configuration might be needed only so that they work together. Fun, right?

💡 There are some nice things about it too, though:

If you do separate the two of them (`SPA` versus `API`), you can deploy them independently - thus, in theory, you should be able to deploy smaller chunks of functionality.

⚠️ There’s a caveat here, too: if you work on a _vertical slice_ (touching both the SPA and the API) you will need to deploy both of them. The good news is that the advantage still applies: first, deploy the API functionality, validate everything is ok, then proceed with the SPA update. This should allow for easier rollbacks, more granular deployments, etc, etc.

To sum it up, for **SPA** s:

✅ **Pros** : code re-usability (due to the templating engine, similar to static site generators), can serve user-personalized content, reduces the load on the `server` compared to `server-generated html`, small deployment size, good UX after the app loads.

❌ **Cons** : multiple build systems to maintain, a lot of configuration on both `local dev env` and in `prod`, content not index-able by the web crawlers (crawlers only see an empty page)

### Single Page Apps with Server Side Rendering

![img.png](https://costica.dev/posts/web-apps-my-mental-cheat-sheet/images/singlePageApplicationsSSR/tableSummary.png)

**SPA** s are awesome - as is `static html`. That’s what a SPA is, actually, `static html` on steroids. And just as `static html` have the `static site generators` to solve their shortcomings, welcome to the _Single page apps on steroids_ - **Server Side Rendered SPA**.

> What does that mean? Do we move the whole SPA on the `server`?
> 
> > Not quite - the SSR-SPA still leverages the browser just like the usual SPA, with one “minor” change: at the time of the first request, when for simple SPAs we would have an empty `div` - we now get back from the `server` the whole `HTML`.

The immediate benefits are that web crawlers can now index the pages - **and** we still keep the same application code as before. On top of that, the user’s browser’s capability of interpreting and running `js` is no longer a bottleneck for displaying information - the browser can just display the `html` the server-rendered as soon as it receives it.

Sounds awesome, let’s make **all** our SPA to be server-side-rendered, right? Right?!

Ofc, do as you wish. But please look into the cost as well: for the first paint, the server needs to do some extra work - and handle the generation of the `html` that the browser displays right-away.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jetptlpqydya0qrp3v87.png)
(Click [here](https://viewer.diagrams.net/?highlight=0000ff&nav=1&title=SPA-with-SSR.drawio#R7V1Zk5s6Fv4t98FVM1NlF%2Fvy2JuTm8nSN53cpJ%2BmsJFtbmPjsPSSXz%2BSQBikA8Y2uHHi7qqkESCE%2BM7R2TVQr5bPb0JnvfgQuMgfKJL7PFCvB4qi6LqN%2FyMtL2mLqmhq2jIPPTdtkzcNd95PlDVKWWviuSgqXRgHgR9763LjNFit0DQutTlhGDyVL5sFfvmpa2eOhIa7qeOLrd88N16krZYubdrfIm%2B%2BYE%2BWpezMxJk%2BzMMgWWXPGyjqmP6kp5cO6yu7Plo4bvBUaFJvBupVGARx%2Btfy%2BQr5ZHLZtKX3jSvO5uMO0SpucsN3X%2F%2BsXs1%2Fjh%2F%2BsZ2nL1%2B9t%2B%2F%2FHlppL4%2BOnyD2GnSw8QubIPKO64F6OfN8%2Fyrwg5A2q7MZMqZT3B7FYfCA2JlVsEKk8QHFU%2FL%2BMj6YJuEjGntx7K3mWdM%2F3nxOH4Cn4VJ8k%2BzlHlEYo2cIBs6EDW8zlRijKFiiOHzB12V3DWUrm%2F4Mn0PTyBqeNl%2FbzpoWhQ%2FNLnMyfM3zvjdzjP%2FIpnmHKbf3m3I2sR3Mdi0y9v8ErzXBjLPUzfA68FYxCm8e8SRE2SzlBCrhA9eJFsjNDhbx0mcXleYf04ExtdBkJtKH6yBrRujDdybIvw0iL%2FaCFT43ReTJ%2BASZWg8zovfcBZMgjoNl4YIL35uTE3FAQOFkR3k%2FQRL73gqPiTFIKX2ZNXnX5fOcMO7RI0LOcuQ767SThTNdJCF64%2BCDa42MPljFY2fp%2BYROLsLpwotxZxGetWsnwd%2BMPolcdBck4ZT0vIhjzKIVXb3A%2F%2BAPRv4hF0SjeRBguDlrLxpN8YuQE9OIXjqepY%2FAf5YeoiuX%2FGPShUKROoK3XQHvSk6ilfmIrAtcRAdArnYGclkAOYYJ%2FjA80hkQkqV%2FMY2DA4BXoAIQcieFKXJcoNbx%2BFI3u8JaFSutxJoiLlFqRxzUUt4n4fLH4s0HfenOPl3%2Fbzp8GCpNl6juFm5Z5dZtWZLFWclX9%2BK05BJa60QHzYvhx2S58B7xn%2FOYgiJtIgij781AZvxIgvQCDDdLIqPcNKX3YlJEKb7TPgYp%2FPmucTPwwJbGwO6dhMBjm4ymmgGNQ2dJ5JUnQqR3a4fS%2FFPocNzlVBiJrIqMRFVtG6sA%2BB0zlKoS5Y0Mn6pUyV8PZD21lLyd9bweVemVVFVE28cgXpC5qMIihzr8XKxB%2FuJgu6G%2FgG6mk19IWr0xyC8v7GIR0fXQput21IoDAZmd1fXSOqCJcpcJoJVddghYr%2BKbp7GpfleG%2Bq3%2BHf0dXn01hpqIVlkEnztHd9lhEMaLYB6sHP9m03pJ7QZUv5D5iRYAWZpm4DNsnvA%2BIIwk%2FTYojl8y6DhJHJRBj79R%2BPIdHwylkSRprOWe4GGkWSZruH7OEJIevRSPblHo4TklOE01Dh5rEv3pMUVZIkXlY64UbSI2xm3qZ%2ByEc1QnFmakQMDShBDwp5JlTeGkouw4RL4Te49lRELgz7q%2FJfpv4ZJgNovwYHnqyEfRiGA%2BSm%2B%2BjdF4LH0Mh%2BbTm9X3K%2FXj0GwqS1ZzMWGJJT%2BgLk5%2FuK%2BsdWthsiReUJUBQdXUACZlt6EdgpMuKoclIVFiNoSN9BfSYVUKg5kguflo7EJyYhjRqca0Kina%2Bjm9jevonfPoRNPQW5NuwmQVY96xRa4EBdAmkuY0mTRY%2BCcpC34%2FyRtyg%2B6nVL3N2l0nfPiEu%2FFiyv9Gkl5uVGiraBxy0cxJ8tlrxgAzzBoQZzLHVLAsUsnmEVVLOFvm5eOx2J3EhnobV4pKiH5rec1O0u6RSdPYIu1upzHZrKAx10HLYIWv8L0oRisqLUszDAeyPvxIUEQhh692lnSS6b%2F0ZJyE2eUhitbBKkJRU0G7LMlsoTlqC73M6axO3txZDBJWA9swVcfYifyOK39I4pqHZFdHZheIz84aWL6TSwuWKY90TbSsqPaI%2BfaKhGHJen75IbTxzvjrfuj9ea8%2F%2BT9%2Fmt%2B%2BuT%2F%2FugPsK3e3%2BAtgklGfL1KsTjBs%2FGor5zJwEypgMw7ioxk1rBBWvZq%2Fp0epBVCwo1do5UVFqQK%2FGzacQxg0iJYgTL48UxKiwCcTUw1r5ppUegxnQJzObEzdwVlXrJFuWrqlyIZtylIZ2pY%2BsjRD1tXsX1F3lFV5JGuY28uWotu2qlsi5E1rZJuFfrpCP2DSvyd8%2BADlUrBoH1W5zFXF%2B5IWKeqUql6lVPYV6yalTCeML0gIAuEivhNF3pQ1jz2fTcdu0C%2BqlyBKNFG7rOOlW7XLxprjYZwd8slut1Fn6rgg6XwMGtsBe08tz15MiWWkZ0f3hTMbYiEHLz2nCmAFyO3hr0QGTBfvCR1oAhl45LPFC7QR0pnQzmvBDkU2HuSUXOERHI4HeXRRQSJfBMtJEm2Xxg%2FDek9BqNRJ1dU6QlcCimyXzUOqaBsCfbutRA7AFCFi8CTFjJ7ir9aq%2FDoiA2SRhi9Ue8UsFVVAKln4Tw2oG3l4JJtGSSYuOl928bX0Ffug3fJEsG%2F0CvtgECMTg%2BlSXhCKc6tdat7j5AaPmATffvnw%2FiwvnIC8wMUrq4AzCYw0zIPG2oeifno8t6dgO6aGxBbzU7MUAEZghCERDiPPJQxu8eKGDo1YhZhdMCuoU4wpnhp6CxKDadpNrWhnaeF4NNM3aUGUlMsO%2F%2B1ORavCqbizd7Kmo6wlRss1nhVUEmHQak4ElYye2U1Zp7UhAROgbceo2T7MT5isctYlzMM4xL2glYvPXQWUDf7r7vbi37VTU9%2BCRxpiJuXNCEo9MnTMhTA0KVs1JMqNSIB5gY2CM556kVeTKHMmC0M%2F8NtJ9Z%2BvDVg2DXfmlpHfUVqGfNaz2UwBMgFJDpQxMfQupWXN1kZyOUBUtkUvnyJBArPZmcAsxnhEVIQh%2BEmFGD%2BYUzOuqIztEk7xa0LMEiGWJ9NVp991BbFcr8rwpZuiQqZBAfNqGwrZ0%2BryNrFuHN2b2i8v67%2Bu0fw7GN3Hwejo6Tl5GOTWPAKtq2kRFYdzds45OwdO8zt6dk4tIbeQndMZVVVrFnXwvb68viSxNAB8U4GR9kBRxVoK8l7hkkngvvCXAMJs%2Baa10Olbb6BcFYTJfYIOsvxakNr%2BEMaALxCGsXXgRCIGXli8Cpq55npABatoLEsrbelCYkc7c8PCvOTx5VE4LfXgrNejf6LS7cDMVTPQWjUAk26O5ZQVbI0sXHqum9qZEJ6MbM0lrIeWJaAUrF8O9GvSVxIHUcbQBPkni5sFykRAfLARj4ZsMSDH71sgeessNy9xUxJ0VChUFgog70q5UET3%2Fc5kZzQkO5v%2BiGT3OQ9UeeusXL%2BQlrm7Ft178rH3Jp8sYaOjWjjViWJ59uMmJQmSzqG8hzbECBi2Yt7kHZ4CEsot3ZISTYp0sV7jFZaa9iM6VDxSRbq7%2B9wAM00%2FbHNsQVJw2S1wKoJwGzVU9gChIfEgBCovqQYAws4MM4qYjCiqzr33DvUUZs3dOXkpq40vh4W4EqeXPJJoXywWVhrpmjqoi4clB7zTqxLDWxN4W%2FeHcjm3jH74kkJDk4%2F5S91Q2X0b7ON5dF4Kl2XLXuWTVP5Btm4U%2B9t%2Bg6XU32Cah95gWlLtDTJvh9vnDrV0B%2F4jncl9851hHiMaf9Uzj%2Bkbj5HK%2FKWeu2y88batDUrxe6aZp67s4pFvxJwax7PVWUObVheQRqqimiV6YeSzG5%2FbmTkpdplKDbuGSjuqXABTcuPimN3Z2XVeijL1hu4tubMAcvbBzibB1kyCFaanQ%2Fzdv7eNrkVPTDPctmC53c%2BBs81FzNUBnTiRNx25wTRZUm71a%2FqQFXiRrWfzO3lhjsxzWcfFxDEsHz6PUjidmE3N2gU5YOWfg0F7BDy2j78XJqtJkqbmP4qt2oogFECGlc5CxFUxJOEcNN6a0mOLlLC3YcUqKT6qodWrPvsaVtpQSUhtOllXyvLvfkoJYBzg68LLEl%2FgssL6ImowfCyMqXM9pTNzsB1Hq3pQ1ciEG2R5yx3AvHC3vJ4%2BpioCkzFOj8nsY4H4ZRkTs6xgziSV8xxGipybWo5jWQEqCoAVQJUd2RjmYnnlGRaj2g4T07jc8qHOu%2B9aMiALD7INvZ7x8Ddolnx0JgJ%2BPXmXepRc3HMltg638xi8rXqzHG3ZRoNfa1qrdCs3MH%2Bdlc%2Fmymc9HJtXvBoZimgCPCoygIWYWW%2FOiuhJKKItYVFWR7JiSpqe%2F5aYGNFTFXPzoyu6LCAXikLpTE%2FVRORqpydC9pTvHSwONpLdDtIsDxS4hjJf7NlsqDTuKnFxSU28U2zr9Wxcnbq6tR44yIREFAXIz%2BkuZB6el2oHWeuZKOMomU5RVF2u95yT0icW2auclHqi7klSCjhIJtoWdz%2BbZjUh1iicBeESuakD9sQk0t82Wv9QMHJbp2XLgQGE60MSZ2eOO130jNhnibMvEiczxlJXg1myyNpyRzGndbsCbK07wkSLntQdYd6Z4m5IIs89w7vPClUtzrZuYsSKlneueimC6tVRtPRQiMtWpHrlS7yj7Ujj%2BQfv4fsP68ff3s%2BbJPj0%2Bc93XzSm9O5EaGfSaom0hEIUlkR%2B2byxAh75NtLirmt5S7brmqwMuvJ3gfCRRQp%2FTduKzpMQb76uIO%2B2qKlyP2VpSmsirTAa8Kwi0pIWaVqnaWsRPXAwZbkDtt3OcAAVZpokcX6zs16TEUW0Z1ryO1lRDcYhI33JnF890VwwvC%2Fp73b1ZV%2BLet4%2FJwqAe7LXbCUEbMVyWqb53TPteO%2Fy0LJEE5gKeYja2EAaJKZ9jOolvnn0daqErWrm3tflDNgmsX1JEfzUrZcMrwiy4uOSjr0%2BiHVQvlBG%2FrQIaBIz3akKI96jXa0QcgkqaE29CV%2BXuUHUvV4Rvv8fslQQ2khXm5AAJ1tS8hpjLT7KIyvLOsQChzsAt46jRQsnL%2FkgJhhmUTaKk1zA9F2o%2FLyAtbGA5Rum5t4uIMJBgSzMbWSKg9QuJnF%2BpPIfkwkxp8nJO4k2MmHKBZrU4vlSEANFutqQUVH6DFY%2BtbsH4QP4lKxkQl5DdEPQDTKcaLUK0dPEmMrF7Z%2FVXp1NahBGAnlGoQwz6wGoFHqSDGLfeiBnBrEvgxAEXLCSBCTgyrx7vjUGsZeZ83VF3EIes2qoZeuDtF%2B07YlLzaARiFXt6VRqtkTjS22u7fHt%2FXXDFoRgb%2BXFHrVcFHYiyewjCyfaLF2Z5SRE%2BNutk1SqXDrhA4kRkRxa39pbEfctq%2FDvTAJiNQHye58WDllpkF9YfjfLZrQIEt9lwjKxx5Dt0%2FwgX5zSRRSsi70R4en4JggPqLTER3TUaQVf%2FCIoFwV8b4ZOd2U7226OvbLJvNVTzqsGF3col4GlzepsZetDeWFeI9CBffNUcBucNjz5tXkfO5Y9yBZBQbDOWdXxtllvk776uJzrABtNA6VEqNZDf6fYp2PjEIoubEafu7307lTLFSsBaFaG0pLlNoplwiHt1TR7rgl%2Bjr%2Bk0ku%2B%2F9bR4y%2FryXu3%2BEuQrtqQEeBUXCiL7lwC6JASQD2sCt4fJeYcOtslH4FzSDRg9YYqXXfHZERrQxrk%2Fcdh0vGvKfzaHH3su2tOS2DiyqbLwDamsgKgqY2QBPgVxCUrd26mqwAxSXnEl0sOgnXsLcnU0iMMmMIfZ9VsL9WsfSWMnS2rHUD0y5GhJjKu1E%2FuiVFdZ%2FD0CzyQa%2BnI6BEr5XPy6f7FH78uUjb2znl00kqMfwzq3NVnq9RpoVcMmzgudlkduD2TP17HLcoKMuVFmO4LZ7aWhM7rP98Xz1U4UQVBLFc9%2BopeRVSXcrfujqguOkVrRbTtJZiyBfb4XlEY9YelPJ0M6s%2ForUWv3hS95muhF3zBfQp19iWQpcR7R9tK8Z94tMqrx3j3mC%2BDwzZPGNkjy1CK6JZHknEO0Tom6JumZKuvBno4c1fcH3AfOnjtKqkVAra8hQR%2BaxjDCdrSq%2BF4v%2FRrWUi%2F3rLRk6rrtTd0VPxKtCdbp0dnvzW9HJMMxIptQi05nTfLtFTQwOCL8bJNF6sISrhBN9olqOVX48e7ZP0UfHxzidzb6X%2BvpSGQciOQU9dhhwZfTE6FQpi6coKCsyKmHd6lBd9EJ%2Bi5GG%2FzYry1CNwt8uaocAB9A3xiVSkG%2F8UPHFfASt9jOX7XwrwH4jKXocoSEbdhjGQYwC5yUP7UHoV48WEYEKfTZm0g7OZD4CJyxf8B) for higher-quality visuals)



1. Alice enters `site.com` in her URL bar inside a browser. The browser (after some `DNS` fun) will make a request to the server.
2. The server receives the request, handles it, and returns a response: the `html` file. Since it was the _first paint_ request, the server will, under the hood, call the SPA methods and render the full web page that should be displayed for the user.
3. Server sends back the `html` for the browser to interpret & run, but also adds a reference to the `app.js` - our SPA.
4. The browser renders the `html` contents - Alice can see her page. For the moment, we can consider the contents of Alice’s browser as pure `static html`.
5. The browser also starts the request for the `app.js` file. The `server` will notice that now a static file is being requested, so it will simply return it.
6. The browser receives and **starts processing** the `js` file. When done, we can start considering that the switch was made from `static html` to `SPA`.
7. Alice can interact with the site as if it was a usual SPA. Let’s say she performs an action by clicking a button.

8 & 9. The app makes an **asynchronous** request to the server; the server **knows** that the SPA is fully loaded (information sent via the request headers) and that it can take the short path - returning only the “raw” response, without wrapping it in `html`.

1. Alice can see (almost instantly, maybe?!) that her operation was successful.

For the build and deployment of the SPA-SSR, things are even darker: we have to say goodbye to the option of choosing our own server-side language. There’s a hard, non-negotiable requirement of “run javascript” on the server side as well. Say “Hi” to node.js, bun, and deno.

We also lose the flexibility of separating the Static Bundle of the SPA from the Dynamic Server API server, because we need to bundle together the `server` and the `SPA`.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/870uwrsba4lamnd5jvnt.png)
(Click [here](https://viewer.diagrams.net/?highlight=0000ff&nav=1&title=SPA-with-SSR.drawio#R7V1Zk9q4Fv41XXXvAy4ttiQ%2FNt3pydzJZDLTsyT3JWWwoJ0YTGzTS379SF7wIgGmG9MQRKpII2NjS98531mkowt8NXv8KfYWd79GPg8vEPAfL%2FD1BUKQAlf8J1ue8haMbJy3TOPAL75VNdwG33nRCIrWZeDzpPHFNIrCNFg0G8fRfM7HaaPNi%2BPoofm1SRQ2f3XhTbnScDv2QrX1n8BP7%2FJW5oCq%2FS0PpnflL0NQHBl546%2FTOFrOi9%2B7QPgme%2BWHZ155reL7yZ3nRw%2B1JvzmAl%2FFUZTmf80er3goO7fstvy8mzVHV%2Fcd83na5YQrcnv%2F1%2Bx2CS%2F570l8nUa%2Fzj8Piqvce%2BGy6I%2BEx%2Fc8vpAXI6G48HAkPpCp%2FOs%2FX7z7ZBwHi1QcjpfzNJjx%2F16sni99KvtUPOpC%2FjlejsR%2Fw4e7IOW3C28s2x4EjkTbXToLxScof0D2IfffjVYNq579bZmGwZwX7b4Xf%2F1NXCZIJdiABZxmI8pa5TeTNI6%2B8qsojGLR5vOJt8yeZRLN0xtvFoTyApfxWN7YOE3E3V97SzHG4sHzLxU4haz4XF5KDDIAVA6yaA%2FCUP2Jaez5Aa%2FOmEfy%2Foer0YflL0TLOOuQuzQVUEcOvhRvYvTkm%2FxCYk2jaBpybxEk1jiaZQfGSfbVm0n%2BEOLPxmM4aFh7kOQrT8d3xW%2BOl2Jcb4I0DebToulLMJ1mQyY6bigGPQ2EWFyGwXQu2maB78uDQ69oGIuHyi6rAq9EkbgEf6w1FUD8iUcznsbidkF51GEFagq1MYCMFi0PlRSuZOeuJoHILRq9QvKnq8tX6Bd%2FFAKwgzAgRRhuRWeJTkDgg9QiCFwuFqHopDSI5kl2q%2BJOEbi9%2FUMnBaIv0ibSm7AskFGHUdGkdPnawdGJVpzLkxQG%2BfPe%2BG4Z85%2FkoWt7JxnoH6E1UUNgV8TuAYdOC4UIYhWFNtSgkPYFQqyA8JrfXyBxMTBcBoLcsj%2Bv%2BSKMnmbyybfDrjucYp4E371Rdik5HosoEMMsr%2BsML5xrea1lGiWFctwB0XWd6u4CwpridbPXrigJvREPhytGad1XfjSKfR63juwBXYxZELcABlhHNWfvAWAfgrn77f3DLy78PONvr%2F%2F0P799q6F8BUKVBoHb6bsxGoq2aYyFZqyOWRvVcSzw53ucTcYK6MURMmZ8NOlJJQGkIsaxNYghbA%2BQ%2Bd37%2BGey%2BHs%2B8B5%2B%2Bd%2Fju%2BTp589kgFVmLK1D2WeZdV52Bvm2lBbtMDOHGZDWctWU25G3H8TQgTASGkh6Dvyeh9Ei12WgND%2Fzq1%2FkQ1ue%2BAMbmuRsDM19KFbFeLRdy629mCIxUKdjIXR6khjkbteyEnmL7r2xcoELfm64kbpewphatNVRFGjox7Ytx9UY2r3pE7tr56yl75qkaYWjyWDrWd5LFnlQYRI8yq8PRR%2BnntAEcWEBqeOzebyfP2r1EcGuJTwkQBiixHEdaGtGB9sC8oS61AYOgoT1NFaOMlaCB2fRfCCeaxJMT8%2F8BM8xPytkvdzcOYBCfilq1zvuyAKMOAC6NmMQuaUCLRQMJRYiwl9CTv6u6BpXo4VxX2qGbFczq9FcwY3Hb%2B55jjpYp1OQmQDJXeVYr%2FPrpatCKPaIakJy6Duclhrpg4CyDCXoZONd6wujKE0FElThSSOpJqPcfrlaBUmBTvBKc2n2OJXRXCuaTIIxFxCbj%2FlCwM6Pxktph30ehd78axftu1kA5NPfFp2dRGHgn5QPAPeh%2F9ezM7VsV0qRa1Nig9JkKQTJlsqd2thh%2BTuxFVHC2MIYMeoCYjvEpUQjWcxiwIGIofy9JzlTbZ2Yf1vyJB0Ihb6I5gk3LHFeLJFZlBATYUISofNpMwqylSVWOZaD0EQZ3nsFnsBQCLet8gQROoEZnjghnmj57pPs1TN%2FOEDodPGX49iCJOyGjEFELEZL%2BnAppkdMIFCNSQoVfie6rEi2GP44K%2F5wLUgxAgxDJoBJSDOKAYljEWYT6ODsHanRnoO6GVAXHT0Mf6wCz%2BtC1YY%2FToQ%2F%2BrPFKLVcRB3qQIdRIs2KhqPhWABUphgB5Ih5Apnc1XNyV2VmYIe01UvBV6LLgqhS1FgDrtwPJpRgjB3guI4KLmRTi7hCf9Piva9QJ9Ip8jwR5Qf3VRKqmBdVNsTegy5xNapOAMo5Ynh4cqGbZKW%2FwqpNcyO1ptXkrSTw5XyVyXI%2BlopdaOj0ad1Vzs20qjPtVuLZQUPUWUg%2Bpl5p5E9cTjVEP4C15ghnnyHhZNiECbIAqEEwA2ityEW8Y0xd1d%2FXpbP3MQFC%2F4RqSsP4%2B8ZeO3J%2FHwJhx0HICCIME8zKiden6O8jNTPje6k38kyk%2BNw8%2FYw7gG1j26GQ0CZ3dPD0ySE9fUQNcxjmODnmyCIAwAVMiJrrYJecMHMwRQL5zAvCxPDGWfEGJK7MMAJpF9kUMtDKfmwnDqcn4nj351%2Bj3%2F7%2FNp38En8HXz69%2F%2FjP8o1mZcnlh59Fw23hr7c5xExrPcdprTZS57Wq0zX7m8mqhS7sPFmzcwfsPJOVtvtFO40VUwvUXzqW2kdQQdtNHXrJRKaRxv4pFgloTN6bG9fFWCtam5G6XeCasOkJJ9rlXWrsKRCgeLTSRWhMmNMwYV4KvpVZbiGbVK9mXo4yy2W1o4fzfLWwfb2ptD4ZEUczlVY4TWhsUtynofjXpLj3JEkYWA6tr%2F5pOgM2soTXW73omhR3%2FaWzHYgFGt%2FpSdTUGNMd93weG4o4O4pg2HLqmGuG%2FLdTBD0kRaiRGUMRhiKOhCJc18KoJkmt1RanxRDqeotJFKWGIc6QIaCDLcDq0D1minjFlRaGIwxHbHXIoWVDVcWfJklo1lTIWnYDoYANT5wdT1AL1bCLKG6u24aYWQBuLKDBDkoUasLMEIUhiiMhii3xJgjgNqvrqIhCrTiXEUX6EBmiOD%2BiYJYDakkJdNw80SHtanjC8MQxBp1OjSbUzHVWK2ucGpY4O5bIwk50PbS308Rh404mfW1o4mhpIos7AVXLnyhPqPnrotJre6VrvljVMnUEz5BAkIXsGj%2BUe4aUkHeZxdxqJidUEK8r8NHbnD34eqltU0jQ0EeXaFSNHpz2UghZGrk6rK6%2BPir2UHPbmZCJQUjMGp%2Fz4ojcyagjuwFsBLaRxEF9DPR6uW2GRphoSEJQBPNtQxKGJAofY91k89PiiFKwNGV6Ro0tJrSlePJqPUX9nXPjE1P6Zs%2FZktYE3aYbAyzQOAgwgOri6r5qFWofUQ3iLuLIV33zkdxqyrjm52h2MWQRp%2Babwx1dc53V1duyS1Pi3xhdx2t0AWgxXHNgTsQz1z6%2BGtbNF65%2BOUMz6qz5AboWrYO6mfpDTOKxdhgrqD5o5Y3XC92a2syGILZlQZgFSH3fuqb%2FICSl5UEcNUOoodswmgbjbMa5YYkzYwkGLFm9o3w1LZ8OJNFX7Fb%2FeK8XuzUsYVhi2zRCYrH6sqTmKvATI4k1W70Ygjg3goBE5q1rgDtuP8Js8mIo4ngpAhJmueunEJ4aR3SI6vZdchDR1tbZCEC4ZY9xXSaH7EEh6WumKn10ze9VlVQI6XIWXo7T6AVKoaahtPpBEd4jFUSk1hps1jftXqr0hfVBN2N%2FpyKG%2BJDIU9cLKrA7YfJTeE6L9jb53XPuzazQW%2BQXOVLsbyzH%2B8pofmwieTX5XdGyurqHveUXy3x9Ddvcn%2FLSDoni9C6ayv2V3lStw6rQK3ixmV%2F9wrtIQisfCp6mT8WYFtMtajJ0QuBbFX9dy%2BRJeY9btFHqxVO%2BCYqFkpKjtxGHMQ%2B9NLjnjbvYP66YwdVx4wqpuNLj78iA5Z4esMTYxE8f5a9b1Ck%2FfyruJvtw%2Fdj49FR8Oi9EdtV09r4BmZ16GcfeU%2B0LRUStuvIH2VAjcrWYPYZ1eCtnIJttPkP8kd9FJR6rx3m%2BxJT3eaISg4zE7CIxG%2FeVfW2RcVSRARtFBrt08xkvFpn4vXfPr%2BFfaPjN9%2Fl9PP8dswHusIMin%2FvilzOHbxx6SRKMmxBu7obwMglSvMZ8buIR491W8b5yxPhjkOayLYNM%2BedMti3bKT9X4i0%2FPNU%2BfOBxIMZX%2FmIl%2Fx%2FrHz619MYaVZF9al%2FtBfYUVIVRDy7SURi3pALKtt1kVhExgttC6bCWt5k%2Fe3HeBmklrH0p0s5X5L2jXGpXTUJs9abR5ntTzqDoAJrE1hXwIatYXEOlkG%2FLqDwwyFN3QkYBZIvHDJnl8SzYW4pV1VgKWK2pNte9tlok%2F%2BE1uyPvYhq8XLG9yDToahdAZ520%2FyB6FZQbzHhxWnLSak900XYTSNA24nqTkD8WX%2B2m8zaqsu06z%2B2o8wppHQguYGVKtF%2BjxFX0X7n50jpVopyBANigSqrzy1uKJpOEp60z9mO4dFkvUEAgS5Zs26Wpw4KqAmn50Sj2edze2uxH3OoJQp0katIpon2Y%2FdskabvUr1PgqtlDTRdDbrP6c0Iyeo7rMLvMWMsvtZahrDjVsJYZxXuzlml%2F1vKmGM7JGctQTjSAlLgMMMxaa8cG0GbIsrEYPfEN%2Be4%2Bz5CmtmOhdrCIoH5s6dVeg9VTbCFA9QzH2fWM0lfo1%2FrukMrte6KFy9zGtIrm7EY57cJR1LeNmls9QhXQhPalznGHTjNbPeY6ew3Pq1n%2B7KVq%2BWKakU6Tbgb0TrMnbKTZArI%2FAHWpFJJL3bqJJy%2FtjZ2FFMJsC%2FFK4JpSSlQLa5W5b0wgg331qTqr2MikfurTunk0m2felCGPcRwlyeDOyzqnKw5XgN9tY9beEKStKoLVBa5JsTu3%2BElhZuHHyyxYNJczzNc5jbPIX2ZRoHIaUcgn2VQxucP2fPou%2B5QPxNbJ7PlUomfW7NBOyXvOfFp90Y4jRDdkHT3OrXuN7x%2FWxVGnteuGZnNvoDPO97C3t%2F4JjkprbtBAx4k4nT69yV59gkhSMasbv01HSHhYqsEMKbIAUpEFKbX6ApdqJs8jnw%2BKqq9mvc%2BprPfZF2ybxS7aFciwYzmwVlSg2%2Bz6fSz30ZvO2zWjWe1jVvvsuNpnT6JkMwujtVUDXNeyaztCOkdTLlz79OpMEm%2BxGGSFAwxHnB1HgJeSRF9lA7QP%2BHrFxwxJGJLYJkvoB2IJtbSMQPosmpsKledIE47c1boCNm1VDkCq%2F3tQ3%2BEVq8mYopSGF7YVZhK0UKur4TQzOZDBugVGy7IXR8oLuEN5vzUJ7J4zZi5oZqibMyEw02TMiGOxOmGr3YrIHoJ1%2BPtkeEVuhvATfb%2F4B3uLv99%2FN%2Fmz58Z7JxNOxtr8mU%2FdEQAtbfSs%2FNkK5bvlzySe8CFBpKYTsjL8Jn12qumzmxtZw68F%2Bn2lz3ZA9UqnNg09XaJDlz%2FrT2t2oJ%2FXTKBV43ecmENgA%2BZ6gxGkTZ5FzSgTVVEloGeVwaZG%2BgzswYfQI0v1ePNy2xlYjLt7uu7u7njF9i5BUaLCt6%2BgqN4IeD3v1%2By1e2be7%2B6y5OCtQdGa17bG%2BdVIE1tNr9i%2FQKm%2BmejjRRBy32yKeHZk4G7JkGEBxE0AZgflAtUjPBQXmD0RDRdszZBJMqilk1GTDIhFUFvOXj8Oqhc0dbKdt1iYCRTnxg6QbaEHubdb7ajqK%2FRVVFsPWzPNzvDD8fKDu3kGheSHSrPbqiwdVaZMDSjd3v5xcYUuLoEJ0Z9uiL5au99DiH6H5ZSr2CpqLBRUHZDDrnCx1fmlPl%2BE0ZOC71Mt7GM5kF48ozbB6VWB2LS%2Bq0ttHxX0nev4FMqzXo5Bu4iwax3BQlqAhUk5M6DfKj7Qps3k2UCwG62LV5dTNpYE208dH%2FExjmR5rurr0hD6NfK5%2FMa%2F) for higher-quality visuals)

To sum it up:

✅ **Pros** : SPA on steroids (see `SPA` above) in terms of functionality, responsiveness, and speed.

❌ **Cons** : locks in the server language of choice; bigger, riskier deployments; considerably harder to maintain long-term.

### Progressive Web Apps

![img.png](https://costica.dev/posts/web-apps-my-mental-cheat-sheet/images/progressiveWebApp/tableSummary.png)We’ve seen how strong `SPA` & `SSR-SPA` are; we’ve also looked at how expensive they are.

What about Progressive Web Apps - PWA? What purpose do they serve?

While they have a lot of power and are quite flexible, I tend to think of PWAs as the “offline web engine”. With the help of a `service worker`, we can now intercept the network requests.

Consider how, no matter the type of app we discussed so far, there’s only one common need: to fetch some files from the internet. What if we remove this constraint?

> Well, we can now access web apps without the internet.

> > Wait, without internet?

> There’s a catch - you need to have that application `installed`.

Basically, if there’s a PWA you’re interacting with, the first time you load that app, you will be asked (ideally) if you want to install it.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g1cne0w1yfn8zlulwrg4.png)
(Click [here](https://viewer.diagrams.net/?highlight=0000ff&nav=1&title=PWA.drawio#R7V1bl6M2Ev4teeizT%2BZwBz92T09Pkp0kne3sSbJvGGSbNEYO4L7k168kEBdJGLAB4x7a58wYmav4qlT1Val0o33avX2JnP32J%2BiB4EaVvbcb7f5GVVXDWKL%2FcMt72qKpupa2bCLfS9uUouHJ%2FwdkjXLWevA9EFd2TCAMEn9fbXRhGAI3qbQ5UQRfq7utYVC96t7ZAK7hyXUCvvV330u2aattyEX798DfbOmVFTn7ZeW4z5sIHsLsejeq9kD%2B0p93Dj1Xtn%2B8dTz4WmrSPt9onyIIk%2FTb7u0TCHDn0m5Lj3uo%2BTW%2F7wiESZsDVn%2F%2BT3s%2F%2FDtyvf8sNcX74n1aPizU9CwvTnAA9DHMAJ3vzvNf0NcN%2FvrXIU7QToH%2FDEgPR%2BjfEEY7B5%2F%2ByQ83AW5%2FxB2tyrf7feC7TuLDMEabC3yEH5ET%2BGECIsfFP6GtVx91EHrZW3yUs9%2Fj784zwAcl%2Fg7Q%2B0APVLqVrCuTd%2Fr6UK%2Fu8VfUD04QgABuImeHdtyDCJ0EXY%2F97bH44e516yfgae%2B4%2BAyvCOCobZvsArSloK9r%2Fw1QxOLtwFmB4C5%2F7Z9gAPHpPbB2DuRet467PUTgCz7RvY4a4iSCz4DuiBCysg0dQQudG4bJg7PzAyw3t5GL78RN8MPfOweENnJ%2FeKcneIjI%2FW2TBImEami36B%2F0lvE%2FeIdY2kCIXoGz92PJhTvygxuTXR%2FW6SXQ18pFDPWOvUz2mCp57iCg9xzCELXfvYAoQW81uA38TYiaE4j7Kn4GibvNesc9RC%2FgwU8SBIis6S9%2FsyEvCp%2BV9BnAYMTPn0uDnL%2FVMpQzdOPLgrdSUwbtLwCidxihB5OzXxe6nclZpogWSq5iXgu5VrRl1rgtCfXSyhqdTJls8vMXAoW%2BZDIlli%2F1y8L7XVO2z19l%2BDO8%2FfXwo%2Fn3YimQLwbBGEz79j2Qa0JnRc8gi3uGdoRh8f2g6QbfDeqyh24QqxmRnmnXD0e79fTOoUdpBtc3OW5G6hutVgdjwSTPRPWH%2BfcBpmpQs2X8KTelGnKFh0Qk1oX6TM9Soz8LqVSaFWKjAqwoBE4bVtSBQF1MVScatQqQh%2Btx%2BLdXZwoVUCrFukCIDQFQNW0woOpNQC1wRVGJf1jEpB%2FRK5IVdf%2BWYpVB7X%2BRKYDuSv7ReXFiN%2FL3yXc3WHTT06%2BiAr8zrPuE9YAA1hgAq7ymVVQBgM3B8Gtw%2BI0O2BL1kxk%2Fk8ePogmsuXHxY55sxHTrlO5WDNNVgp4yBT2l2IN1lVU7VFScuWYz5%2BHBlmWBmRMjfKYQrhkQxN5jr%2FfQYXjq5MsedsED8lRBs%2BbhdMlUdYWWbZdcYU1bLh8e8DNmMNVk7AvmANXkfvzOttJo1kgjL3UXlCu7wQRLkfUzTLa4N1oaS%2BjC%2Fj7%2B4HD7TD4Mu4Ha1wb%2BiLiazyb%2BsFzFJnI8HxSnzgiSC0My%2B5U6BNlAIHD8LQFeqavRO1wtRQBXFnzeBjxlmzBKtnADQyf4XLTeVW2x82yp4gpfIVYl6bsBSfKeQcc5JLAKevDmJ3%2Fgly8Z2dafpV%2Fu3zJckI33bIPDkkz%2BJiwxBi8xGcOAHi30bjHTXqC9o4UT02dpMs0xGFpZh7Iky4ZVdTCoFRSBwEn8lyq%2FL8J2dvpH6JOxn57bqlpTKksOJk60AUl2VJlwpyeiO8L1OgY1%2B9RcTGFpprTruIsRccz75XQJ1XhDjbD0%2Bwjf%2BCdiEe32Pib48QbcJ%2F4OI4ZsIUEsfZk9qJ48qE6MZy3ta1zaXdLMb0PXo%2FcWvZcOwpt%2Fln8rDiNb1ztGqEfGiG4wbhwQqF5KdW0fI0frUeE80NvfBuhn8B7DpN4SvBTlEwFvC2t9UuH28ySFg7CtrjTTnDqEm2PzK5gkcCeEdfewuiFXXcqFKuJhhVF1s4%2BoulhuTlCyBAEX07Ec2O7IZ8Jgs3l9met4z4m3eV%2FijUcnQWfA4EPjn2xXrSLCxuRmEXbd1NxQqrGNyFZJdRzPEmlUyGZrhaxPSiGLAq7CgAPPaq2B6boc8Pohq85PTaHaRbMY7ZK7KCXtItQtQ6kWPkbYqstpxw7Q20eRcforuFQHtwii7SHhID6%2FoD6IqQItc7C5%2FpEbtKzp2mC15sXDc4C9dqmN8QhjnyQlavcuCFNVSAfVr8wO%2BeAqjkw42VZ%2BHnhIAj9E90SzV7PkN2JF7d42OKtWegHA2UmBs09Pci00uyoPhG6jBt21ikSvqhGFTzUQpsoMhXGeVEMoQe%2FlSMDv1k3gGbgrCYEQcVcFKcbseHi4wymM4yrSWqgJBihtTP3JRwB%2FCOMEOVxOmlfNQAw9VVLFB6eiWETtfM9LeQkQ%2B%2F9kAwnuf6KXyfMYdzfGPT4XMnTjwmMTDn%2BCYbJsZy67gFHkvA9kzBzJNGa0zUJf4nBE8afwDpIopVQfCiJ80vFjhJxxEMfYYlXl38HqhiTqox42nR3WH%2BEqTvMZ5RYIavua2yNNxAxU88WvSoFdHpKGgP5XDUHO92A%2BOkX8RVLf2exu2i22LSAvbIFs5rN8%2Bu8XEcs2p0bNqVHTTY3KRblbatTIcqXWytWcGvXhUqM6QJKmRlWHAp13EUdNjVL4WT%2F8%2BDj90GHB8spyheaVJYTBmxNY3uuLLB5Lnao1bho5a2onNHLWyim5U7ZekQaqPLulTt1GkfNe2iHzD4uLM8lOumkz5pjGTFluOkBRsjstRC%2B9idYZWH0lTimtufnhzFtTldnuEWR8KiLqazjuS%2BEZdPRYCXr6hQcChC3yBDFA6ieqNfPcw6rFmLtKld%2FXVd6QB4t%2FSUmwGxqiip5%2FQafxk%2FdUVxnVRpW08q5tEWpur3sypWDySkGWrQdi1ZWH2eISdaMnHWGV8bRbpxH7rJmRSnv%2B7YKQ5mMWT4%2Bo01Gz9nab0iYrBLqgnuHdQe8QlDmRAKyJr4YBGG6%2Bkq2UPGhkTTJDv2x5tU%2BVEHIplfeJ0UmNjhgGuGfq0ydoyQy1k4xcPJKdua1DwDSPSEiKrluaaevI6THU6kCGWiT7OGVom1J2qKkphrXkAW8YkjoU4kXzty5N3lgC6n1sJ7N%2B%2Fs1M3szkzSTJG6tGICdF3ojqpMzkzUclb9pDcprkDR2ISnA9JSXx0uRNnvcty%2FpNkfktS4ZGt2umPKCNj83b5MSWIskKQ2xpmnUKsVVrKjVTQRmOm6mgzDzpL32xhpdhw40m63vVzJHryhiZ9N5yhkNeHqeMuHzl7keYtsloiBLH1Bd%2FpPJhQP0KVQgVE5LVq1flxLBPSvP9WIrkDKm320p971OgTpJVw2TlyGoQPPYARc5cvmElj7c1jSuUvNrB29Ib5it%2B%2BMF7hJGW2ntDj7R51SOumGPfIy0%2FbsrHxZc7wqjK%2BzDSq%2FGmNye8eYJ%2BCS9HcXE%2BWWVwFpHMk1VCH2WwOVItZvM1uMVsmvrKiX1X8qB72JEe%2FJiz8tUOvHCOxva8sKRZLb3XwZChcshw9nvpr5jDx9STh%2B0uKKpQdPivFwCPgM3BsKjIkiovl6qefyo6DJsWaulPVgVhCl2AXHUw5IpK5Y4cltAs0i9W8akqfmvJK37FXErLZekQje%2B04chVTZSq0FPd1nMqFefJ50GuZGhL9rtc3WUFvXd2l6NxCT6AsRJfnEQvaC%2FS%2ByQ16Us3fezW8giI%2BOZWzXd2xqvoHN0p3XhabBdfOHLZpydDQl0HdOz40wDC97IIA%2FxeIjA1RbCOhhJmS%2BlcS0mrUcC1ilasMhtrLw6nRvnEJj%2F0wJuUgm02na7YdGoPzpJtpJX%2BZE2mUa0SQkUAHc44uuRaE%2FQoLiNRVIZs3NgytVDnnI05Z4MozOnnbOSiPOWcDb1hIlsLU9Zu51WcciKx9GS0NnfBr9Dx0CuTJOk8qZn6qK%2BcOuyLZ1tf%2B7DfXswoe8fkobQrVjMYk0cJm5IIfiNFNz9WwKpcQlTO4%2BppOE9WTpxG5URJY9XmtnOMKIKnUJ9ZYYqcLzTWpO6zQDMbo9bY8XTgAs06T3nSYOY1iXg5TySNVxcI1%2B2T8qmuTwUcK6lXK5vNxe1ayjCdUNhJhk2tAn8qacNmkixYCVcbMkm4A%2Bws%2BnnxaYI6z71npaDkGJC1TmN8jXJWc%2BHBOejnILVM8Y5uBEBITNRrE3%2B%2BLhv5m7CoqkdEtS7RukVVzNOl%2FIQRWDXtqvTms%2BbPXSFB5dZaVfobgnsTvdalHIfjw0w2fUcVpIUoouj%2FgE4DP5vx9vGHm3lO7jwnlxGcbuzTyCjmZyjCLV4z9EAWv5W5gO8f4nAs0oV%2FH0CcpGOsH67hjaAGWh%2BLmYgm1JxftHzyI6mgoGMeQ6obSfsHKk3eWEpI5i1zmf1L6ZIja6YolpTvjv%2B1eZQPB3J%2BuukaQwofRxfILZjMKt4zM1OYglCwpKKwwYz9bxH7imjV0IuCf8lBcfKOzkXXD8rpxKmKQ7ec%2FaOwb%2FaX2i4gpPc%2BZ%2B68%2BvN8tDoCySEKK9qeKvdckV%2BNzl6aluZMXmdXdTNQPANYl9TNorKll9TNxjVy0LNunopubjuz0WhLeo2km%2Flwq3WFclCOxShWBdaSapkN0P4gsRgB3vN7pppCkWRZKekKWdJk9bi%2BEMyt5KWnK%2BfbbMOYLeUkG27Qi9etagXITCTPZYaZpXOrxw%2FH9RoTmBgiWrpo5JQso36mx5zqOKc6Ei2Xr6YyjVTHXHKnnOpoiEJJzQC%2Bv7u%2FM%2BxBJz6VZYA5aM%2Bd9Hs%2FXa67zb3XZUqytGJZ3r7j7gHtwN1G440PMcuHEfnJ52l2WhlSZMMIVdTUwlT96wi6SFPVDtH4GdfKqIs2GXzM9QrZzY9l5Z9ul1Mzq9Eu72yWq%2FlNFAkD%2FRjmCpeywY6WPRUSWSjL6pWMhtwtdv9FtV7X5XK3DD7EfMWruxcVunJv1tY6O7Plunh5XnJ6NtPM6%2BR9u9TBGc5%2B2zxOqn0uXO6LK%2F9TTbkUrOXAZVJ32t8coSifISrvPDKNoDMpY6Ll1kWrCQ5nuzTV5m0xP8uomeh1zJvgen6eg3%2FmHPwc3t187VHRRk98BtraTgasKzuBHLw9DGNAuvQdJ2B%2FFLdynvR%2FmjTQIm9Vu5bTy6K5f4NN9zf56bfJlswrwBRmW5KHZL9yEvCUZQLLtcBnSRzXwQkKHk6eXEHUH4RnevXxN0GOWXqjEeklnHec4BFVyAs1ChhnPt6Rj1gU%2BlyQtv2SKx9puBHNYcp7vDIBor2JVCtvlsKYjLqotpZI6vI5gv2LHW8RNruAl2dqCqm4Hlxx8VhZ0pfLigdbxGfbu7AtpumQl0B3KXJAqv5uU3HrEVxBOgYMXYXWYskjvWW9974cMzoNcZa68aSuq5ycjvfWVZdHwztLSepsJl1fVZfrLjQozWHyaQJkPTtkv4E4%2FBe%2BP6Q4Y8Ky4n%2FWfkQ2FkJjzsc%2F%2BRjLMAzIw2NTEOz2Cd4ggffpuEkNBmIfpVLy81ftxcpiOxXZGsGSvIjX1dneW2isOCiiWQmqaPXHwQgJawKcIFtWbQJV1ax6VnBONZpTjYgmnFiqkXUa%2FTmuXNGrleTqhzBOHHKks98HqK8SH6KeemhHkEyLgZwTW05EpDixRTQOiBJbBlsa2eZZSIVHZZcg%2BflF5k723OhixlPm3wQ1DHpY98Zo64HRYX8iMzLsU9i4GWtDYm1o33yhsawwa%2Fo31p6psapVhVkvdODSbrQ6T1l3iufVfcUe4nDDOhtOPmV87jpZjEru%2Bc4RrnSkW9UJk4vsVKdibfjkMls0VePCbqUqCq%2BMbP7WZ9rPbuXsVk7RrcwledJuJZ%2BA%2FtvWCZ%2Bx8MPDd7MfedV%2BZAcIigtZC%2FxIUVh9MDfSUjl4cpAsYZFCj9hFjwhKKSNyv4JJgt6JAKw1HDsuvEP%2B6jVGxVpXObSiM3jWciXXU%2FzZL5XcRB%2FGluSj4TqWkH2B3358tisyUQ2uCgpqrNfAdN0h8c0WibZ4gI%2FLk%2FBzCZQr9F1L9TC4Ms7mGZUDPqw33Mi8tC1TZE9jke%2BFxgiWpo%2BQl2%2FzMbjfSAohWaIvDT6HSPOWSyT5KWuOZKWcCIxD2Gn2YTv7fbnEa0NxPgSIXtIizq8wesaZkjXWuxwdQnxz6GZ8D%2BTXXkXwNRaUWp1%2BemN2patxH1qnK55plnWOdesW43sLCgOrdIGScVIb7VOmpM706UkDRiVzqr5aVAWiRRqkaZRLWMmSYdG0yDHK0lBjvXnMGqu0HtqMINbQxaCDzeyfoIdp08%2F%2FBw%3D%3D) for higher-quality visuals)

While it looks 99% the same as for the SPA, take a look at the final pieces: 10 & 11. The app notices that it is, in fact, a PWA, not a simple SPA. It asks Alice if she’s ok with installing it. 12 - Alice gives her consent - the `service worker` is now registered, and the app is installed.

With an installed app & **no internet connection** , if Alice tries to use the same app, this is a rough look at what will happen under the hood: the service worker will pretend he is both the API & and Content Delivery Server.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3yxzz785mtbqcu16ky6m.png)
(Click [here](https://viewer.diagrams.net/?highlight=0000ff&nav=1&title=PWA.drawio#R7V1Zk5u4Fv4t8%2BBHUwixPqbT7WRudSaZSt0sT1MYsE2CjQO4l%2Fn1IwHCaAGEbdx2h3ZVYmSExOE7%2B5GYwLfrp3eJu119iP0gmmiq%2FzSBtxNNg7rqoP9wy3PRogEdFi3LJPSLNrBv%2BBz%2BG5SNatm6C%2F0gpU7M4jjKwi3d6MWbTeBlVJubJPEjfdoijuhRt%2B4y4Bo%2Be27Et34N%2FWxVtNqGum9%2FH4TLFRkZqOUva5ecXDakK9ePH2tN8G4C3yZxnBXf1k9vgwhTj9Cl6Ddr%2BLWaWBJsMpkOU3v3Z5TF7q%2Bv93dx6Oz%2Bmv94mpZXeXCjXXnDHxeLKNwE%2BA7Q0yynnj0TemTBExrtZpWtI9QA0Fc3Cpcb9N1D8wgS1PAQJFmIKPim%2FGEd%2Bj7ufpMEafivO88vpaLjbRxusvz5GDcT4xZfa5fFaYEBfOk0S%2BKfwds4itF1bzfxBl9lEUYR2xRvshI6wCmPZ%2B46jDDq3iTeKswQNlJ0J7fuDj2rfJr4JHKdiQZtFX%2FwoD%2BDzFuVM%2FB2yUMwC7Ms3CzLph%2FhcpnfAnqCN%2FxDIBRFRAieak3lQ3kXxOsgS57RKeWvU2CYJURKJplqpqqotb%2Fymo97AAK97LKqgY%2B0uSXml9VYe1igLyUyeqBE41DyKYmX6HGm4QNGytdgjv59s0U8qZnueosIs5mn25w%2BqgSEZJ%2BzPNQe8SP%2FvHU9POYjkk0YfvFu4wd%2BCb6V6612SfAO%2F3Sr9wHN53iX5NddZRm%2BYwO%2BQf8gAuN%2F8AmpsoxjhBF3G6aKF6%2FzH7w0P3W2KIZAX6lBDO2GHaYAtHYhmIRE5NVQqBkGj0JrKBRCDoVpgCiRcABDknaLv3q7eRMWauCbF7C4n1cNrvdzmYPl4y7LZWHR7rvJz4%2FoMmGGaYI41KAbtbyVx7MfLNxdlPWCWCnMbF5Oqao1m80Y%2FtgPsUxcPwz2PUrOqZQPOB%2BIzw9ah8WsyWMWQIHkBIOBVudAi0RkBYbccCGP1vy1w7YAIgWczRwHwnqTucT%2FIysnQwSaIjMLSd785snl5gk5iXBF0T4pHif5cWSWkVkK3rBfnDcMAW8w6MTQ2jLPDz3XxSIwPa%2FJchiIlpWTUZqwlB3foEU1WiIBgUByBDQ3hyK5eRjJCWEHoHYrMg5%2FBC9FYKubwLnbEyR3D0Hh%2FYC6yFFzMZmu9nZqk5mM2MD07GC%2B4NnDdwN7gdkjcudB9Am5VFkYCw3ne%2BaEeZxlSHzxlnUWb0UGeFwI%2FbeV960WN5OrlPXTEkcFlIcgcNdK5G6Li%2FxOlncrE0oLa52RIgYnRAwBxuFQGLc5jCOUeHysgOBgt47eeFl8BO5qTCBE3FVBirFRZrMbwxoKak2CtBFqGq%2BgREbBYPLT6ZafwcZ%2FgyN7exVUgwft5FckFYKEIqiA4Jy8LaIx1S8kIGhcLuCA2RLpYrSG6arqYtFmEgU%2BFSxt1boiiUTakiByMxw6oqK1AiiVI3zCGrNmV7HBCQgYOKY5kctu9ZgocyWLcRht1tbN3GQZZNyFcmhX9y2FduPDJ3%2F3zgn%2BCQ347fGf7%2F%2FGHyPCnnVwIxJ%2FLg%2FjJFvFy3jjRnf71hrCwdEI349wH2NBW8iZIMueS%2FzggGyHEdLAFOC6mKK6C4T55PkbPktB3iNp%2BI4prBgGIA23TyXNi6Pn%2BtGnIAkRMvCwReNTmJVXzIfGx%2BUFdVAe76%2BHD55rB%2BzVDufOI9nOUBXNcqo%2FSzdo5tFsqOjm%2FgRbipWQKHefa6eVSYHGWQCD5llNb%2BVw9nQ8S4aTixkcytfR31kK1w9f%2FV%2Fql%2FvnP4Nvzoe%2FBWmVBjdrSOcTmMwDgqqlOGYtr6Dzul4XRHQrD%2BoYbS%2BkE59YkKVTK9mPJh6AvIldpSTPQxo%2B2i0TOCx1Oxc4nONMqHxQkNYxHTHB3Mm8qeKAfJiNMmx766hLVSJGo7ciiVatAa0tLM2KXF1grQtdwVP4gsKb6Ixv71FFMIl%2FmBZZXvSAVKBtnwqkMpj9%2F2qioUmp%2F3Mf3NRLwm32hzDePYL6tKAeDr6QtRh4KQu0gbxN4T3wEehkt8GdshE9l46eKlnxYuiRDqYfR5L%2B1gtDKAGdTIGZB2y66kSFA9FNFCMvRLgfPrBSvT1NamOnjdMcKYJqgeYGzVA1CwY80Rx66CnxbJqDqbPEXUvkaq8lKAog745D6Dh54paAFubOeQVXqDZaX0eGUVs5vVtaUUwmyqbaQ0kjPipPw7fA1V9xtsK0kLSZ0LjhNn3lYLvLP3xAdGHgjyjmdWfiz4TJ2zWVE7woIKvgDaUTLF4nWAK0En%2FjGLD%2B%2Br76Mn20vt79ClZ29CVavf%2FhyIT5a%2BDqzBpxeckGAywvHcB%2FzdKDCmJqoofvW85cVdmHTyVt2QxoGKeWEiI1nippkD%2F79LUagZogs1CVawyFbqCxtmFnpEtYQKsp5MyTi2dihdUgn5cBbJMgK%2FxcRPltiJ54fhBvs3CNKZofIZzUvoyeyZCeiXwp1TMtWl%2FMDwGA19uHppEOeuoHpJFITkRVjMk%2BI9KRDSGpmbJTlZiZtCdlmlNWlwpXjTdSqqxtPxinZOJdcqlIz7ScWErY02WZjsM8bzC8SsyP2G05T5eELsH4pWBXlNs5e3pQhbRLMDUBNpo4XaapIjcWiA2s09OqOcEwBovGYNElBosq9u4XLbJFbKYOZjOKiu%2FHcNErDRf1gCSJF9EOtc5n6s4aL5Ioqx%2FjRVfpmp8iXtQf3oCpIDUZc4ZfcX32eBGfXbxGl2fvsgPoUE67AnS7w3EXVlNen0dE6sPlPCJpx13W%2B4Gy3g9xDXAa2NYp%2FiDudr8S0r61nVPTsWifxDDtOidJ9CBbczT20G27tQddEbrvT24iXizSoL2sfGroumIYe3GiiUccoMxcDBUJ9fkCDqdudEbpgWjxHgBnKlQAzTnV0fkcnc%2BLdD6tBoa9KOdTlP4dnc%2FX6nzKQ%2FIynU%2BRFhidz9H5PBTe7Jok1vl8%2BWIFkr6uQR5en%2FP5ujzF%2BsLEXDPUXGkIq5WKfVzpw51PKJs1Jib00IsTp5bGrnZrYKsTr0ecmuwyO1vr8lnZHjq9iLHJA615l%2ByIcuufT%2BVPVl7hXjzoo3i42kCSLcnL0oGkoaNEKrcMrovj2B6W1bIKWMRxtiIQJbWrKbq6X%2FnsSEmak3GjxnHjCfcVGLnxvNworVnhmRQrUNlle03ryE%2BtWQ1WT1qwg8%2B5HpCWDBKaVYE1PjbZ8S3FgFxY91xaV7psiMZpKx5PENg1Ocuru%2Fpa6L8PtsuAqIaIIVxHyIj1keduGnqKH3u7dU7RV%2Bwe89BpR6f8rmYKtCQjO4Mhg6%2BCcbdb5UfK4ePS9z23%2B6CICl%2Fjv5MA%2BAzYHAyLQFU0ZMBpevWhRBrON2m1P1WTrBBgHbPTIffwxcenk%2FyWoyuOY2nVh9YDhiYsKAWmQ%2FeCPN2Gyz1ozauPj96x4pgdWqqd86NKzpCW8neVPmUe%2B8%2FsKa1pOz6%2FNxcPnif3CBXJPJFcpCbdNrUqQSie3Lx7Zkc8it7Jz9rEi21G8MCJx959rhWaCNCT8IcBhKeyCAP8WSIwdSV4WzNto7F0rLHUe4WjWGR2rjYfTozySbFw4wdPSgG20Xq6YutJHpw18wjW%2FlSokqxYDaEigA5nH%2FElBte4SpLkfPKaPH1CJX10%2B6Ckz%2FUF2oQvdijn3Gje1gNtbTu1d2ewyuhBr%2FJJE1KmMIH5wIFxoBtsLqrOSIIO7F5B%2FTsYpsMw69HVk0Bn9uUFhqWounqGwJuw%2FoOUl4%2Fb9F7ONr0p4tuMbAPuRW6KTEzSPAsjQgYp8SAdhxejQ5OUD%2BdZXAr50g0OvWO10vV6GPLVSv3fCcS%2BrmZqC14SJHwfgMbuwH6y4ruL2EpZtWnCCLZPaqhU1xS1nlByBqKSJqDSWKg%2BFqpfRKF6K19fSJ26cI6ihGsN0RLhSVsuUnzIhcS8UxpI3ID3seujB6YoynE8c%2BmRHHBoKEf8%2Ft%2FrCeUcyWQkJ8tU3vN6TqTmTpGfFc9%2FNGZHY%2FaE8GYr7wV23ICl9sJ7kKhNOb99K3oNGHBEe0afy8Bt3q5kNHBHAzeXHtWL9C7DwNUb2POSDFxREUk3fG9vbm8Me9AShjoHMJ223EXfh8XmqDJzb7KPyzdYCrntD24O6ARuGp0THyJff23WOWHbvtZ5FfcVCqjLfz%2F3kRKCvJyTts4FL6kSvsH7FBvPiu0vieDcaJ7%2FtuZ5b3wDJn0peFv6uVfC8mUEJgfxyy8j%2BC02nm1fPMu%2BM7i%2BmbRqTmqVFTiBX5VanGc5bQn7zlyjbKqxXopgMFW5JIF%2F9LogwC6qY5d9QJO%2BaMO6oAOLBLjhu%2FakbagS6F9lwY6sdew45dhOy%2FmTY99A2pqV7mnaz2aOA6GMZ%2Bput8hkdnMVrqlRjFRwLhXjxF0GImtYzoIlKtfbzSXc1XkhV%2B%2FnVUNlK3ws3hNftvtu8vMjukyY5RysqAbdqOWtvFW7fy%2BCvNRrq1qyZnkKpq5Y90M07clC7JMzxpePNHf7p541LvUsUP5C6xaw7%2Bw%2BnXnLx%2Bas0yn%2Fc1UCUVswTqgKQts4cQXhK6wtIkxYKyyS1vVtOvx6Vts7NGeCLnXHdiBvqW1etcttDNi3g2lb7T10dk5Mj4GUMB9fc65PgIzsfgy7C0z7tnLk81cRipHL51vs60NuXfU5rO6rdiMeVV%2FvsloSUMBbUTm1kALypTWrNayAD1iiipxzfyjmu2hdazCF7xq9TU13h07lzJXW9%2B2A1HvL1jndmhMdJjH2Lfen49jqh9gP8Bn%2FAQ%3D%3D) for higher-quality visuals)


For the deployment & delivery, we have the usual build system where we `build` some static files into a `bundle`:

 ![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jicc85j6ak8s7b9poe2a.png)

But we also have an extra step, an interesting detail: the deployment is no longer a dev-only process. It is noticeable by the user. It can even be allowed & delayed by the user if the app is set to take into account the user’s choice on the matter:

 ![image](https://costica.dev/posts/web-apps-my-mental-cheat-sheet/images/progressiveWebApp/PWA-Optional-update.svg)

I know most people would disagree with my `complexity` score, especially for the SSR vs PWA. Hear me out, though:

- I am reasoning about PWAs as a non-SSR-SPA with offline capabilities. While I am aware that you can do an `SSR-PWA`, I think it is out of the question how many needs that covers: basically all. But, the complexity score goes to the roof.

- The SSR locks you in and **couples** the frontend with the backend very tightly. We know how that goes in the long term.

- While PWA is complex to set up & understand… once you get the hang of it and have a working setup, it tends to just work. A lot of things are handled automagically by the service workers.

- For the PWA you can opt-in & opt-out of various settings pretty much any time you want. The only risky thing is to mess up the `service worker`’s self-cache/update mechanism. Then you’re kinda screwed. SSR, on the other hand, is an **all-or-nothing** kind of setup.

✅ **Pros** : has the same capabilities as a normal SPA + it works when there is no internet connection or an intermittent one, and a lot of extra functionalities that can be configured on a per-need basis.

❌ **Cons** : complicated to set up initially, requires a more thoughtful approach - your web app is now susceptible to “the fallacies of distributed systems”.

### WASM

![img.png](https://costica.dev/posts/web-apps-my-mental-cheat-sheet/images/wasm/tableSummary.png)

Delivered as `static html`, with a bunch of `js` for integrations… and 100.000 other things behind the scenes.

WASM apps deserve a lot more in-depth dive than what I can do in a high-level overview here. Sorry, but I will skip this one for now - I need more knowledge on the matter before I can summarise it as I did for the other types of apps.

## Necessary disclaimer

This is my mental model that helps me reason about things. It is in no way a comprehensive guide to all things possible in the _web apps_ world.

However, in my experience, understanding these gets me through my workday quite easily, as I can expand on my knowledge of these basic concepts and then build upon them:

- maybe some parts of an SSR SPA would have client-side hydration - for some reason.
- or maybe we deploy a static blog with comments from a database embedded at build time: the new comments won’t show up until we rebuild & redeploy the website altogether.

The possibilities are endless.

## Closing notes

❗For web dev to really make sense, look at the whole lifecycle of an app, from how long it takes to create a new `<div>`, all the way to how users (or web crawlers) will interact with your app.

❗ Understanding all the trade-offs between the type of software that can be run in a browser brings tenfold rewards: you can now do almost anything, on all platforms.

❗I was often able to reduce the challenge into a frontend/backend problem once I was able to understand the requirements: how do users expect to interact with the app and what features must the app support.

❗Understanding trade-offs doesn’t mean only “SPA or PWA with React or Angular - which one is best for my needs”. It means understanding how your app will scale in time: how complex & expensive it will be to develop and, most importantly… **deliver it**.


Dev.to community, if you've made it this far: please let me know if you have any feedback on the topic, if the pictures & visuals links are visible enough; also, if there's interest, I can go in-depth on certain topics - all you need to to is ask :)