Daniel Allen Deutsch

Web Developer


Browser Compatibility Is No Joke

December 20, 2016

There is nothing I like working on less than fixing browser compatibility issues 1.

It would often go like this: I'd get to work and all would be well in the world. Then we'd get a bug report like, 'the progress upload bar doesn't work in certain versions of Internet Explorer'. Then all would not be well in the world.

There are a few reasons these are so un-fun. These problems were difficult to debug, solutions were a pain to test across browsers, fixes would inelegant if-elsif-elsif-elsif hacks, and it didn't feel like productive work.

So, well, I'd whine. "Do we really have to support IE8?" I'd say.

My boss should have told me not to complain so much. But he was kind, so he'd open some metrics.

We'd look at the percentage of users on different platforms, both globally and using our application. Sure enough, the number of people affected by the bug I didn't want to fix was not even close to negligible.

So I'd fix it. But I'd sigh, and think bad things about Enterprise Software.

Fast forward. I've been building more hobby projects recently. One of the nicest things is that I get to choose what I support.

IE8? No way. I'm building things for myself and my friends. If there are a few edge cases that aren't well handled, 1. the world won't end 2. the people I know use modern web browsers.

I thought that these were safe assumptions. Nope.

I'm building a small web application written in Go. It's more complex than a 'Hello World' website, but it's fairly simple.

I built it to the point where it worked. It wasn't styled and was missing obvious features, but the core functionality was complete. So I sent it to 3 people 2.

It worked for one person and did not work for the other two. Additionally—it didn't work for those two people in different ways.

This is a major bummer; I built something that doesn't work for the majority of users. WTF? We'll dive into what happened on a technical level in a minutes. But here is what I learned:

Browser compatibility problems are no joke. They exist as soon a web application is one hair more complex than trivial. They cannot be dismissed as enterprise problems. And rather than treating them as rare edge cases, they need to be thought of as first-class problems.

One the one hand, this is disheartening. There is no such thing as a 'quick project that will work 95% of the time'. One the other hand, this is the state of the web. So I'm changing my attitude: better to account for the differences and build things properly than any alternative.

Technical Learning

This first one is actually kind-of my fault. But still. I assumed that SSL/HTTPS is such a standardized and regulated thing that it would be consistent across platforms.

(I want to lie and say them I implemented HTTPS so early in a hobby project because I always follow best security practices. In truth, I am depending on a JavaScript function that won't run from an insecure origin.)

I installed a certificate from Let's Encrypt 3, and plugged the location of the cert and key into the proper Go function. HTTPS worked nicely everywhere, except it didn't work at all on Android Chrome 4.

It turn out I was using the 'key' and not the 'full-key'. The full key provides details about the intermediate certificates. I wrote up the details (with links to even more details) on the Github issue.

This makes sense (or enough sense, without knowing much about SSL). But the difference surprised me.

It's all in this chart. All browsers support MP3, most browsers support Wav, fewer browsers support Ogg.

I am using a JS function to record an audio file from the user's microphone. This does not return an MP3 format.

To get this working everywhere, I convert all files on the server to MP3 using FFmeg 5.

This is nothing new, but different browsers support different JavaScript functions. My application is dependant on MediaDevices.getUserMedia(). (I want to access the mic without a third-party library.) Unfortunately, there is no support for Internet Explorer and Safari.

If you use an unsupported browser, my web application displays a "Sorry, you are out of luck" message. Better than buttons not working, but still sad.

I don't know if certain browsers don't support this feature because they consider it a security risk or if it is coming in future versions.

Chrome and Firefox, for example, both support MediaDevices.getUserMedia(). However, capturing the audio was working on Chrome and not working on Firefox.

Digging into it, Chrome captures the audio and breaks it into chunks a few times a second—constantly breaking the recording down into small pieces. Firefox just delivers one big chunk.

As a result, Firefox needs a second (more accurately, about 3 milliseconds) to get the file ready after the recording is stopped. I was trying to send it immediately, so I updated the code to wait until the chunk list is ready 6.

Again--I had no expectations about the implementation details. But I did not expect them to be so different.

Consider yourself warned 😁
1 That isn't exactly true. Because timezones.
2 Moms™: the ultimate beta testers.
3 Let's Encrypt is awesome. They give you SSL certs for FREE, they make it super-simple to install, and they are helping HTTPS everywhere become possible.
4 It still seems crazy to me that it worked on Desktop Chrome but not Mobile Chrome.
5 I was not familiar with FFmpeg, so this was a bunch to figure out. But it was easy to install (just apt-get or brew install) and works great.
6 If I was a decent JavaScript developer, this seems like perfect use for a callback or promise. But because I am not, I just retry every 25 ms until it's ready.

Have anything to say? Questions or feedback? Tweet at me @cmmn_nighthawk!