Better Than Bootstrap Javascript: Click Delay

Click Delay

This entry is part 3 of 3 in the series Better Than Bootstrap Javascript

Last week we dug into Javascript Carousels, first analyzing the implementation Bootstrap offers and then examining two alternatives in Flexslider and Slick. We reviewed examples in each and noticed the simplicity of setup as we moved beyond Bootstrap – but that wasn’t enough. Developer productivity and effectiveness is important, but what else did alternatives have to offer?

Ultimately, the user experience was the major differentiator. Flexslider and Slick offered swiping and dragging for navigation, natural animations, and fine tuning for responsive displays. One important differentiator was around user feedback – how the carousel responded to a users tap or click, and the detriment of the click delay.

This weeks post is a bit different in that it’s not specifically comparing a Bootstrap component to an alternative, but comparing the absence of a feature and how you can implement it in your web apps. Let’s get started.

Click delays and the smartphone tap

If you’re an iPhone user, i’d encourage you to visit the Bootstrap website on your phone and tap around on the links and features displayed there. A great example on the phone would be clicking the “hamburger” menu (the three stacked bars you see at the top right corner of the page). You’ll immediately notice the short delay between tapping the menu, and actually seeing the content open or close. Is it loading from the server? Did my action register?

Bootstrap-Delay

Looking at it in action, it’s not painfully slow. Is there really an issue? Is the perceived latency that big of a deal?

Now go to the Google homepage, and click the menu in the top left corner (again, the same “hamburger” style menu, with three horizontal bars). Here, the reaction is immediate. You tap, and right away it slides open and gives you a scrollable list of pages. Tap it again (now moved to the right) and it immediately slides closed.

Google-Tap

The experience on the Google homepage is a clear improvement over that of the Bootstrap site. The Bootstrap responsiveness seemed fine, but then we experience Google’s menu and the Bootstrap interaction feels less natural. The responsiveness of Google’s menu is instant – difficult to distinguish from a native application.

What’s the deal, Bootstrap?

You might be wondering why Bootstrap, being a mobile first framework, wouldn’t take care of something like click delay for you?

I’ve never looked into it specifically, but Bootstrap’s reasons could fall into a few camps – reducing dependencies, inconsistencies between the multitude of platforms Bootstrap tries to support with one codebase, or feeling that browsers will eventually fix the issue for them.

I used to be a jquery mobile user, and their goal is to support as many mobile platforms as humanly possible. They found removing the click delay was problematic while trying to maintain maximum platform support, so they left it as a task for the developer to deal with on a case-by-case basis. Since Bootstrap does the same, it’s up to us to figure out how to approach the issue.

So how can we move ourselves beyond the sluggishness of the Bootstrap site with their click delay to the immediate feedback that we get in the Google example?

Immediate feedback with touch events

The first approach you could take to resolve this might be with touch events. Touch events are fired immediately when a user taps something. Using touchstart, we recognize the users tap and can react right away.


$('.action-button').on('touchstart', function () {
  alert('no click delay');
});

The problem is that this is only useful for isolated interactions. What about regular pre-existing links on the page – do we apply touchstarts to them all? What if we want to prevent the default behavior and perform a different action when something is clicked? How can we apply this to existing javascript code running on the site without modifying it (for instance, how could we improve the speed of the Bootstrap menu)?

Pretty quickly, the depth of the click delay issue becomes apparent. In principle the solution could be simple, but the reality is that it bleeds into all aspects of your site, and can be inconsistent to implement between browser vendors and devices.

Leveling the playing field with FastClick

The most popular approach available to solve the click delay issue is with a tool called FastClick. They take the issue and approach all of the multitude of scenarios for you, all wrapped up in a very simple API.

Since we’re talking about Bootstrap here, I’ll assume jQuery is available and use it to load FastClick once the DOM is ready. You get a reference to the body element (which can be accessed directly from the document object using the body property), hand it off to FastClick, and you’re good to go.


$(function () {
  FastClick.attach(document.body);
});

This is the shotgun blast approach. Everything on your site is now freed of the click delay – buttons, links, click events – all of it. FastClick attaches itself to the touch events that are immediately responsive (similar to what we did with touchstart earlier), and handles the rest for you from there.

Now when you attach a click event to something, the delay is gone. Not only that, but our ability to suppress the default behavior (for instance, a link changing the url of our browser) is also available.


$('.action-button').on('click', function (e) {
  e.preventDefault();
  alert('clicked immediately!');
});

It’s dead simple, and generally it just works.

If we apply FastClick to our Bootstrap example from earlier, we now have the same responsive feel that the Google homepage gave us.

Bootstrap-Fastclick

Alternative to FastClick: device-width

You might notice that when I first talked about the issue, I said “If you’re an iPhone user…”. That’s because outside of the iPhone, there are some alternative approaches that browsers and devices take to the click delay.

If you’re on an Android phone, check out the sites I mentioned earlier (Bootstrap and Google) in Chrome. Depending on your Android version, and which provider released it, you may not experience any click delay. This is because some browser vendors have been introducing ways to avoid click delay when your site meets certain criteria. In this case – if you define your viewport as being the width of the device – Chrome on Android will remove the click delay for you.


<meta name="viewport" content="width=device-width">

In general, this is an important setting for mobile-first sites, and a Bootstrap recommendation. Having a width of device-width means your viewport width is based on the device you’re using. So if your site is responsive, and the width of the viewport is device width, you’ll get a display that is better suited to the device.

On Chrome on Android, they piggy back on your viewport setting to mean you don’t need tap-to-zoom, and they remove the click delay for you automatically.

You can read more about this here. That article is also nice because it mentions approaches that apply to Windows Phone as well, which works by a different set of rules from iOS and Android.

Why wouldn’t I always use FastClick?

Learning about FastClick might seem like a good point to stop the discussion, apply it to your site, and call it a day. And in many ways, it could be. If you have a responsive site using Bootstrap and you want to remove click delay across the board, this is the way to go.

There are some warnings here, though. FastClick works really well, but like any project it is continually in development, and it can have issues. New versions of mobile OS’s come out and break things. The browser vendors are not expecting FastClick, they implement their own behavior, and edge cases arise. FastClick meets the browser, meets the rendering and javascript engines, and on the fringes of functionality things can breakdown.

In some cases, FastClick can also impact other plugins. At the time of this writing i’ve had issues personally getting FastClick and Select2 to play well together, and have had to patch FastClick to bypass the issue. This is something that could happen with other libraries as well, who may try to eliminate the click delay issue themselves, or just have some other scenario which ends up conflicting with what FastClick is trying to do.

There’s also the question of whether this user experience matters to you at all. If your site is heavily content driven, and most of the interaction is through clicking links – you may not want to bring in another library just to remove a click delay which only happens as the user intermittently clicks things. Perhaps in this case just manually applying touch events when appropriate is the better approach (for instance, to improve a specific scenario like a carousel, but not to remove it from everything across the board).

The important thing to consider if that FastClick is a tool, and you should weigh the benefit of the tools that you use, and test them on your site. If you’re creating a web experience that needs to give the user a native feel – I’d encourage you to use FastClick. Just make sure you do your due diligence and test your site before pushing it off into production.

Should I always use device-width?

If you’re designing responsive, mobile-first sites using Bootstrap, then you should definitely be setting the device-width on your viewport. But in terms of its impact on click delay be careful, and understand the extent to which it’s available. If you have some sense for what browser or devices you’re deploying to, test to see that it actually works.

I’ve encountered situations where it didn’t work, even when it was supposed to. I had a client with a lower-end Android tablet being deployed to their userbase running Android 4. We were having the client use Chrome and the click delay was supposed to be removed. It wasn’t. Even applying FastClick we still had some work to do – FastClick tries to intelligently disable itself if it detects a browser and device which should have click delay disabled natively. In the end we had to apply a minor patch to FastClick to remove the check for the native feature.

Approaching the problem differently with FastActive

A very different way of approaching click delay is to solve the problem by altering the users perceived performance and offering immediate visual feedback, even if the actual result of the interaction is not immediate. This can be achieved by using the FastActive library.

It applies an .active class to links and inputs, so you can create the appearance that they are reacting immediately (through CSS). This may be an alternative for you if you do not want to risk platform related click issues, and are more concerned with the users perception of performance.

Conclusion

You’ll notice that i’ve talked at length about user perception and interaction in this Bootstrap series so far. This is because despite my love for the web and its potential, the experience of native is compelling and fluid and fast, and the web struggles to compete with this out of the box. More and more people have an expectation of performance, regardless of whether they’re in an app or in their browser. The app experience creates high expectations, and that expectation still remains when using the web. How we deliver on that expectation is through tools and approaches like these.

If approaches like flipboard’s react-canvas are any indication, ios has raised the bar and users are expecting beautiful interactions. Flipboards approach was about flawless animation and scrolling. Click delay wasn’t even discussed in this situation because it’s so basic as to be taken for granted – it’s just not an option. When I hop out of a native app where I can swipe, tap and scroll with ease into a website where I click a link that takes 300ms to register, I feel it. And if your app is trying to compel your users to continuing using it, that may make the difference between them coming back or choosing something more compelling (or ditching the web entirely, and using a native app instead).

Series Navigation<< Better Than Bootstrap Javascript: Carousels
  • Christian Weyer

    Nice post.
    What exactly did you do to patch Fastclick to make it work with Select2?

    Thanks!

    • Unfortunately you’ll prob have to mod FastClick a bit – there is a pull request related to it here: https://github.com/ftlabs/fastclick/pull/308

      The FastClick folks used to think it didn’t make sense for them to fix it, but seem to be coming around to the idea. Hopefully this will get merged at some point (though complaints and PRs have been circulating for this since 2013 so your best bet is to try and apply the PR yourself).

      • Christian Weyer

        Thanks!