UJS, CoffeeScript and Sprockets, oh my.
A quick program note: If you’ve liked the Entropy Essays, I’m doing a virtual Chicago Ruby Meetup on July 7th at 6:00 Central Daylight Time. It’s being streamed via zoom, and you can sign up here. I’ll be tying all those essays together and talking about how they relate. Please do come, it’ll be nice to have you.
And now, on with the show. Please use the inline buttons to share, comment, or subscribe.
When I was in grad school, I worked with a professor who studied what was then called “ubiquitous computing” – what we could do when everybody had instant access to a computing device all the time. We all carried around Apple Newtons, and his seemed amazingly futuristic in 1997. Now we just call it “life”.
rails_ujs library. Rails UJS replaced the
remote_form_for helpers with a remote: true attribute that the helper rendered as a
To some extent that becomes the long-term pattern. While the Rails team continues to evolve their particular way of doing client-side interaction, Rails itself continues to adapt to allow other patterns to be usable.
Rails 3.1: CoffeeScript and Sprockets
The first step came in Rails 3.1, which added CoffeeScript and the Asset Pipeline. Which was a lot for a point release.
Rails 4.0: Turbolinks and Russian-Doll Caching
Rails 4.0 added Turbolinks and Russian-Doll Caching – the caching is a server-side feature but it’s a big part of what is supposed to make Turbolinks work.
Turbolinks was partially inspired by a tool called pjax, which was similar to
link_to_remote in that it automated the process by which you could get HTML from a server and overwrite part of the page. Turbolinks generalizes this and makes the default behavior of all links to go to the server, strip out the body part of the page response, and replace the body in the DOM with the new HTML. This allows you to effectively refresh part of the page without visible flicker, so it enables frequent refresh of partial pages with new server-side HTML. That’s the goal – to make it very simple to get the perceived-performance of a single page app changing the DOM client side while still keeping the basic structure of a server-side application.
But. You still have to make the server side call, and make it very fast, which is where the caching came in. The Russian-Doll caching setup is a clever way to have most of a page be cached except for one particular part, so if you were showing a calendar page, you could break the cache for only one event, and have the rest of the page be cached and the rendering much faster.
My experience is that the caching works really well in the view template, but getting the controller to limit the database calls appropriately so as not to waste database calls is a pain. And I think a lot of apps don’t lend themselves to the Russian-doll structure. You also need to set up routing so that the Turbolinks calls can go to URLs that replicate the client-side state which can also be tricky.
Sidebar: I think a lot of Rails teams could probably stand to cache more aggressively, but caching a) seems like a lot of work in the early days of an app, b) is something whose value is very hard to see in development mode, and c) can lead to a lot of weird and dangerous bugs if you aren’t careful.
I also think there was kind of a “why are they even trying to deny the awesomeness of single page apps” reaction. Especially early on, there was a lot of tech triumphalism around some of the single page app frameworks, and so why would you yell at the the incoming tide?
Next up: Webpacker, Stimulus, and whatever the heck Hey.com runs on.
Comment prompts: Is there a CoffeeScript feature you really miss? Why do you turn Turbolinks off?
And, you can subscribe, which will eventually give you access to some longer subscriber-only posts.