Hybrid Static: A New App Architecture

Roots it a projects that's been in the works for years, both in my free time and as a primary component of my job at Carrot. While it was at first intended to be a way to speed up build times for smaller static sites, it ended up evolving into something that was much more, and in the latest release we stumbled across what is essentially a new way to build web apps, that's significantly more efficient than anything else we've encountered. We're calling the approach "hybrid static". But before we dive in, let's back up a little so we have some context.

A Short History of Web Apps

A couple years ago, Rails ushered in an era in which apps were built on top of monolithic frameworks that render views on the server side and send them to the client as the user requested them. Rails, Django, Sinatra, Flask, and a number of PHP frameworks were the primary targets for building new websites. Job listings for rails developers were off the charts -- so much so that it spawned an entire industry of "dev bootcamps" to teach rails and help to fill the enormous demand. Server side apps were king, there was no questioning it.

But as there began being a web app for anything you can imagine, developers started to see a new set of issues that Rails and similar frameworks were unable to solve. Users wanted quick, native-like reactions to their actions within an interface, and reloading the entire page, as would be necessary with a purely server-based app, was just not responsive enough. Can you imagine if the page had to fully reload every time you click into an email in gmail? So developers started relying on javascript in order to respond immediately to user actions. But as these interfaces got more complex, the javascript got messier. Wiring together large sets of elements in different places is no trivial task from an architecture standpoint, and a need developed for javascript frameworks to organize these newer, more client-side focused apps, dubbed "single page apps", or SPAs. A new set of javascript tools started to emerge that load the app on the client side and make requests to a simple API on a server in order to quickly update the page. This approach proved to be very popular, and SPAs began to dominate with Backbone, Angular, and Ember as the most popular frameworks.

Now, this sparked a massive change in the architecture of web apps. Previously, a request would be made, the server would compile the page, then return html to the client, with all content fully rendered. With single page apps, a static page is initially loaded with little to no content but a large bundle of javascript. The javascript then makes a request to the server in order to render the content. This makes the initial load time slightly slower, as you need two requests to get the first batch of content (static server -> base page, javascript -> api). However, it pays itself off quickly as subsequent interactions are significantly faster -- in many cases near instant. This is the tradeoff you make when switching from a server-side app to a client-side app. For many, the slight extra tax you pay upfront is worth it, as it does pay itself off quickly down the line, and as of the writing of this article, single page apps are gaining traction much more quickly than server-side frameworks, with Angular.js becoming the "new hotness" that is spawning seedy developer bootcamps around it, much like Rails started to do a couple years ago.

A New Era

Roots introduces the capability to build a different kind of app, one that is a mix between client and server-side rendering. This approach eliminates the shortcomings of both the all-client and all-server approaches by allowing the developer to choose which portions of their apps are compiled as static content, and which portions are loaded dynamically in response to user interaction, while sharing view templates between the two approaches. We are calling this approach "hybrid static". Let's break this down a little bit with an example.

Mojotech just finished building a new version of their company's website on top of roots. Their approach to hybrid static is very interesting. Click around the site a little bit. Note that the initial load is nearly instant -- it's a static html file being served. On top of that, subsequent content is loaded through javascript, meaning only a single http request is made: the one that's made to initially load the first page you view. All other pages are rendered like a single page app. You can see this through the subtle transitions between pages that would not be possible for a traditional page refresh.

As another example, imagine you are building a blog. You can make a very simple blog that's compiled as a static site, but once you pass a certain complexity point, it's simply no longer possible. For example, tags, categories, and search are three features that you cannot implement with a fully static blog. At the same time, blogs are typically infrequently changing, and it's a waste of resources to have a full server response to each request. For large portions of the content, you could just compile the page out to static any time the blog is updated rather than any time a viewer comes to the site, which is what happens with a fully server-side blog. The hybrid static approach lets you break down an app like this such that parts of it are static and the rest is dynamic. So the homepage showing the first five posts can be served as static, and be recompiled whenever a new post is added. But when the user clicks to the second page, it could be loaded from the server like a single page app and rendered into the same template as the first page through the magic of Roots. You can even connect Roots to a CMS like wordpress or contentful to allow non-developers to easily make updates.

How does Roots do this? In short, roots is a static compiler that can be made aware of your site's API and data, and can use a view template to render static content and also compile that template for client-side usage through javascript. This way, you choose which portions of the content you want to have compiled out as static files, and for the rest you can hit your API with javascript and use the same templates to update the page.

This level of control over how you present your content offers a huge number of possibilities, and we're excited to see how developers put it to work. Check out Roots' tutorial videos and docs and build something awesome!