Why Single Page Application Views Should be Hydrated on the Client, Not the Server

Recently there has been some high profile chatter promoting server-side rendering over client-side rendering. The argument made by Peter-Paul Koch and Tim Kadlec is client-side MVC frameworks take too long to initialize and bind data to markup. Kadlec and Koch are not alone I have run across several others preaching against client-side rendering over the past year, some were clients and others developers and architects. After at least 6 years of relying on client-side templating I have to disagree.

Client-side rendering provides a better user experience, but you need to architect your client application properly. Unfortunately the vast majority of web developers still think in terms of server architecture when designing their modern, client heavy applications. Those of you who have attended my presentations or possibly read my SPA book know I approach things very differently than the 'main stream'. The reason is simple, my approach is user first and that means performance is a primary goal, not developer comfort.

The recent discussions point out some of the issues I have with Angular and other god frameworks. In short they are big, bulky and poorly designed. They cause an unhealthy performance hit. Tim Kadlec points to research done by The Filament group showing how much of a hit these god frameworks are to a web application's 'boot' time. Koch references a Stanford study showing the impact jQuery has on battery life, its bad. Before I go deeper I want to summarize Kadlec and Koch's argument.

Defining the Server-Side Rendering Argument

When a web page is composed in the browser a request is made to the server for markup. This markup is a set of instructions telling the browser how to compose and render the 'page'. Within the markup are references to CSS, Scripts and Images and possibly some other resources. The browser must download these files, then evaluate them. For CSS and JavaScript evaluation means parsing the code to build things like the CSSOM and an in memory instance of the JavaScript. For images the files must be downloaded, uncompressed and rendered. Even when these resources are inline the browser must still do the evaluation step.

Modern web applications tend to rely on making AJAX calls to retrieve data. This data is processed by the application's JavaScript and then bound to the markup, producing the rendered product we all see in the browser. When a page or application is loaded these steps can be very time consuming. If you look at the Filament study over a 3G connection just reaching the evaluation point for popular frameworks takes around 5 seconds. Of course that is unacceptable. Research has proven to us a good user experience is a 1 second load time. After that threshold our customers begin mentally disengaging. By 3 seconds half have already left to try out our competition.

By rendering the markup on the server the browser can render the page much faster. And for a classic web site this makes perfect sense. In fact I do this for my core site solutions. A core site is what you should send to a search engine spider and legacy browser. A core site is a classic web site and for a public facing site should be part of your strategy. For a behind-the-firewall line of business application is it not necessary.

Use a Core Site for SEO & Legacy Browsers

You should load a core site if the visitor is using an older browser, like IE 9. To determine if a visitor can run your high-fidelity application do some early feature detection. If they do not support some modern features, then redirect them to the core site.

 <script> var ef = "?_escaped_fragment_="; if (!('querySelector' in document) || 		!('localStorage' in window) || 		!('addEventListener' in window) || 		!('matchMedia' in window)) {  	if (window.location.href.indexOf("#!") > 0)	{   			window.location.href = window.location.href.replace("#!", ef);  	} else {   if (window.location.href.indexOf(ef) < 0) {     		window.location.href = window.location.href + ef;   }  } } else {  	if (window.location.href.indexOf(ef) >= 0) {   window.location.href = window.location.href.replace(ef, "#!");  } } </script>

A core site is a great solution, but it does not solve the scenario described by Koch and Kadlec. In fact a core site is really only useful for a Single Page Application (SPA). Which is my point. If I were developing a classic web site I would render data in markup on the server and not rely on heavy client-side frameworks.

The Difference Between a SPA and a Classic Web Site

However I stopped building traditional web sites a few years ago in favor of SPAs. Several years ago I began being tasked with building rich, fast, mobile first applications. I quickly learned a single page application was the only way to accomplish these requirements. I also learned I had to adjust my approach to building web applications. As I survey other sites and applications as well as working with some of the popular god frameworks I see many mistakes being made.

To be honest there is NO WAY to accomplish performance first qualities using popular god frameworks like Angular. They are NOT designed for SPAs, at least not a performance first SPA. As Peter-Paul Koch accurately wrote, Angular is not designed for the browser, it is designed to appeal to a traditional server-side developer.

"Angular is aimed at corporate IT departments rather than front-enders, many of whom are turned off by its peculiar coding style, its emulation of an HTML templating system that belongs on the server instead of in the browser, and its serious and fundamental performance issues.

I’d say Angular is mostly being used by people from a Java background because its coding style is aimed at them. Unfortunately they aren’t trained to recognise Angular’s performance problems.

I have doubts about Angular 1.x’s suitability for modern web development. If one is uncharitably inclined, one could describe it as a front-end framework by non-front-enders for non-front-enders."

I want to add to Koch's Java background to include .NET developers as well. Basically enterprise developers who tend to specialize in back-end coding.

