What's a Single-Page App?

Jake Lazaroff November 5, 2024
Source
The web development community talks a lot about single-page apps, but are we all on a single page? Heydon Pickering tackled this question in his similarly-named article What Is A Single-Page Application? The TL;DR — spoiler alert! — is that it's a website that uses a ton of JavaScript to improve user experience by showing you a loading spinner. That's obviously tongue-in-cheek, but it's a reaction to the working definition that most people use. For better or worse, "single-page app" is usually a euphemism for "JavaScript framework app". I recently wrote about building a single-page app with htmx using service workers to render everything client-side — no loading spinners in sight! In response, Thomas Broyer objected to the premise that htmx and single-page apps were opposites. He showed me an article that he wrote called Naming things is hard, SPA edition (which you should also go read!) that breaks down rendering into a spectrum. In a bid to cement my burgeoning reputation as a Quadrant Chart Guy, I feel compelled to add even more nuance to the situation: I'm sorry. Kinda. Okay, let's define the extrema of each axis: Server-side rendering (SSR) is when HTML is produced on a server and sent to the browser. Client-side rendering (CSR) is when HTML (or some other representation, such as the result of a JSX transform) is produced on the client and applied to the DOM. A multi-page app (MPA) is when a hyperlink click or form submission results in the browser replacing the current page with an entirely new document. A single-page app (SPA) is when the browser never replaces the page with a new document, and instead makes all changes through client-side DOM manipulation. If you just came here for an answer to the title, that's it; I guess you can go home now. But I think it's interesting to look at the various tools people use and how they fit in. Most tools for building websites don't lock you into just one quadrant. After all, any tool lets you drop in a plain un-enhanced tag and at the very least get MPA behavior, and most JavaScript usage outside of Google Tag Manager relies on client-side rendering (even if done manually). So: without casting any aspersions, here's my ontology of web app architectures organized by rendering and navigation. Traditional Web Frameworks and Static Site Generators This is a pretty large tent, encompassing WordPress, Django, Rails (pre-Turbolinks) Jekyll, Hugo, Eleventy and myriad others. It also includes hand-authored HTML, though I wouldn't describe that as a "tool" so much as a "way of life". Tools in this category are on the bottom left of the chart: server-side rendered multi-page apps. The tradeoffs of this quadrant are well known: The browser takes care of a lot of important accesibility features, such as letting screen readers know when the user navigates to a new page. Delivering HTML first allows the content to be visible even if CSS or JavaScript fail to load. Pages can load even faster if HTML is streamed in, rather than delivered all at once. The full page must be downloaded and replaced on each navigation. In fact, every interaction requires a network round trip. This experience has remained mostly unchanged for 30 years. And it's great! With only a little bit of HTML and CSS, you can make a pretty good website; the many Motherfucking Website variations show just how far a few tags and properties get you. The low barrier to entry is one of the main reasons the web flourished. Three decades on, improvements in HTML and CSS are starting to mitigate some of the downsides. Preloading resources, for example, allows the browser to preemptively download associated files, which can make navigation almost instantaneous. And cross-document view transitions — not yet well supported, but hopefully soon! — promise to allow multi-page apps to navigate with fancy animations. That said: requiring a network request and a whole new page for every interaction is a pretty strong constraint! As developers' ambitions grew, they leaned more and more heavily on JavaScript, which led to… JavaScript Frameworks Although JavaScript was invented way back in 1995, I don't think a schism truly happened until 2010 or so. That's when the stereotypical single-page apps began to emerge: rather than using small snippets of JavaScript to add client-side functionality to server-side rendered HTML, people started building apps with a JavaScript framework and rendering them on the client. Note that I'm not talking about Next.js or similar tools (I'll get to them in the next section). I'm talking about Backbone, Angular 1, React with a custom Webpack setup… basically, JavaScript apps before circa 2018, when people would ship an HTML file with an empty except for one lonely

Discussion in the ATmosphere

Loading comments...