pushState() API) can provide the perception and navigability of separate logical pages in the application. Interaction with the single page application often involves dynamic communication with the web server behind the scenes.
- 1 History
- 2 Characteristics
- 3 Technical approaches
- 4 Running locally
- 5 Challenges with the SPA model
- 6 Page lifecycle
- 7 References
- 8 External links
The term single-page application was coined by Steve Yen in 2005, though the concept was discussed at least as early as 2003 and Stuart (stunix) Morris wrote the Self-Contained website at slashdotslash.com with the same goals and functions in 2002 the same year that Lucas Birdeau, Kevin Hakman, Michael Peachey and Evan Yeh described a single page application implementation in the US patent 8,136,109.
There are a few distinct characteristics defining an SPA:
- Chunking – the web page is constructed by loading chunks of HTML fragments and JSON data instead of receiving full HTML from a web server on every request. (Backbone.js, pjax, jQuery, Breeze)
- Routing – selection of views and navigation (without page reloads) that preserves page state, elements and data (History.js, Crossroads.js, Backbone.js, pjax, HTML5 History API)
- Local storage – capabilities of storing data on a browser for performance and offline access replace cookies and intensive data loads from web server (HTML5 Local storage).
Advanced SPAs employ real-time communication – two-way communication between a client application and the web server that replaces one-way requests from a browser (HTML5 Web Sockets, Socket.io, SignalR). When new or modified data arrives from the server, reactive templating can be used to automatically update the DOM with the new data, via declarative binding of data to HTML templates using a templating system such as Mustache or its successor Handlebars. If user inputs are also bound to data, the SPA has two-way data binding, a concept popularized by AngularJS. Alternatively, data can be rendered using web UI widget libraries such as DHTMLX, Dojo Widgets, Ext JS, jQuery UI or Webix.
There are various techniques available that enable the browser to retain a single page even when the application requires server communication.
- AngularJS is a fully client-side library. AngularJS's templating is based on bidirectional UI data binding. Data-binding is an automatic way of updating the view whenever the model changes, as well as updating the model whenever the view changes. The HTML template is compiled in the browser. The compilation step creates pure HTML, which the browser re-renders into the live view. The step is repeated for subsequent page views. In traditional server-side HTML programming, concepts such as controller and model interact within a server process to produce new HTML views. In the AngularJS framework, the controller and model state are maintained within the client browser. Therefore new pages are generated without any interaction with a server.
WebSockets are a bidirectional stateful real-time client-server communication technology part of the HTML5 specification, superior to AJAX in terms of performance and simplicity.
Data transport (XML, JSON and AJAX)
Thin server architecture
An SPA moves logic from the server to the client. This results in the role of the web server evolving into a pure data API or web service. This architectural shift has, in some circles, been coined "Thin Server Architecture" to highlight that complexity has been moved from the server to the client, with the argument that this ultimately reduces overall complexity of the system.
Thick stateful server architecture
This approach needs more server memory and server processing, but the advantage is a simplified development model because a) the application is usually fully coded in the server, and b) data and UI state in the server are shared in the same memory space with no need for custom client/server communication bridges.
Thick stateless server architecture
This approach requires that more data be sent to the server and may require more computational resources per request to partially or fully reconstruct the client page state in the server. At the same time, this approach is more easily scalable because there is no per-client page data kept in the server and, therefore, AJAX requests can be dispatched to different server nodes with no need for session data sharing or server affinity.
Some SPAs may be executed from a local file using the file URI scheme. This gives users the ability to download the SPA from a server and run the file from a local storage device, without depending on server connectivity. If such an SPA wants to store and update data, it must use browser-based Web Storage. These applications benefit from advances available with HTML5.
Challenges with the SPA model
Because the SPA is an evolution away from the stateless page-redraw model that browsers were originally designed for, some new challenges have emerged. Each of these problems has an effective solution with:
- Server-side web frameworks that specialize in the SPA model.
- The evolution of browsers and the HTML5 specification aimed at the SPA model.
Search engine optimization
Google currently crawls URLs containing hash fragments starting with
#!. This allows the use of hash fragments within the single URL of an SPA. Special behavior must be implemented by the SPA site to allow extraction of relevant metadata by the search engine's crawler. For search engines that do not support this URL hash scheme, the hashed URLs of the SPA remain invisible.
Alternatively, applications may render the first page load on the server and subsequent page updates on the client. This is traditionally difficult, because the rendering code might need to be written in a different language or framework on the server and in the client. Using logic-less templates, cross-compiling from one language to another, or using the same language on the server and the client may help to increase the amount of code that can be shared.
Because SEO compatibility is not trivial in SPAs, it's worth noting that SPAs are commonly not used in a context where search engine indexing is either a requirement, or desirable. Use cases include applications that surface private data hidden behind an authentication system. In the cases where these applications are consumer products, often a classic "page redraw" model is used for the applications landing page and marketing site, which provides enough meta data for the application to appear as a hit in a search engine query. Blogs, support forums, and other traditional page redraw artifacts often sit around the SPA that can seed search engines with relevant terms.
Both of these do require quite a bit of effort, and can end up giving a maintenance headache for the large complex sites. There are also potential SEO pitfalls. If server-generated HTML is deemed to be too different from the SPA content, then the site will be penalized. Running PhantomJS to output the HTML can slow down the response speed of the pages, which is something for which search engines – Google in particular – downgrades the rankings.
Client/Server code partitioning
With an SPA being, by definition, "a single page", the model breaks the browser's design for page history navigation using the Forward/Back buttons. This presents a usability impediment when a user presses the back button, expecting the previous screen state within the SPA, but instead the application's single page unloads and the previous page in the browser's history is presented.
Analytics tools such as Google Analytics rely heavily upon entire new pages loading in the browser, initiated by a URL change. SPAs don’t work this way.
After the first page load, all subsequent page and content changes are handled internally by the application. So the browser never triggers a new page load, nothing gets added to the browser history, and the analytics package has no idea who’s doing what on the site.
Adding page loads to an SPA
It's possible to add page load events to an SPA using the HTML5 history API; this will help integrate analytics. The difficulty comes in managing this and ensuring that everything is being tracked accurately – this involves checking for missing reports and double entries. The good news is that there's no need to build everything from the ground up. There are several open source analytics integrations for Angular available online, addressing most of the major analytics providers. Developer should integrate them into the application and make sure that everything is working correctly, but there's no need to do everything from scratch.
Speed of initial load
Single Page Applications have a slower first page load than server-based applications. This is because the first load has to bring down the framework and the application code before rendering the required view as HTML in the browser. A server-based application just has to push out the required HTML to the browser, reducing the latency and download time.
Speeding up the page load
There are some ways of speeding up the initial load of an SPA, such as a heavy approach to caching and lazy-loading modules when needed. But it's not possible to get away from the fact that it needs to download the framework, at least some of the application code, and will most likely hit an API for data before displaying something in the browser. This is very much a "pay me now, or pay me later" trade-off scenario. The question of performance and wait-times remains a decision that the developer must make.
An SPA is fully loaded in the initial page load and then page regions are replaced or updated with new page fragments loaded from the server on demand. To avoid excessive downloading of unused features, an SPA will often progressively download more features as they become required, either small fragments of the page, or complete screen modules.
In this way an analogy exists between "states" in an SPA and "pages" in a traditional web site. Because "state navigation" in the same page is analogous to page navigation, in theory, any page-based web site could be converted to single-page replacing in the same page only the changed parts result of comparing consecutive pages in a non-SPA.
The SPA approach on the web is similar to the Single Document Interface (SDI) presentation technique popular in native desktop applications.
- "Inner-Browsing: Extending Web Browsing the Navigation Paradigm". Retrieved 2011-02-03.
- "Slashdotslash.com: A self contained website using DHTML". Retrieved 2012-07-06.
- "US patent 8,136,109". Retrieved 2002-04-12.
- "Meteor Blaze".
Meteor Blaze is a powerful library for creating live-updating user interfaces. Blaze fulfills the same purpose as Angular, Backbone, Ember, React, Polymer, or Knockout, but is much easier to use. We built it because we thought that other libraries made user interface programming unnecessarily difficult and confusing.
- Introducing DDP, March 21, 2012
- "Server Side Rendering for Meteor". Retrieved 31 January 2015.
- "Unhosted web apps".
- "The Single Page Interface Manifesto". Retrieved 2014-04-25.
- "Derby". Retrieved 2011-12-11.
- "Sails.js". Retrieved 2013-02-20.
- "Tutorial: Single Page Interface Web Site With ItsNat". Retrieved 2011-01-13.
- Michael Mikowski. "How to optimize single page sites for search engines". Retrieved 6 January 2014.
- "What the user sees, what the crawler sees". Retrieved January 6, 2014.
- "Making AJAX Applications Crawlable". Retrieved January 6, 2014.
Historically, AJAX applications have been difficult for search engines to process because AJAX content is produced
- "Making AJAX Applications Crawlable". Retrieved 2011-01-13.
- "ItsNat v1.3 release Notes". Retrieved 2013-06-09.
- Holmes, Simone (2015). Getting MEAN with Mongo, Express, Angular, and Node. Manning Publications. ISBN 978-1-6172-9203-3