I agree with Koch. In the projects I have been forced to use Angular I found it to be a hindrance in so many ways. Like he points out here, when I present to a JavaScript user group they cheer my position of no Angular. However at .NET user groups I am met with resistance and often fear. I hear server-side developers praising how easy it is to accomplish X or Y. I just shake my my head because I know X & Y are simple to begin with and actually harder with Angular. They also tend not to see many other issues I find with Angular. Basically they just don't know what they are missing, they are NOT web developers. They are developers that throw a client interface together to interact with their back-end. They do not have the same set of expectations I place on my applications.

Building A SPA Correctly

I got a formal start on modern SPAs before these god frameworks were a thing. I had nothing to reference. I had a set of requirements, all focused on user experience. This meant performance was the #1 thing. In fact users want 2 things, easy navigation and speed. Developers can do some things around navigation, but we can control performance completely. It is our thing.

So what about the rendering issues highlighted by Kadlec and Koch? Single Page Applications are a new breed of web applications. The server has no clue what 'page' should be rendered. If you load an application with a deep link or traditional URL with a long route, the user will always load that page first if they bookmark the site. This includes when the user adds the application to the home screen. Anytime they share a link the wrong page is initially loaded before the right view is rendered. This is not a good. You need to only load the application via the domain or single core URL, not a variety of possible URLs.

I have had several SPAs that need to determine what view should be rendered first. If the user is authenticated take them to X, if not then to Y, if authenticated and A is true then take them to view Z. Again you cannot predict what content to render on the server.

Instead you should render the core layout and fill in content. Of course this is what Koch and Kadlec are preaching against. Unfortunately it is the reality for the initial application load. This is why I have designed my SPAs to persist my view's markup in browser storage. I also devise caching strategies for my data. This means on subsequent loads everything is ready to go.

I have tried over and over to find a good way for an 'instant' start. But with a SPA you have to load the application. I don't think this is a bad thing. If you compare it to a native application we are still thousands of times faster than their initial load. Sometimes I count native application initial load times in minutes as I am waiting on everything to download. My applications are typically in the 1 second range on the desktop and 3-6 seconds on cellular connections. Of course there are times when I network latency kills you, while there are things you can do to help, you are at the mercy of the wireless infrastructure.

Every time you visit a web page you must install it, that is the nature of the web. A SPA reduces the installation to a single time, where visiting a classic web site involves multiple installations as you navigate through the site. My approach is to reduce this initialization to 1 time, the very 1st time. After that the application quietly updates in the background, without hindering the user experience.

Another advantage I have is I do not use any of the god frameworks. I have written some libraries and use other small libraries as needed. This keeps my JavaScript footprint small. For small SPAs I can easily use less than half that of Angular alone. Even my large applications are smaller than Angular, plus they are broken into pieces, making the initial load small.

The 14k Strategy

Something I am in the process of refining is a 14k strategy. Over the past couple of years the web performance community has determined 14kb to be the largest amount of data to send across the wire for an 'instant' experience. This is based on TCP slow start. The idea is to get everything you can in 14kb because this will fit into the initial packet sent across the wire for an HTTP request.

I plan on isolating the markup needed for the application's core layout, possibly initial view and inlining initial CSS. The only JavaScript I plan on sending is the core site check I shared above. Because the markup tends to be small, in fact the HEAD is always larger than the BODY content, 14kb is very easy to achieve.

The next phase is application bootstrapping. This involves downloading the additional CSS, JavaScript and markup to drive the application. Here I also think a layering approach works best. While most applications are very small, a few are large. For small applications I can still get away with inlining all the view markup, think 5-10 view SPAs. But I like the intent of the web component HTMLImports, the execution however is not effective. So I am finishing a custom 'module' loader for a SPA (hopefully this week).

Without getting too deep, the web application should be designed to load fast, use perceived performance as an asset and leverage caching to load 'instantly' after the first access. Yes it is not simple, SPAs are not simple today. As time goes on these techniques and architectural decisions will be second nature. The good news is I got there before the masses and have been working on these issues for several years.

Once the application is loaded views are instantly loaded, depending on the speed of the AJAX call. When proper data caching is leveraged even that is avoided after the initial request. If you can, you can even pre-request data and have it ready to go. I sort of do that in the movie application I use in my book. While the live version is not 'up to date' it still loads fast. I plan on refreshing it soon with some updates to make it even faster in the near future.


While I get Kadlec and Koch's arguments I disagree with them within the context of a properly architected SPA. All software is full of trade offs. My trade off is a slightly slower initial rendering for instant rendering there after. Angular, Backbone, Ember, etc are often being misused and we are seeing a proliferation of poorly developed web clients today. These applications continue to give the web a bad reputation, when the web can and should be better than our native competition.

Peter-Paul Koch and Tim Kadlec are folks I consider influencers, especially to me. They do some awesome research and provide invaluable tools that drive the web forward. On this topic they are partially correct, in the context of a classic web site you should render everything on the server. When developing a proper single page application stick to client-side rendering and use a core site where appropriate. If you are building a classic web site, please rendering all markup on the server, evaluate if you even need frameworks like Angular and always put performance and your end user first.

Share This Article With Your Friends!