Saturday, February 16, 2013

Why isn't our warning banner based on feature detection?

In my last post, I showed how we display a banner above Coursera to users on explicitly unsupported browsers, to warn them that the site is known not to work well on them.

After my post, Kyle Simpson, a well-known web developer and creator of the talk "Browser Versions are Dead", put together a post about why he thinks browser version detection should be avoided, and feature detection should be used instead.

He has some great points in it. Generally, the web developer community is trying to move towards using feature detection instead of user agent sniffing to warn users and degrade website functionality. We try to do that at Coursera where it makes sense for specific features (we deliver video via Flash if you don't have native HTML5, e.g.), but we determined that it's not practical to do that for our cross-site warning, for a few reasons:

  • We would have to test for *a lot* of features, and those tests would take time on page load. We could cache the results of those tests in a cookie or localStorage, and so there would only be a one-time cost. But if the browser upgraded and suddenly did start supporting a feature, we would need to know to re-run the tests - and as far as I know, the only way to know about a browser upgrade is via user agent sniffing and some knowledge of how versions work.
  • We couldn't just tests for features, like "does canvas work", we would also have to test for performance. We've seen some older browsers simply can't handle the amount of JavaScript that we use or simultaneous XMLHttpRequests that we send off, and they will hang. How does one test for a hanging browser yet still recover? I imagine it's possible, but I don't know if it's easy.
  • I have personally been bitten by feature detection in the past and now approach it cautiously. There are some features that developers have put a lot of approach into figuring out rigorous feature testing for, like all of the tests in Modernizer.js, but there are other features that are newer and whose detection quirks are less known. For example, when I tried to use FormData for sending a form, I checked for the existence of it on window. Unfortunately, it existed in Safari, but Safari wasn't actually setting the data, and since the FormData API had no accessors, there was no way that I could feature detect it. I resorted to user agent sniffing instead, blacklisting that Safari version for that feature. That is just one example, and there have been others.
  • We have limited resources. Yes, we could try to solve the problem of doing performant, comprehensive feature detection tests, of caching them and figuring out when to update our cache, doing performance tests, and determining the cross-browser feature detection technique for every single feature we use. Or, we could focus our time on our actual product, and decide that it's okay to say "Alright, we know we don't work in these older browsers, so let's just tell users what we know."

Something that I've come to appreciate in my last 8 months as engineer is that we can't always do what's perfect and ideal. Sometimes, we have to do what is practical and be cognizant that there is a better way, and when the time has come, try to move to the better way.

No comments: