# Single Page Application

## Summary


A web application broadly consists of two things: data (content) and control (structure, styling, behaviour). In traditional applications, these are spread across multiple pages of HTML, CSS and JS files. Each page is served in HTML with links to suitable CSS/JS files. A Single Page Application (SPA) brings a new programming paradigm for the web.

With SPA, we have a single HTML page for the entire application. This page along with necessary CSS and JS for the site are loaded when the page is first requested. Subsequently, as the user navigates the app, only relevant data is requested from the server. Other files are already available with the client. The page doesn't reload but the view and HTML DOM are updated. 

SPA (along with PWA) is the modern way to build web applications. SPA enhances user experience. There are frameworks that simplify building SPAs.

## Discussion

### Could you explain the single page application for a beginner?

In a typical multi-page application, each page is generated as HTML on the server and served to the client browser. Each page has its own URL that's used by the client to request that page.

When a user navigates from one page to another, the entire page loads. However, it's common for all pages to share many UI components: sidebar, header, footer, navigation menu, login/logout UI, and more. It's therefore wasteful to download these common elements with every page request. In terms of user experience, moving from one page to another might be annoying. Current page might lose UI interaction as user waits for another page to load.

In SPA, there's a single URL. When a link is clicked, relevant content is downloaded and specific UI components are updated to render that content. User experience improves because user stays with and can interact with the current page while the new content is fetched from the server. When an update happens, there's no transition to another page. Parts of the current page are updated with new content. 


### How does the lifecycle of an SPA request/response compare against a traditional multi-page app?

In multi-page apps, each request is for a specific page or document. Server looks at the URL and serves the corresponding page or document. The entire app is really a collection of pages. 

In SPA, the first client request loads the app and all its relevant assets. These could be HTML plus JS/CSS files. If the app is complex, this initial bundle of files could be large. Therefore, the first view of the app can take some time to appear. During this phase, a loader image may be shown to the user. 

Subsequently, when the user navigates within the SPA, an API is called to fetch new data. The server responds with only the data, typically in JSON format. The browser receives this data and updates the app view. User sees this new information without a page reload. The app stays in the same page. Only the view changes by updating some components of the page. 

SPAs are well-suited when we wish to build rich interactive UI with lots of client-side behaviour. 


### Which are the different SPA architectures?

Application content might be stored in files or databases. It can be dynamic (news sites) or contextual (user specific). Therefore, the application has to transform this content into HTML so that users can read them in a web browser. This transformation process is called *rendering*. From this perspective, we note the following SPA architectures: 

    + **Client-Side Rendering**: When browser requests the site, server responds quickly with a basic HTML page. This is linked to CSS/JS files. While these files are loading, user sees a loader image. Once data loads, JavaScript on the browser executes to complete the view and DOM. Slow client devices can spoil user experience.
    + **Server-Side Rendering**: HTML page is generated on the fly at the server. Users therefore see the content quickly without any loader image. At the browser, once events are attached to the DOM, app is ready for user interaction.
    + **Static Site Generators**: HTML pages are pre-generated and stored at the server. This means that the server can respond immediately. Better still, the page can be served by a CDN. This is the fastest approach. This approach is not suitable for dynamic content.

### What are the benefits of an SPA?

With SPA, applications load faster and use less bandwidth. User experience is seamless, similar to a native app. Users don't have to watch slow page reloads. Developers can build feature-rich applications such as content-editing apps. On mobile devices, the experience is richer: clicks can be replaced with scrolling and amazing transitions. With browsers providing many developer tools, SPAs are also easy to debug on the client side. 

SPA optimizes bandwidth usage. Main resources (HTML/CSS/JS) are downloaded only once and reused. Subsequently, only data is downloaded. In addition, SPAs can cache data, thereby saving bandwidth. Caching also enables the application to work offline. 


### What are some criticisms or disadvantages of an SPA?

Among the disadvantages of SPA is **SEO**. SPA has a single URL and all routing happens via JavaScript. More recently, Google is able to crawl and index JS files. In general, use multi-page apps if SEO is important. Adopt SPA for SaaS platforms, social networks or closed communities where SEO doesn't matter. 

SPA breaks **browser navigation**. Browser's back button will go to previous page rather than previous app view. This can be overcome with the *HTML5 History API*. 

SPA could lead to **security issues**. Cross-site scripting attacks are possible. If developers are not careful, sensitive data could be part of the initial data download. Since all this data is not necessarily displayed on the UI, it can give developers a false sense of security. Developers could also unknowingly provide access to privileged functionality at the client side. 

SPA needs **client-side processing** and therefore may not work well on old browsers or slow devices. It won't work if users turn off JavaScript in their browsers. SPAs can be hard to maintain due to reliance on many third-party libraries. 

It's worth reading Adam Silver's article on the many disadvantages of SPAs. 


### What are some best practices when converting a traditional app to SPA?

An SPA has to implement many things that come by default in traditional apps: browsing history, routing, deep linking to particular views. Therefore, **select a framework** that facilitates these. Select a framework with a good ecosystem and a modular structure. It must be flexible and performant for even complex UI designs. 

After the initial page loads, subsequent data is loaded by making API calls. Building an SPA implies a **well-defined API**. Involve both frontend and backend engineers while creating this API. In one approach, serve static files separately from the data that's handled by API endpoints. 

Define clearly which parts of the UI are dynamic. This helps to organize project modules. Structure the project to enable **reusable components**. 

Due to its high reliance on JavaScript, invest in **build tools** for better dependency management. Webpack is a good choice. A build process can do code compilation (via Babel), file bundling and minification. 

