4 The web, frameworks, and R
Broadly speaking there are two approaches to building web applications:
- Multi page applications
- Single page applications
The above are somewhat self-explanatory but it’s nonetheless good to quickly look into their particularities to ensure we distinguish between them and understand their implications.
Here I just skim over these high-level ideas, they should become clearer as the book progresses.
4.1 Multi page
The multi page approaches consists of make applications that consist of multiple pages. This is also often referred to as the traditional approach as it predates the single page style.
In this paradgim the website will organise content on different pages and provide the user with ways to navigate between pages and find the content they look for.
This concretely often result in <nav> used in, for instance, “navbars”. These are essentially stylised links between the various pages of the website.
Each page is served at its own path. The index.html sits at the first / which is stripped by web browsers; when visiting github.com we actually visit https://github.com/ but the browser displays https://github.com. Other pages have their own path, for instance, we can then visit the about page at /about.
Every time we visit one of these paths in the browser, be it via the provided navigation or by typing the address in the browser, we execute a GET request to the respective server which then returns the appropriate HTML.
I do not know the exact stats but it’s safe to say that the majority of websites out-there follow such an approach.
Coming from R, blogdown follows this approach, although it builds static sites that do not requires servers to dynamically render pages.
4.2 Single page
Single page applications differ quite a bit. It does very much what it says on the tin; it consists of a single page.
We’ll likely never get to zero page application, there is no avoiding making an initial GET request to the server to obtain an initial response.
Where such applications differ is that then, everything happens on that one page. The user is never sent to other paths in the application, there is no /about or any other pages.
That is not to say there is no possibility to display content that would otherwise be placed in an about page, but it has to work differently.
Take some examples of single page applications, or mostly single page applciations:
- Google maps
Those, if the don’t consist of a single page, certainly see most of their action on the landing page.
However, this content is hardly static, on Google maps you see your position on the map updated in near real-time but it does not do so by repeatedly refreshing the page, that would be obnoxious.
These applications update the already loaded page with the use of the WebSocket, which allows two way communication between the client (web browser) and the server. The messages anda data sent from the server to the clients ultimately use JavaScript to update the page.
In the R world, you can build such applications with the shiny framework.
Note that this categorisation is relatively unimportant and the distinction between the two will often be blurry as large applications likely both have multiple pages and use WebSockets. For instance, Github adheres primarily to the multi page paradigm but also makes use of the WebSocket: when starring a repository the page the does re-render this goes through the Websocket.
4.3 Performances
There used to be great differences in performances between the two approaches but this is no-longer the case.
All applications have dependencies, be it Bootstrap, a visualisation library such as d3.js, or other. It used to be that single page applications had to load all such dependencies upfront but this has since changed.
For instance, shiny renders the required dependencies dynamically; the dependencies required to display a plotly graph are only rendered when such a plot is made visible and not when the app loads.
Technically the websocket is a tiny wee bit faster because HTTP requests require headers but we’re talking about dozens of milliseconds at best.
All in all, use the approach that suits you and the application you build best.
4.4 Frameworks
One thing to keep in mind is that web frameworks, the tools you will use to build your applications, tend to suit one approach over the other.
Ambiorix is unopinionated, you can build either form of applications with it, however, as the author of the package, I do not think you should use ambiorix for single page applications, simply because there is a framework out there that already specialises in it and will likely make your life easier: shiny. But it’s good to know you can still access the WebSocket if needed.
A somewhat uninformed comment because I have not used Python in a while, but if you want to build a multi page application you are probably well to choose Django whereas Flask suits single page applciations better.
4.5 Reactive programming
This section is because most R users who have built web applciations have used the shiny web framework which makes use of reactive programming in the back-end.
However contentious this may be: reactivity is a must-have for single pages applications but very little for multi page applications.
It is practical in a single page applications to have elements react and dynamically send messages to clients to appropriately update the page.
This has little place outside of single page applications. It’s difficult to tell what should be reactive to begin with. Whatever should react cannot emit anything, it all hinges on requests that return responses. You could admittedly still benefit from reactivity within a single page of an application but that makes unecessary complexity for the developer, it is difficult enough as it is, mixing reactive and non-reactive elements is difficult to wrap your head around. It also removes one advantage of non-reactivity: statelessness (or a word like that). Multi page applciation can be totally stateless where as reactivity implies a certain state.