Een Single Page Application (SPA), ook wel een Single Page Interface (SPI) genoemd, is een webapplicatie of website die uit een enkele webpagina bestaat waarvan de inhoud dynamisch aangepast wordt. Voor de gebruiker lijkt het alsof hij meerdere webpagina's ziet, terwijl het eigenlijk om dezelfde pagina gaat met telkens een andere inhoud. Het doel is een vlotte gebruikerservaring te bieden, die te vergelijken is met een computerprogramma dat op de computer van de gebruiker zelf draait. Er zijn diverse technieken beschikbaar om een Single Page Application te bouwen, waarin HTML-scripting een essentiële rol speelt. De technieken kunnen daarnaast onder meer gebruikmaken van HTML-formulieren, HTML-frames en XML.
In een SPA wordt alle benodigde code - HTML, JavaScript en CSS - opgehaald met een enkele laadactie van de pagina, of de noodzakelijke middelen worden dynamisch geladen en aan de pagina toegevoegd zodra ze nodig zijn, meestal als reactie op acties van de gebruiker. De pagina wordt op geen enkel moment in het proces opnieuw geladen en draagt ook geen besturing over naar een andere pagina, hoewel moderne webtechnologieën (zoals die zijn opgenomen in HTML5), de perceptie en de navigeerbaarheid van afzonderlijke logische pagina's in de applicatie kunnen bieden. Interactie met een SPA gaat vaak gepaard met dynamische communicatie met de webserver die achter de schermen fungeert.
De term Single Page Application werd bedacht door Steve Yen in 2005, hoewel het concept in elk geval reeds in 2003 besproken is. Stuart 'stunix' Morris schreef met hetzelfde doel en functie zijn SPA-website op adres www.slashdotslash.com in 2002, hetzelfde jaar waarin Lucas Birdeau, Kevin Hakman, Michael Peachey en Clifford Yeh een SPA-implementatie beschreven in de Amerikaanse octrooiaanvraag 8.136.109
Moderne browsers die HTML5 kunnen interpreteren, bieden ontwikkelaars de mogelijkheid om de gebruikersinterface en applicatielogica van webservers te verschuiven naar de client. Complete open source bibliotheken ondersteunen het bouwen van SPA's zonder dat de ontwikkelaars te diep in JavaScript hoeven te duiken of hoeven te worstelen met technische problemen.
Kenmerken van SPA's Een vakkundig gemaakte Single Page Application beschikt over de volgende kenmerken: Inhoud opdelen in kleine eenheden (Engels: chunking): de webpagina wordt opgebouwd door het laden van stukjes HTML-fragmenten en JSON-data, in plaats van het bij elke request ontvangen van de volledige HTML vanuit een webserver (Backbone.js, Pjax, jQuery, Upshot.js) Controllers: JavaScript-code, die complexe manipulaties van Document Object Model (DOM) en data, applicatielogica en AJAX-requests afhandelt, wordt vervangen door controllers die views en modellen scheiden door gebruik te maken van Model-View-Controller (MVC) of Model-View-ViewModel (MVVM) patronen (Backbone.js, Knockout.js, JavascriptMVC, Angular) Gebruik maken van templates: de codering van manipulatie van gebruikersinterface (Engels user interface, afgekort tot UI) en DOM wordt vervangen door declaratieve koppeling van data aan HTML-templates (Knockout.js, Mustache, jQuery-templates, Underscore.js, Angular) Routering: selectie van views en navigatie (zonder herladen van de pagina) die de paginatoestand, elementen en data bewaren (History.js, Crossroads.js, Backbone.js, Pjax, Angular) Realtime communicatie: communicatie in twee richtingen tussen de client-applicatie en de web-server vervangt eenzijdige requests vanuit de browser (HTML5 WebSockets, Socket.io, SignalR) Lokale opslag: mogelijkheden voor het opslaan van gegevens in een browser ten behoeve van een beter prestatievermogen (Engels: performance) en offline toegang vervangen cookies en intensieve data-laadacties vanaf de webserver (HTML5 localStorage).
Technische benaderingen Er zijn verschillende technieken beschikbaar die de browser in staat stellen om een enkele pagina vast te houden, zelfs wanneer de applicatie communicatie met de server nodig heeft.
JavaScript-frameworks JavaScript-frameworks voor webbrowsers, zoals AngularJS, YUI App Framework en React hebben het SPA-concept toegepast. Angular is een volledig client-side framework. De template-mogelijkheden van Angular zijn gebaseerd op bidirectionele data-koppeling. Data-koppeling is een automatische methode voor het bijwerken van de view wanneer het model wordt gewijzigd, evenals het bijwerken van het model wanneer de view wijzigt. Het HTML-template wordt gecompileerd in de browser. De compilatiestap creëert pure HTML, waarna de browser de actuele view opnieuw weergeeft. De stap wordt herhaald voor volgende pageviews. In de traditionele server-side HTML-programmering werken controller- en modelcomponenten binnen een proces op de server om nieuwe HTML-views te produceren. In het Angular-framework blijven de controller en het model gehandhaafd binnen de clientbrowser. Zodoende kunnen nieuwe pagina's worden gegenereerd zonder interactie met een server. Het YUI App Framework is een combinatiepakket van de componenten App, Model, Model List, Router en View; met elkaar gecombineerd vormen ze een op MVC lijkend framework voor het schrijven van Single Page Applications met JavaScript. Deze componenten zijn afzonderlijk of samen te gebruiken voor het bouwen van allerlei applicaties, van eenvoudige niet-interactieve webpagina's tot omvangrijke applicaties met URL-gebaseerde routering, data-koppeling en volledige client-server synchronisatie.
AJAX Een prominente techniek die momenteel wordt gebruikt, is Ajax. AJAX maakt overwegend gebruik van het XMLHTTPRequest-object van JavaScript. Andere AJAX-technieken gebruiken de HTML-elementen iframe of script. Populaire bibliotheken zoals jQuery, dat het gedrag van AJAX standaardiseert in browsers van verschillende fabrikanten, hebben de AJAX-technologie verder gepopulariseerd.
WebSocket WebSocket is een protocol voor bidirectionele communicatie over een enkele TCP-connectie. Dit protocol maakt onderdeel uit van de HTML5-specificatie en wordt ook gebruikt voor Single Page Applications.
Browserplug-ins Asynchrone aanroepen naar de server kunnen ook worden gerealiseerd met behulp van plug-ins voor browsers, zoals Microsoft Silverlight, Adobe Flash of Java-applets.
Data-transport (XML, JSON en AJAX) Requests aan de server resulteren meestal in ruwe data (bijvoorbeeld XML of JSON), of nieuwe HTML die wordt geretourneerd. In het geval dat de server HTML teruggeeft, werkt JavaScript aan de client-side een deel van het DOM bij. Wanneer ruwe data worden teruggestuurd, wordt aan de client-side vaak een JavaScript XML / XSLT proces gebruikt (en in het geval van JSON een template) om de ruwe data te vertalen naar HTML, die vervolgens wordt gebruikt om een deelgebied van het DOM bij te werken.
Serverarchitectuur Dunne-serverarchitectuur Een SPA verplaatst logica van de server naar de client. Dit heeft tot gevolg dat de rol van de webserver evolueert naar een pure data-API of webservice. Deze verschuiving in de architectuur wordt wel eens 'dunne-serverarchitectuur' (Engels: Thin Server Architecture) genoemd om te benadrukken dat complexiteit wordt verplaatst van de server naar de client, met het argument dat dit de totale complexiteit van het systeem vermindert.
Dikke-serverarchitectuur met bijgehouden toestand De server houdt de benodigde toestand (Engels: state) van de pagina van de client bij. Wanneer een request bij de server aankomt (meestal als gevolg van een gebruikersactie), verzendt de server de juiste HTML en/of JavaScript met de concrete wijzigingen om de client in de nieuwe gewenste toestand te brengen (gewoonlijk het toevoegen/verwijderen/wijzigen van een deel van het Data Object Model van de client). Op hetzelfde moment wordt de toestand op de server bijgewerkt. De meeste logica wordt op de server uitgevoerd en HTML wordt meestal ook opgebouwd op de server. In sommige opzichten simuleert de server een webbrowser, door het ontvangen van gebeurtenissen (Engels: events) en het uitvoeren van wijzigingen in de servertoestand die automatisch worden doorgegeven aan de client. Deze aanpak vereist meer geheugen en processorvermogen van de server, maar het voordeel is een vereenvoudigd ontwikkelingsmodel, doordat a) de applicatie meestal volledig gecodeerd is in de server, en b) de data en de toestand van de gebruikersinterface worden gedeeld in dezelfde geheugenruimte waardoor geen client/server-communicatiebruggen nodig zijn.
Dikke-serverarchitectuur zonder bijgehouden toestand Dit is een variant van de benadering waarbij de toestand op de server wordt bijgehouden. In dit geval stuurt de clientpagina gegevens over zijn huidige toestand naar de server, meestal door middel van AJAX-requests. Met deze informatie kan de server de clienttoestand van het gedeelte van de pagina dat moet worden gewijzigd reconstrueren en de noodzakelijke gegevens of code genereren. Dit gebeurt bijvoorbeeld met behulp van JSON of JavaScript, die naar de client wordt teruggestuurd om deze in een nieuwe toestand te brengen, meestal door het wijzigen van de DOM-boomstructuur van de pagina, naar aanleiding van een gebruikersactie die de aanleiding was voor het request.
Bij deze aanpak moeten meer gegevens naar de server worden gestuurd en het is mogelijk dat per request meer processorvermogen nodig is om de clienttoestand op de server gedeeltelijk of volledig te reconstrueren. Tegelijkertijd is deze benadering beter schaalbaar omdat op de server geen paginagegevens per client bewaard behoeven te worden, waardoor AJAX-requests naar meerdere servernodes kunnen worden verzonden zonder dat sessiedata tussen servers behoeven te worden uitgewisseld.
Lokaal uitvoeren Sommige SPA's kunnen worden uitgevoerd vanaf een lokaal bestand met behulp van het URI-schema voor bestanden, zoals gedefinieerd in RFC1630 en RFC1738. Dit geeft gebruikers de mogelijkheid een SPA te downloaden van een server en uit te voeren vanaf een lokaal opslagapparaat, zonder afhankelijk te zijn van een verbinding met een server. Als zo'n SPA data wil opslaan en bewerken, moet hij gebruikmaken van browser-gebaseerde webopslag (Engels: web storage). Deze applicaties profiteren van de extra mogelijkheden die HTML5 biedt.
Uitdagingen met het SPA-model Omdat het SPA-model een ontwikkeling is die afwijkt van het toestandsloze model van het opnieuw opbouwen van webpagina's waarvoor browsers oorspronkelijk bedoeld waren, is een aantal nieuwe uitdagingen ontstaan. Voor elk van deze problemen bestaat een effectieve oplossing door gebruik te maken van:
Client-side JavaScript-bibliotheken waarmee diverse problemen kunnen worden aangepakt Server-side webframeworks die gespecialiseerd zijn in het SPA-model De doorontwikkeling van browsers en de HTML5-specificatie gericht op het SPA-model.
Zoekmachineoptimalisatie Vanwege het ontbreken van JavaScript-uitvoering op de spiders (ook webcrawlers genoemd) van populaire webzoekmachines, heeft zoekmachineoptimalisatie (Engels: search engine optimization of SEO) in het verleden problemen opgeleverd voor publiekelijk toegankelijke websites die het SPA-model wilden toepassen
Google doorzoekt momenteel URL's met deel-URL's, hashfragmenten genoemd, die beginnen met #!. Het deel van de URL dat begint met '#' wordt de fragmentidentifier genoemd. Dit maakt het gebruik van hashfragmenten binnen de enkele URL van een SPA mogelijk. De SPA-website moet specifiek gedrag implementeren om het ophalen van relevante metadata door de spider van de zoekmachine mogelijk te maken. Voor zoekmachines die geen ondersteuning bieden aan dit URL-hashschema, blijven de URL's met een fragmentidentifier onzichtbaar.