When converting to an SPA, don't take an all-out approach. **Migrate incrementally**, perhaps one page at a time. 


### How do I test and measure performance of an SPA?

Testing tools Selenium, Cypress and Puppeteer can also be used to measure app performance. WebPageTest is an online tool that's easier to use. Compared to multi-page apps, there's more effort to fill forms or navigate across views. 

Application performance on the client side can be monitored via Navigation Timing API and Resource Timing API. But these fail to capture JavaScript execution times. To address this, User Timing API can be used. LinkedIn took this approach and improved the performance of their SPA by 20%. Among the techniques they used are lazy rendering (defer rendering outside viewport) and lazy data fetching. 

At Holiday Extras, their app took 23 seconds to load on a good 3G connection. To reduce this, they adopted code splitting to defer loading of non-critical libraries. CSS was also split into three parts loaded at different stages: critical, body, onload. They moved from JS rendering to HTML rendering, and then started serving static HTML from Cloudfront CDN. They did real user monitoring (RUM). Among the tools they used were React, EJS, Webpack, and Speed Curve. 


### Could you mention some popular websites or web apps that are SPAs?

Facebook, Google Maps, Gmail, Twitter, Google Drive, and GitHub are some examples of websites built as SPAs. 

For example, in Gmail we can read mails, delete mails, compose and send mails without leaving the page. It's the same with Google Maps in which new locations are loaded and displayed in a seamless manner. In Grammarly, writers get suggestions and corrections as they compose their content. All this is powered by HTML5 and AJAX to build responsive apps. 

Trello is another example of SPA. The card layout, overlays, and user interactions are all done without any page reloads. 


### Which are some tools and frameworks to help me create an SPA?

The three main frameworks for building SPAs are React, Angular and Vue on the client side, and Node.js on the server side. All these are based on JavaScript. Other JavaScript frameworks include Meteor, Backbone, Ember, Polymer, Knockout and Aurelia.  

Developers can choose the right framework by comparing how each implements or supports UI, routing, components, data binding, usability, scalability, performance, and testability. For example, while Ember comes with routing, React doesn't; but many modules for React support routing. React supports reusable components. React supports one-way data binding whereas Angular supports two-way data binding. Ember and Meteor are opinionated whereas React and Angular are less so and more flexible. 

.NET/C# developers can consider using Blazor. Blazor can work both at client side and server side. It runs in a web browser due to WebAssembly. 

Design tools support traditional multi-page sites. Adobe Experience Manager Sites is a tool that allows designers to create or edit SPAs. It supports drag-and-drop editing, out-of-the-box components and responsive web design. 


### How does an SPA differ from PWA?

PWA uses standard web technologies to deliver mobile native app-like experience. They were meant to make responsive web apps feel more native on mobile platforms. PWA enables the app to work offline, push notifications and access device hardware. Unlike SPA, PWA use service workers, web app manifest and HTTPS. 

PWA load almost instantly since service workers run in a separate thread from the UI. SPAs need to pre-fetch assets at the start and therefore there's always an initial loading screen. SPAs can also use service workers but PWA do it better. In terms of accessibility, PWA are better than SPAs. SPAs might be suited for data-intensive sites that are not necessarily visually stunning. 

But PWA are not so different from SPA. Both offer app-like user experience. Many PWA are built with the same frameworks that are used to build SPA. In fact, an app might initially be developed as an SPA. Later, additional features such as caching, manifest icons and loading screens could be added. These make an SPA more like a PWA. 

## Milestones

1995

In the mid-1990s, rich interactions on web browsers become possible due to two different technologies: **Java Applets** and **Macromedia Flash**. Browsers are merely proxies for these technologies that have to be explicitly installed as browser plugins. With these technologies, all content is either loaded upfront or loaded on demand as the view changes. No page reloads are necessary. In this sense, these are ancestors of modern SPAs. 

2005

Jesse James Garrett publishes a paper titled *Ajax: A New Approach to Web Applications*. This describes a novel way to design web applications. AJAX, that expands to **Asynchronous Javascript + XML**, makes asynchronous requests in the background while the user continues to interact with the UI in the foreground. Once the server responds with XML (or JSON or any other format) data, the browser updates the view. AJAX uses the `XMLHTTPRequest` API. While this was around since the early 2000s, Garrett's paper popularizes this approach. 

2008

With the launch of GitHub, many JavaScript libraries and frameworks are invented and shared via GitHub. These become the building blocks on which true SPAs would later be built. 

Sep  
2010

Twitter releases a new version of its app with client-side rendering using JavaScript. Initial page load becomes slow. Due to diversity of client devices and browsers, user experience becomes inconsistent. In 2012, Twitter updates the app towards server-side rendering and defers all JS execution until the content is rendered on browser. They also organize the code as CommonJS modules and do lazy loading. These changes reduce the initial page load to a fifth. 

May  
2016

Google builds an app for its Google I/O event. Google engineers call this both an SPA and a PWA. With an App Engine backend, the app uses web components, Web Animations API, material design, Polymer and Firebase. During the event the app brings more user engagement than the native app. We might say that the app started as a SPA to create a PWA. In general, it's better to plan for a PWA from the outset rather than re-engineer an SPA at a later point. 

Feb  
2019

Google engineers compare different SPA architectures in terms of performance. One of these is called **rehydration** which combines both server-side and client-side renderings. This has the drawback that content loads quickly but not immediately interactive, thus frustrating the user. 

May  
2019

With the rise of edge computing, Section describes in a blog post how a Nuxt.js app (based on Vue.js) can be deployed at the edge. The app is housed within a Node.js module deployed at the edge. This SPA uses server-side rendering.