Why Your Next Web App Frontend Might be The Backend
How LiveView and other real-time server-side rendered HTML technologies are changing how the frontend is written
A brief history of Web architecture
Throughout the history of computing, even before the web, the pendulum has swung back and forth between server-oriented and client-oriented approaches.
Let’s go back through some of the history of web architecture to see where we started, and where we are now.
Server-rendered, mostly static HTML
Languages like PHP and frameworks like Ruby on Rails (and many others), helped to expand the capabilities of web apps by generating HTML dynamically for each request. While this approach greatly enhanced what web applications could do, the content was still, for the most page, static once it arrived to the browser.
Server-side rendering & Isomorphic rendering (SSR)
Though SPAs excel in interactivity and unlock the ability to build new kinds of applications, they do come with some downsides with regard to rendering time, frontend performance & SEO. Rendering an SPA often requires many round-trips to the server and because content is rendered with JS on the client, the process is typically much slower than static HTML. Furthermore, content is not readily available to some search engines (more on this below).
To address this, some frameworks began to introduce isomorphic rendering: the strategy of rendering an initial version of a page on the server, then letting the client SPA take over for the rest of the application lifecycle. Because the initial page content is fully loaded in an HTTP request, this technique improves initial load times & SEO discoverability.
There are now a wide variety of frameworks that offer isomorphic rendering functionality. In fact, it’s built-in to some popular frontend frameworks like Vue and React, though setup and maintenance comes with some overhead — isomporhic rendering may introduce new backend dependencies in order to perform the rendering at request time.
Server-side rendering “plus”
SSR with isomorphic rendering helps to solve a set of common issues with SPAs, but a new generation of technologies is taking the idea even further: what if you did all of your rendering on the backend, and effectively eliminated your frontend application.
This is what LiveView and other new tools are enabling: rich & highly-interactive web apps driven entirely from the backend. For the rest of this article, I’ll refer to this approach as SSR+. That’s not a standard term for these next generation SSR projects, but I’ll use it differentiate them from the other, non-interactive SSR solutions.
SSR+: LiveView & Friends
LiveView is a server-rendered library for the Phoenix Framework written in the wonderful Elixir language. When a page is requested, it returns the fully rendered content, just like an old-school web app. But after the page is rendered, a persistent Websocket connection is maintained under-the-hood to dynamically update the page based on the server’s application state.
If you’re familiar with how React components are rendered using declarative templates that update automatically whenever state changes, LiveView works essentially the same way.
If you’re familiar with how React components are rendered using declarative templates that update automatically whenever state changes, LiveView works essentially the same way. The difference is that LiveView runs fully server-side, and the “state” we’re referring to is not some local browser data store (like Redux, for example), but is derived from actual backend server state.
What this means is that as data changes on the backend, views can be automatically re-rendered and delivered to the frontend, without the developer dealing with API calls, polling, synchronization, etc. And just like frontend frameworks that use DOM-diffing to only re-render what’s necessary, LiveView pushes out only pieces of the page that are updated when state changes.
Benefits of Server-Rendered HTML
There are many benefits, and of course some downsides, to an SSR+ approach. Let’s explore a few.
Simplified state manage — no client/server synchronization issues
With SSR+, there’s only one source for application state: the server. Any changes that happen on the server are immediately and transparently pushed out to the client. Likewise, client interactions are immediately handled as evens on the server. The server then simply renders what the state of the client should be, and updates are automatically synchronized to the browser.
Not just a single language — a single application
Some developers like using Node.js because they see a benefit in using a single language on both the frontend & backend. Sometimes there’s even some level of code reuse. This is great in theory, but the reality is that you’re still dealing with two logically separate “applications”: a frontend and a backend which communicate via an API. In my experience, code sharing between the two applications is real, but often not significant.
Using a server-rendered approach, you are truly dealing with a single application for your front- and backend, typically with far less code than required to build them separately. This has massive benefits for the development lifecycle. There’s no time or effort spent on building & maintaining APIs or dealing with synchronization issues on the frontend as those APIs change, not to mention the general overhead of maintaining two projects vs. one.
Faster Load Times & Better SEO
Challenges with SSR+
In spite of their benefits, server-rendered apps aren’t right for every single use case. Here are some of the challenges you might face in developing an app with the SSR+ approach.
No offline functionality
Poor network connectivity & latency issues
This is related to the previous point, but represents a much more common scenario: when network connectivity is poor, performance of an SSR+ app suffers as the server is unable to push updates out to the client in a timely fashion.
Real-time interactions & animations
Frontend integrations & browser APIs
Server load & scalability
A benefit of the traditional client/server approach is that you can effectively offload a great deal of processing to the client. With server-rendered HTML, that cost is paid by the server — every meaningful DOM update on the page involves the server pushing updates out to the client. As the number of clients grows, the load does as well.
How big of an issue this is will depend entirely on the complexity of your application. Don’t automatically assume that the performance will be much worse than an API-driven approach: after all, processing API requests, rendering to XML or JSON and then formatting on the client can all be expensive operations as well, so skipping a couple of steps and rendering directly to HTML on the server may not necessarily be any worse. Just be aware of the potential for increased load and monitor accordingly.
Which approach should you use for your next project?
Even if SSR+ isn’t the right approach for a project you’re working on right now, I would encourage to keep an eye out for the opportunity to give it a try, just to learn more about how it works and to get a visceral feel for the tradeoffs. Whether end up using SSR+ or not at the moment, it’s a very interesting development in the evolution of web architecture and worth keeping an eye on.