Learning from React - part 6
Tags: programming, react, net, essay
Published: 2021-06-16 20:13:55

---
title: Learning from React - part 6
published: true
date: 2021-06-15 20:25:37 UTC
tags: programming,react,net,essay
canonical_url: https://siderite.dev/blog/learning-from-react---part-6/
---

Original post at: https://siderite.dev/blog/learning-from-react---part-6/

Learning from React series:

- [Part 1](/blog/learning-from-react---part-1/ "Learning from React - part 1") - why examining React is useful even if you won't end up using it
- [Part 2](/blog/learning-from-react---part-2/ "Learning from React - part 2") - what Facebook wanted to do with React and how to get a grasp on it
- [Part 3](/blog/learning-from-react---part-3/ "Learning from React - part 3") - what is Reactive Programming all about?
- [Part 4](/blog/learning-from-react---part-4/ "Learning from React - part 4") - is React functional programming?
- [Part 5](/blog/learning-from-react---part-5/ "Learning from React - part 5") - Typescript, for better and for worse
- [Part 6](/blog/learning-from-react---part-6/ "Learning from React - part 6") (this one) - Single Page Applications are not where they wanted to be

We cannot discuss React without talking about [Single Page Applications](https://en.wikipedia.org/wiki/Single-page_application "a web application or website that interacts with the user by dynamically rewriting the current web page with new data from the web server, instead of the default method of a web browser loading entire new pages. The goal is faster transitions that make the website feel more like a native app."), even if one can make a React based web site that isn't a SPA and SPAs that don't use a framework or library. What are SPAs? Let's start with what they are not.

_SPAs are not parallax background, infinite scroll pages where random flashy things jump at you from the top and bottom and the sides like in a bloody ghost train ride! If you ever considered doing that, this is my personal plea for you to stop. For the love of all that is decent, don't do it!_

SPAs are desktop applications for the web. They attempt to push the responsive, high precision actions, high CPU usage and fancy graphics to the client while maintaining the core essentials on the server, like security and sensitive data, while trying to assert full control over the interface and execution flow. In case connectivity fails, the cached data allows the app to [work just fine offline](https://blog.bitsrc.io/building-an-offline-first-web-app-with-react-and-firebase-d3bdcda8f1d8 "Building an Offline-First Web App with create-react-app") until you reconnect or you need uncached data. And with React (or Angular and others), SPAs encapsulate UI in components, just like Windows Forms.

You know who tried (and continues to try) to make Windows Forms on the web? Microsoft. They started with ASP.Net Web Forms, which turned into ASP.Net MVC, which turned into ASP.Net Web API for a while, then turned to [Blazor](https://dotnet.microsoft.com/apps/aspnet/web-apps/blazor "Build client web apps with C#"). At their heart, all of these are attempts to develop web applications like one would desktop applications.

And when they tried to push server side development models to the web they failed. They might succeed in the future and I wish them all the luck, but I doubt Microsoft will make it without acknowledging the need to put web technologies first and give developers full and direct access to the browser resources.

Ironically, SPAs (and modern web development in general) put web technologies first to a degree that makes them take over functionality already existing in the browser, like location management, URL handling and rendering components, but ignore server technologies.

It is relevant to make the comparison between SPAs and desktop applications because no matter how much they change browsers to accommodate this programming style, there are fundamental differences between the web and local systems.

For one, the way people have traditionally been trained to work on the web is radically different from how modern web development is taught.

Remember [Progressive Enhancement](https://en.wikipedia.org/wiki/Progressive_enhancement "a strategy in web design that puts emphasis on web content first. This strategy involves separating the presentation semantics from the content, with presentation being implemented in one or more optional layers, activated based on aspects of the browser or Internet connection of the user")? It was all about serving as much of the client facing, relevant content to the browser first, then enhancing the page with Javascript and CSS. It started from the idea that Javascript is slow and might not be enabled. Imagine that in 2021! When first visiting a page you don't want to keep the users waiting for all the fancy stuff to load before they can do anything. And [SEO](https://en.wikipedia.org/wiki/Search_engine_optimization "the process of improving the quality and quantity of website traffic to a website or a web page from search engines"), even if nowadays the search engine(s?) know how to execute Javascript to get the content as a user would, still cares a lot about the first load experience.

Purely client tools like React, Angular, Vue, etc cannot help with that. All they can do is optimize the Javascript render performance and hope for the best. There are solutions cropping up: check out [SSR](https://www.educative.io/edpresso/what-is-server-side-rendering "What is server-side rendering?") and [ReactDomServer](https://reactjs.org/docs/react-dom-server.html "enables you to render components to static markup. Typically, it’s used on a Node server") and [React Server Components](https://blog.bitsrc.io/react-server-components-1ca621ac2519 "React Server Components — It’s not server-side rendering."). Or [Astro](https://astro.build/blog/introducing-astro "Introducing Astro: Ship Less JavaScript"). Or even Blazor. The takeaway here is that a little bit of server might go a long way without compromising the purity of the browser based solution.

Remember jQuery and before? The whole idea back then was to access the [DOM](https://en.wikipedia.org/wiki/Document_Object_Model " a cross-platform and language-independent interface that treats an XML or HTML document as a tree structure wherein each node is an object representing a part of the document. ") as a singular UI store and select or make changes to any element on the entire page. Styling works the same way. Remember [CSS Zen Garden](http://www.csszengarden.com/ "The Beauty of CSS Design")? You change one global CSS file and your website looks and feels completely different. Of course, that comes with horrid things like CSS rule precedence or [!important](https://www.w3schools.com/css/css_important.asp "What is !important?") [Shudder], yet treating the page as a landscape that one can explore and change at will is a specifically browser mindset. I wasn't even considering the possibility when I was doing Windows Forms.

In React, when I was thinking of a way to add help icons to existing controls via a small script, the React gurus told me to not break encapsulation. That was "not the way". Well, great, Mandalorian! That's how you work a lot more to get to the same thing we have done for years before your way was even invented! In the end I had to work out wrapper elements that I had to manually add to each form control I wanted to enhance.

In the same app I used Material Design components, which I thought only needed a theme to change the way they look and feel, only to learn that React controls have to be individually styled and that the theme itself controls very few things. Even if there is support for theming, if you want to significantly change the visuals and behaviour you will have to create your own controls that take what they need (much more than what Material UI controls do) from the theme provider.

A local desktop application is supposed to take most of the resources that are available to it. You can talk about multitasking all you want, but normal people focus on one complex application at a time. At its core a SPA is still a browser tab, using one thread. That means even with the great performance of React, you still get only one eighth (or something, based on the number of processors) from the total computer resources. There are ways of making an application use multiple threads, but that is not baked in React either. Check out [Neo.js](https://betterprogramming.pub/create-blazing-fast-multithreading-user-interfaces-outside-of-nodejs-c4199b0023ec "Create Blazing Fast Multi-Threading User Interfaces Outside Node.js") for an attempt to do just that.

You can't go too far in the other direction either. Web user experience is opening many tabs and switching from one to the other, refreshing and closing and opening others and even closing the browser with all the tabs open or restoring an entire group of bookmarks at once. And while we are at the subject of URLs and bookmarks, you will find that making a complex SPA consistently alter the address location so that a refresh or a bookmark gets you to the same place you were in is really difficult.

A local Windows app usually has access to a lot of the native resources of the computer. A browser is designed to be sandboxed from them. Moreover, some users don't have correct settings or complete access to those settings, like in corporate environments for example. You can use the browser APIs, but you can't fully rely on them. And a browser tab is subject to firewall rules and network issues, local policies, browser extensions and ad blockers, external ad providers and so on.

You may think I am taking things to an unreasonable extreme. You will tell me that the analogy to desktop apps breaks not despite, but because of all of the reasons above and thus SPAs are something else, something more light, more reusable, webbier, with no versioning issues and instant access and bookmarkable locations. You will tell me that SPAs are just normal web sites that work better, not complex applications. I will cede this point.

However! I submit that SPAs are just SPAs because that's all they could be. They tried to replace fully fledged native apps and failed. That's why [React Native](https://reactnative.dev/ "Learn once, write anywhere.") exists, starting as a way to do more performant apps for mobiles and now one can [write even Windows applications](https://microsoft.github.io/react-native-windows/ "Take your apps across PC, Xbox, Surface Tablets, and dual-screens with these robust Windows extension to React Native.") with it.

Single Page Applications are great. I am sure they will become better and better with time until we will forget normal HTML pages exist and that servers can render and so on. But that's going in the wrong direction. Instead of trying to emulate desktop or native apps, SPAs should embrace their webbiness.

Is Javascript rendering bad? No. In fact it's just another type of text interpreted by the browser, just like HTML would be, but we can do better.  
Is Javascript URL manipulation bad? No. It's the only way to alter the address location without round trips to the server, but sometimes we need the server. Perhaps selective loading of component resources and code as needed will help.  
Is single threaded execution bad? No, but we are not restricted to it.  
Is component encapsulation bad? Of course not, as long as we recognize that in the end it will be rendered in a browser that doesn't care about your encapsulation.  
The only thing that I am still totally against is CSS in Javascript, although I am sure I haven't seen the best use of it yet.

React is good for SPAs and SPAs are good for React, but both concepts are trying too hard to take things into a very specific direction, one that is less and less about the browser and more about desktop-like components and control of the experience. Do I hate SPAs? No. But as they are now and seeing where they are going, I can't love them either. Let's learn from them, choose the good bits and discard the chaff.