Tuesday, December 16, 2014

Death by a thousand cuts

The Legionnaire that scoffs at a lasgun has not charged across an open field against a hundred of them.
Maor the Scarred, Siege-Champion of the Scargivers, Warhammer 40,000: Black Crusade

A large part of building a website that gives the users the best experience possible is fending off a death by a thousand cuts - usually introduced through practices and design patterns that are sanctuaries for inefficient code and unnecessary complexity. Today I offer you a simple example that will show (on a small scale) how poorly things can be written using code generated by the Demandbase Ad Code Generator (I've changed the user ID to 'no-names' to protect the user - the number of bytes in "no-names" and the user ID hash are the same, though).

Here is their code:

<!-- Demandbase Advertising Code --><script>(function(d,b,a,s,e){ var t = b.createElement(a), fs = b.getElementsByTagName(a)[0]; t.async=1; t.id=e; t.src=('https:'==document.location.protocol ? 'https://' : 'http://') + s; fs.parentNode.insertBefore(t, fs); }) (window, document, 'script', 'scripts.demandbase.com/no-names.min.js', 'demandbase_js_lib');</script><!-- End of Demandbase Advertising Code -->

Wow, that looks complicated; it must do something pretty cool. Let's prettify it and add line numbers so we can figure out what it's actually doing and be amazed at its compact (403 bytes of) awesomeness. I'm going to be a little careful here, because there's a rather threatening message on the Demandbase Ad Code Generator page that tells us clearly not to "alter this code"...but I'm just explaining it for educational purposes, not running it in production (which I would never do, by the way), so I'm going to risk it under fair use.
  1. <!-- Demandbase Advertising Code -->
  2. <script>
  3.   (function(d,b,a,s,e){
  4.      var t = b.createElement(a),
  5.        fs = b.getElementsByTagName(a)[0];
  6.      t.async=1;
  7.      t.id=e;
  8.      t.src=('https:'==document.location.protocol ? 'https://' : 'http://') + s;
  9.      fs.parentNode.insertBefore(t, fs);
  10.   })(window, document, 'script', 'scripts.demandbase.com/no-names.min.js', 'demandbase_js_lib');
  11. </script>
  12. <!-- End of Demandbase Advertising Code -->

Ok, now that I've prettified it, let's dig into the code.

I'll ignore lines 1 and 12 because those are just comments to let us know that this is Demandbase code, and the only comment I have about line 2 is that this line is one of the good things about this snippet - it doesn't bother to use the language or type attributes. One of the other good things is that the author of this snippet wrapped it in parentheses, making it a self-executing function so at least you don't have to add more code to your page to get it to work.

Line 4 creates a script element and line 5 gets the first script  tag. lines 6 through 8 set various properties on the script element (created in line 4), and line 9 adds the script element to the DOM. Line 10 kicks off all this awesomeness by calling the self-executing function and passing in all the data used to set the properties of the script element in lines 6 through 8.

Just so you won't have to go through and figure out what properties are being set, here's the tag that's generated by this code (assuming it's run on a page using http as the protocol - if the page is using https, the src attribute of the script tag will match the protocol).

<script src="http://scripts.demandbase.com/Hwd8TqVa.min.js" async="1"></script>

That's not so bad, right...after all, async is specified, so the external script will be downloaded and executed asynchronously (except on versions of IE less than 10 and versions of Firefox less than 3.6).

Hey, wait a minute...the tag is only 79 bytes (80 if the protocol is https)...and that's way less than 403. Oops. Of course we can make it even shorter in a way that is protocol agnostic, and we can reduce the page weight even more if we ignore XML rules and use HTML validation rules instead.

<script src="//scripts.demandbase.com/Hwd8TqVa.min.js" async></script>

Now it's only 70 bytes and works for both http and https without a problem. Further, using the tag directly not only means you've reduced your page weight by 333 bytes but also means your page is not blocked while the little Demandbase function - which is supposed to be placed at the top of the page - is trying to run, and it's immensely more friendly to attempts to debug problems with your page.

At this point you may be asking yourself "what is the advantage of using the code generated by the generator" - and that's a good question. There are no advantages to using their code, but there are potential disadvantages, and even worse, the generator could generate better code - code that doesn't have some of these disadvantages - but it doesn't.

Code like the code in today's example is poor writing - and I'll be honest, there is a lot of code out there of the same low quality - and poor writing will, in the end, lead to a slow and torturous execution - a death by a thousand cuts. We only use it because we either don't know better or we don't care (which would say something about our GSD attitude). Raise your game - avoid the unnecessary complexity - keep your writing clear and concise - do this, and you will be much happier in the end.

Happy coding.

No comments:

Post a Comment