Let’s get started with basics: a website is a collection of files. Those files are stored on a public folder on a computer called server whose characteristics are that it is always on, and always connected to the internet under the same IP address (a short IP would be
126.96.36.199). Because no human can remember those long random character sequences, IP addresses are aliased by domain names (google.com). Internet service providers (ISPs) maintain the domain name system (DNS), which is like a phone book, connecting (domain) names to the (IP) address. When you enter a URL (uniform resource locator) into your browser (the combination of the website’s domain address and a reference to the desired page of that website), your browser makes a HTTP (hypertext transfer protocol) call to the ISP, who forwards the request to the right server. The server returns the files that are specified under the requested URI (uniform resource identifier, a sub-part of the URL). Your browser then shows those files.
A basic web page is made off of HTML and CSS files.
HTML stands for Hypertext Markup Language. HTML entails the content of a web page, but also the semantics, so structural information. Similarly to a word document, you can define that something is a first level heading, a second level heading, a paragraph and so on.
CSS is Short for Cascading Stylesheets. CSS takes care of how the HTML looks and is optional. A page could work with only HTML and that’s actually how the web started. In CSS you’ll define stuff like “my first level headings should always be blue and bold except for when being part of the navigation bar, there they should be italic instead of bold”. There’s some rules of inheritance, that’s what the “cascading” part of the CSS acronym is about.
With this, you have the full web of today… …except for most1 interactivity. Any internet page built with HTML and CSS is similar to many PDF documents: visually there’s no limit to complexity, but there’s no interactivity. For every page you view, your browser loads HTML and CSS and displays it. Nearly the only possible interactivity is links to other documents. Clicking them will load that pages HML and CSS files.
Not having much interactivity is fine for more informational website, like news sites, blogs, and the like. But without advanced interactivity, it’s not possible to build complex web apps like Google mail or Facebook. There’s a wide spectrum between those two, but you can keep in mind that we’d call more static sites “websites”, and the more interactive ones “web application”, or “web app”.
So with JS you can do everything a modern web app can do, but it’s extremely tedious to write a web application with “pure” JS. The reason is that you have to attach one “event listener” to every single element that is clickable in the app. You then have to replace content on the page with the new content in reaction to those events, hardcoding HTML stings inside the JS for every single possible combination of application states. It’s close to impossible to do, it would be much too much self-written code, hard to keep a mental overview and good structure. So how do software developers solve complexity? Right, with more software on top of the base technology! You can look at any IT topic as layer cake, with actual application development moving more and more layers up the stack, further abstracting / simplifying the complex computer stuff that is going on beneath.
Nowadays there’s a couple popular JS frameworks: React (invented at Facebook), Angular (invented at Google), Vue (by an ex-Google employee who had worked on AngularJS). They all borrow a lot of fundamental ideas from each other:
- You don’t write HTML anymore, but a templating language. The reason is that those templating languages are built to work well with JS, making it much simpler to build interactive behaviours. The framework then translates this templating markup to HTML.
- You split your application into components. Components are an intuitive concept: You don’t want to have write the HTML, CSS, and JS for every button in the application from scratch. You want to write a button component once and then re-use it throughout the application. When you build the button component you want to know all the different button types there are, so that you can write the button component in a way that it can be customised to match all use cases. Splitting a large code base into smaller snippets makes the applications code much easier to navigate and reason about. When you need to change how an application’s buttons look / work, you know exactly which place in the code to touch. Writing automatic tests for small code snippets is much easier than to test a whole application.
- There is similar patterns in how data flow throughout the application. Managing all possible application states is one of the hardest things to get right in a big application. At any given time there’s thousands of combinations of circumstances that the application has to consider to decide what to show: What needs to be shown when a user is logged in, but has no verified email, but was invited to a team in the application, and has not yet used the application, but the team has entered a lot of data into the application already, and the user came from a password reset link, but the password reset link was no longer valid? Having a clear logic of how data is handled in any given place in the application, and having easy ways to react to data changes is of super high value. The frameworks also automatically recognise which components depend on which data, and show those components with the latest data whenever their data dependencies change. The application always shows the latest data to the user, without having to reload/re-apply the full page HTML. This comes with performance benefits, as updating the whole HTML page content is slower than updating just small parts of it.
- The application rarely contains the content that is shown anymore. Usually the data are dynamically loaded from another server via some sort of application programming interface (API).
Now, those mentioned frameworks are used to create “Single Page Application”s (SPA). The name stems from the fact that the whole application only has one HTML page (whereas we said that traditionally a web page would have one HTML file for every page). Basically HTML is only used as entry point to the application. Whichever application URL you open, you’ll always get that one single HTML file returned. This HTML file has basically no content besides a link to the application’s JS. That JS is then downloaded by the browser and executed. The JS contains all logic of what to show for that URL.
Single page applications have some negative side-effects, like web crawlers used by search engines to detect the page content no longer being able to understand what’s on a page without executing all the JS2. Those applications also only work on computers powerful enough to run all of that JS. You have to know that JS is much more computing intensive than HTML and CSS. You might think that our computers are all powerful enough at first, but there’s plenty of people with old computers, and older or cheaper smartphones are much less powerful. There’s plenty web pages are built using those JS frameworks which don’t need to come with such heavy baggage. This happens because developers use the tools that they are well-versed in, and nowadays that’s often those JS frameworks. Those side-effects are, why web developers debate whether we’re marching in the wrong direction, or just not yet there. So let’s take stock:
Never before could we build more capable web applications. A well-build web application can do nearly all of the things a native program which has been installed on your computer can do,. And the nice thing is that no one needs to install or update a web application. It doesn’t take space on your computer when you’re not using it. Publishing an application on the web immediately makes it accessible to every human on the world wide web - that’s more than 4.5 billion! We just haven’t yet learned how to use all of those capabilities to their best abilities every time we build something new. Like with any craft, there’s often reasons to cut the corners that no one sees at first (accessibility, offline usage, and so on). Give us some more time, mom – we’ll get there!
1 Forms are built into HTML, and form data can be sent to the web server from a HTML only page. ↩
2 Of course there's technical fixes for that called server side rendering (SSR), but those increase the complexity of operating the web applications and are not used everywhere due to the difficulty of setting it up correctly. ↩