One benefit to sitting at home sniffling on the couch is that I finally had time to watch a DHH talk from 2013 that I’ve had waiting in a browser tab for weeks now. Hidden amongst all the waffling and swearing there was some useful content. To me the key premise was:

  • Rails is optimised for document style apps (e.g. GitHub, Basecamp), not blank canvas style “GUI” ones (e.g. Spotify, Google Maps). If Rails works for your app, embrace the document (constraints can be liberating) but address the speed/latency problems

The key techniques I took away for embracing the document while addressing the (real or perceived) speed/latency problems are:

  • Key-based caching with nested doll approach
Code slide showing how to bubble changes up the model hierarchy
  • Share caches as much as possible, not per user. For example:

    • Cache UTC time, localise it in the view with JavaScript

    <%= time_ago_tag(event.created_at) %>

    renders in the source as:

    <time data-local="time-ago" datetime="2017-09-13T03:02:58Z">Sep 13, 2017 at 3:02am</time>

    which gets decorated by JavaScript to:

    <time data-local="time-ago" datetime="2017-09-13T03:02:58Z" title="September 13, 2017 at 1:02pm AEST">21 hours ago</time>

    • Cache the full page, e.g. including role-specific or time-limited links, and then hide the links from non-authorised users. Even if they view source and see the links the controller will stop them from visiting them. Basecamp uses this to enable you to edit/delete a comment for 15 minutes if creator or admin and after that only if you’re an admin:
      <span data-available-until="2017-08-31T00:19:12Z" data-visible-to="admin creator">
        <a class="edit" ...>Edit</a> or <a class="delete" ...>Delete</a> for <span data-display="available_time_left"></span>
      </span>
    
      <span data-available-after="2017-08-31T00:19:12Z" data-visible-to="admin">
        <a class="edit" ...>Edit</a> or <a class="delete" ...>Delete</a>
      </span>
    
  • Turbolinks lets you swap in a new document body and merge the new document head. Benefit is that you don’t need to tear down and build a whole new JavaScript process.

    N.B. Turbolinks only helps if your underlying app is quick

  • Get native-like live refresh behaviour with a fraction of the complexity by polling for changes and use RJS to respond with fully formed JavaScript replies. Based on GitHub’s pjax approach:

Code slide showing one way to respond to polling requests with fully formed JavaScript replies

Other takeaway:

  • Basecamp’s approach to new ideas is to spike a feature in Basecamp with a plugin and, if the approach/technique works, extract it and generalise it for Rails. This is similar to what Myles has been talking about recently in our little suite of apps; try an approach or a pattern out with a narrow problem area and if it works we’ll generalise it