Numerous studies have shown that even modest improvements in latency can have measurable impact on usage. As such, sites should have aggressive goals for both actual and user perceived latency.

The most obvious metric is load time: how long does it take for a page to appear in front of the user. This is influenced by many factors, including DNS lookup, network speed, and how many resources need to be loaded before the page is visible (stylesheets, javascript, images, fonts), etc.

Sites will often optimize and minify stylesheets, combine images into a single sprite, defer loading of javascript, and serve static files from a CDN. All in order to speed up load time. This is great. And once all the resources are cached by the browser can lead to pretty snappy feeling sites.

However, even with cached resources the browser still has to re-parse and execute the CSS and JS on every page load, it still has to lay out the HTML and redraw the UI. This slows down the actual navigation but can also add perceived slowness and often introduces a white flash.

The Single Page Application

In order to improve actual and perceived latencies many sites are moving to the Single Page Application (SPA) model. That is, once the initial page is loaded subsequent navigations are handled without a full page load. Additional content is requested via an XMLHttpRequest and using the history API it is now possible to update the location bar so that pages are easily bookmarkable and sharable.

SPAs were pioneered in the mid-2000s by full-on web applications like Gmail and Google Maps. These days the approach is widely employed by the likes of Facebook, Twitter, GitHub, and Flickr. While these examples all feel kinda app-y, the SPA model isn’t the sole domain of web applications; sites with more traditional layouts can still reap the benefits, and as content sites are becoming more and more interactive the boundary between the traditional web and web apps is blurring.

Technologically Medium is a single page application but it is intended to feel like a traditional website. We use a hybrid rendering model in an attempt to get the best out of both worlds.

Hybrid rendering

Web applications like Gmail do all their rendering on the client: the browser loads a bundle of JS, requests the data, and then generates HTML or DOM dynamically. This approach is more appropriate for applications that are intended to be left open for long periods of time, because it initially takes more time for content to get in front of the user, as they are left waiting for code to load before the UI can be rendered.

The hybrid approach is to allow both the server and the client to be able to render pages. Server rendering allows us to get content in front of the user even before the javascript has loaded. It has the additional benefit of allowing pages to be indexed by search engines. Client rendering means that subsequent navigations are less heavy; there isn’t a full page load and fonts, javascript, and CSS don’t need to be re-parsed.

For Medium there are actually several ways we render pages:

Client-side only. This is for pages that don’t need to be indexed and are rarely landed on directly, we just do what I described for Gmail above.

Server-side & HTML fragment. Often known as PJAX, the server is set up to be able to render a page fragment with or without the common chrome. Client-side navigations simply request the fragment and inserts the HTML into the content pane.

Server-side & templated views. It turns out that often times we need to present data in more than one place and we need to make sure the UI is consistent. In these cases we request data via JSON and store in an event-based store. UI is rendered using templates that generate HTML and when the data changes the templates are updated. When the server renders a landing page, it sends both the HTML — which is parsed and laid out quickly — and data embedded as JSON, which avoids having to re-request the data or needing to pluck the data out of the DOM piece by piece.

Performance benefits

For Medium, we measure performance using the Navigation Timing APIs.

Our initial load time currently averages around 2 seconds, which is certainly something we want to improve on.

Subsequent navigations are usually below 500ms which is way more reasonable but still has room for improvement. We need to do a round of server optimizations, but the SPA model also allows us to improve on these latencies through smarter caching on the client and preloading.

Other benefits

As well as allowing you to speed up the site, the single page model gives affordances for more intricate interactions. We are already starting to see sites move beyond traditional page-based transitions.

“Infinite scroll” is probably the most commonly seen variant. Though even with a SPA infinite scroll is easy to do wrong, both Facebook and Google+ lose your place in the list when you navigate to an item and then use browser-back. Quartz offers a subtle variation on the traditional infinite scroll, but may actually be confusing at first.

Pinterest uses a modal style dialog if you navigate to an item from one of the boards, the browser location is updated to allow deep linking, browser-back takes you back to the board.

Artsy takes advantage of the fact it is a single page application to do subtle fades between pages, and to slide away navigational elements while the next “page” is loading. 

impress.js while blingy and primarily aimed at slide decks, shows what could be done in an extreme. 

The Future

I don’t think the next-generation of content sites will look like web applications, but I certainly don’t think they’ll feel like the content sites of today. As more sites move to a single page model I’m excited to see how designers and developers will utilize the reduced constraints.