Sometimes the HTML is rendered on the client, but not necessarily. All HTML code or at least the initial structure may as well be rendered on the server.
Instead of making server round-trips after each user input, the app makes HTTP server requests in the background to publish actions or to load new data.
Passing on existing best practices
Ten years ago, web creators tried to understand how user interfaces of native apps work, and what benefits they provide. To catch up with the
richness and responsiveness of desktop apps, they adapted certain existing patterns for the web.
The architecture of web apps
Stefan Tilkov makes a claim about the architecture of web apps I’d like to comment on:
The business logic is a set of high-level operations on the data. Like creating, reading, updating and deleting records (CRUD). Updating relations between records. Finding, transforming and merging records to serve a particular request.
This business logic lies in the server code given you’re building an app that somehow synchronizes with the server. This is where the data is processed in the end, this is where the data needs to be consistent. This is the code and the data storage one cannot tamper with easily. This is where authorization, validation and security checks need to be performed.
Usually this server code offers a HTTP REST API which is consumed by several clients, for example web or native clients. These clients mostly contain user interface logic.
Sharing logic between client and server
A gray area is input validation, for example. For consistency, the API server has the final say on validation. However, it improves the user experience to perform at least simple validations in the clients. This gives instant feedback instead of making the user wait for server requests and user interface refreshes.
There are already practical ways to share logic between client and server. In the form validation example, we can specify the rules in a neutral, declarative format like JSON or XML. Each client has glue code that reads and applies the rules to the specific user interface.
Client-server architectures instead of monoliths
“A fantastic example of the problems created by the SPA approach is parallelization of work. If you have a team of multiple people, or God forbid, multiple teams working on the same SPA, you need to come up with a good way to support this. Instead, you can just have each of those teams build their own web application. Each of those applications can be connected to every other one built at the same time by the same organization (as well as to every other web application residing anywhere, if you want to) — in fact relying on the core strength of the web.”
“In terms of accessibility, rendering semantic HTML on the server-side provides an out-of-the-box support. There is only a limited set of things that you can do with HTML, and again this is a feature, not a bug.”
“You can address some of those problems within an SPA, too. But it takes effort. With the ROCA approach, you have a well-known, extremely mature, proven architecture to rely on.”
This is misleading. Your HTML is not more accessible or more semantic when it’s rendered on the server. Whether you render HTML on the server or in the browser, you need to write accessible and semantic markup.
There are differences between server-side and client-side rendering regarding accessibility: Rendering on the client is less robust since you have little control over the client. But once the HTML is parsed into the DOM, the accessibility is the same.
“[The single-page apps that I know] are bloated and slow to load, even though the actual information they display and the interaction they offer is very simple. […]”
“In almost every case I’m aware of, your [single-page application] has zero benefit for the user, and there are only positive sides to embracing browser features instead.”
Such sites provide a great benefit to the user. In the end, every software, every information system should enable the user to perform tasks in an easy, fast and approachable way. This should drive your architectural decisions.
As Greg Babiars puts it,
I’m ‘fatigued’ by posts like this taking nuanced technical and UX discussions and declaring [there’s] one right way that fits all needs.
The web was invented as a “document retrieval system”, and we need to appreciate the principle of universal access. But the web is also an “application delivery system”. Let’s reconcile these two approaches as far as possible instead of ignoring or excluding one of them.
Please see my other articles on the topic:
For a full list of references, see my bookmarks tagged with progressive enhancement.
I’d love to hear your feedback! Contact me via email, on Mastodon or Twitter.