Using Turbolinks with Typekit and Google Analytics

This week I decided to try out Turbolinks here on my blog in advance of its inclusion as a part of Rails 4.0. With as simple as my site is, I didn't expect there to be much of an impact overall. But I was mistaken.

After adding Turbolinks, I saw a huge increase in the speed of my site. Page loads felt almost instantaneous upon clicking a link, and got even faster as Turbolinks cached requests. The documentation claims that Turbolinks will increase speed by 2-3 times, and though I don't have any hard numbers I can attest to the noticeable zippiness.

The only problems I encountered were when trying to get Turbolinks to play nicely with Typekit and Google Analytics. Typekit was causing Turbolinks to invalidate its asset cache and do full page refreshes instead of using pushState. And Google Analytics was not tracking page views after the initial one.

To compound the issue, I experienced a “Google drought” when searching for possible solutions. Fortunately, I was able to piece together a solution for both problems myself using what I did find. I hope by documenting them here I'll save someone else that trouble.

As far as I can tell, the key is to make sure that Turbolinks is included after any other referenced JavaScript files but before any inline JavaScript. Otherwise Turbolinks will do full-page reloads every time because it thinks that the assets have changed.

In the case of Typekit, their snippet involves two components: an included file from their server and an inline script to load the fonts. The former should come before application.js (which is where Turbolinks will be loaded if you're using the asset pipeline) and the latter should come after, like so:

%script{ src: '//use.typekit.net/<your_id_code>.js' }
= javascript_include_tag 'application'
%script try{Typekit.load();}catch(e){}

The Google Analytics issue is also simple to solve. Since their asynchronous snippet is inline JavaScript which dynamically generates a script tag, make sure to include it after Turbolinks. Then, to track page views whenever Turbolinks updates the page, add the following line to the Google snippet:

document.addEventListener('page:change', function() { _gaq.push(['_trackPageview']) })

This hooks into a custom event that Turbolinks fires each time the page is updated (page:change) and ensures that Google is called each time as well. Fortunately, since every browser that supports pushState supports addEventListener as well, you don't have to worry about cross-browser event handling.

That's it. By getting everything in the right order and adding one simple event listener, I was able to reap the speed benefits of Turbolinks and still use the external libraries I needed. I hope this post saves somebody a little time and frustration.

One Resource to Rule Them All?

Friday, the Develop with Purpose blog published my latest post, which is about WebPlatform.org. I'm linking to it here and additionally offering a translation.

Real Artists Ship

I am a perfectionist.

People who know me well can attest to that. Being both a task-oriented and detail-oriented person is kind of a perfect storm for perfectionism. Whatever I'm working on, I'm always asking myself if it's really good enough and if I did it the “right” way. That can be very exhausting.

The late Steve Jobs is credited with saying “Real artists ship.” (Is it just me, or is it still weird to say “the late Steve Jobs”?) That's a pretty tough concept for me in my perfectionism. Steve Jobs was the perfectionist's perfectionist, though, so I'm not really sure what he did to cope. Not even Apple ships perfect products.

Shipping a product means making a commitment. I probably wouldn't describe myself as someone who is afraid of commitment, but I am often afraid of shipping. It's hard to commit to a concrete standard of quality in both content and execution.

Over the last couple of years I've gotten better at getting past the “is it ready” hurdle. In fact, I've become quite vicious when it comes to stripping things down to the very basic idea that needs to come out. After all, once you execute well on the basic idea, from there it's all about iterative improvement.

It's that “is it right” question that haunts me the most. I am obsessed with so-called “best practices.” I like to see that my approach is the one that most people consider to be the correct one. Finding a workable approach just isn't enough if I suspect that there's a better one.

Obviously there is a balance to be attained. The Develop with Purpose team has a saying that the balance between perfection and production is called “excellence.” I've tried to take that principle to heart in all of my work.

And so, it is in that spirit that I humbly embark on this journey of blogging. My blog may not be feature-complete and I may have made some mistakes in the execution, but I am making the commitment to my work that shipping it requires. This is only version 1.0. There will be more versions to come.

Real artists ship, so here goes nothing.