DEV Community

Marko V
Marko V

Posted on • Edited on

2

"Uint8Array, we need to have a talk." -- IE11

Yesterday's post, where a pre-commit was enforced/distributed among the team, linting errors were found a-plenty. This was to be expected of course, since there were 132000 linting errors in the javascript code that has been growing over the past 5 years. However, 110000 of those are just within the last year.

Hence me trying now to enforce this to get that in control.

So I was approached today by a fellow dev in my team to help him with a linting error that he couldn't understand at first.

It all started with let.

The first error he encountered was a parsing error for eslint. ESlint couldn't get past the "let variableName = {}" so converting all let and const definitions to var. I know what you're thinking.... but this is fine, it's not typescript, it's not es6 enabled either in .eslintrc, so it's by design because let and const, are not fully supported in IE11 and we still have IE11 customers in the application. 30% in fact.

So once all of the "let"s were converted. More issues surfaced of course. Most of which were possible to be resolved with --fix with eslint. So what we were left with were just semantics/styling for the exception of one. Uint8Array.

Now Uint8Array is a ES6 feature partially supported by IE11. Uint8Array however, was used with an iterator constructor, which ISN'T supported by IE11. So the code had to be refactored.

The original block of code.

// IE hack; see http://msdn.microsoft.com/en-us/library/ie/hh779016.aspx
if ($window.navigator.msSaveBlob) {
  let byteCharacters = atob(response.data);
  let byteNumbers = new Array(byteCharacters.length);
  for (var i = 0; i < byteCharacters.length; i++)
    byteNumbers[i] = byteCharacters.charCodeAt(i);
  let byteArray = new Uint8Array(byteNumbers);
  var blob = new Blob([byteArray], { type: 'application/octet-stream' });
  $window.navigator.msSaveOrOpenBlob(blob, filename);
}
Enter fullscreen mode Exit fullscreen mode

After the style-related issues + let/const were fixed. We had this.

// IE hack; see http://msdn.microsoft.com/en-us/library/ie/hh779016.aspx
if ($window.navigator.msSaveBlob) {
  var byteCharacters = atob(response.data);
  var byteNumbers = new Array(byteCharacters.length);
  for (var i = 0; i < byteCharacters.length; i++) {
    byteNumbers[i] = byteCharacters.charCodeAt(i);
  }
  var byteArray = new Uint8Array(byteNumbers);
  var blob = new Blob([byteArray], { type: 'application/octet-stream' });
  $window.navigator.msSaveOrOpenBlob(blob, filename);
}
Enter fullscreen mode Exit fullscreen mode

Not only was the developer that did this inconsistent, because they had a "var blob" in there. Meaning they likely just cut-n-pasted code from elsewhere and joined with whatever was there before.

Also, I think it was entirely untested. When I ran the steps to reproduce this in the IE11 console, instantiating a Uint8Array from another array with data (i.e. iterator) the Uint8Array only took the length of the other array to instantiate itself to the appropriate size, but it didnt take the data. Meaning this code that we had, would not work. It would be an array of bytes where all the bytes were set to 0 and the user, if they clicked on the button tied to this function, would get a very useless file.

To fix this, it was quite simple. The Uint8Array, could simply take the same charCodeAt conversion happening in the for-loop above, directly. So instantiating it to the length of the byteCharacters variable, we just had to fill it with data using simple byteArray[i] = byteCharacters.charCodeAt(i); So we reduced memory usage and fixed a previously untested bug.

Just by linting!

// IE hack; see http://msdn.microsoft.com/en-us/library/ie/hh779016.aspx
if ($window.navigator.msSaveBlob) {
  var byteCharacters = atob(response.data);
  var byteArray = new Uint8Array(byteCharacters.length);
  for (var i = 0; i < byteCharacters.length; i++) {
    byteArray[i] = byteCharacters.charCodeAt(i);
  }
  var blob = new Blob([byteArray], { type: 'application/octet-stream' });
  $window.navigator.msSaveOrOpenBlob(blob, filename);
}
Enter fullscreen mode Exit fullscreen mode

Sentry blog image

How to reduce TTFB

In the past few years in the web dev world, we’ve seen a significant push towards rendering our websites on the server. Doing so is better for SEO and performs better on low-powered devices, but one thing we had to sacrifice is TTFB.

In this article, we’ll see how we can identify what makes our TTFB high so we can fix it.

Read more

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay