3

I am authoring a lot of plugins for the content management system that I am writing. I believe it to be of utmost importance that script files (especially if they're plugins) should load quickly, which leads to me to the question that I've asked today?

What's more important for plugins, minimizability or readability?

Let's imagine that we live in an ideal world where code is always perfect. Should a plugin (which being perfect, the author doesn't expect the end user to read) be designed so that it takes up as little space as possible, or so that it readable by the end user.

For example, I'm writing a piece of code that spits out HTML and appends it to the body. I have replaced every instance of the tag 'div' with '!' and then used String[replace](/\!/g, 'div') to save four characters (therefore bytes?) for each declaration of a div element.

NB, [replace] is also a declared variable so that when it is minified it will read something to the effect of String[r](/\!/g,'div')

Am I caring too much about download speed or should care a bit more about readability. (IMO, most minifying techniques are easily reverse-engineered, but is it bad practice?)


Edit

Thanks for all the answers, you guys are great!

  • To be clear, this is about logic changes which permit smaller file sizes (after additional automated, semantics-preserving minimization), not about said automated minimization tools, right? –  Jul 14 '14 at 15:30
  • @delnan I slightly lost you, but I'm talking about when I'm writing the code *before* it is minified. – Luke Madhanga Jul 14 '14 at 15:33
  • It sounds like you are over-analyzing things. Are you benchmarking actual performance, or just making changes like that regex because you 'feel' it will make things faster? – GrandmasterB Jul 14 '14 at 15:45
  • @GrandmasterB That's what I was afraid of. I'm currently employing the 'Every little helps' attitude when it comes to files size – Luke Madhanga Jul 14 '14 at 15:46
  • 1
    Possibly relevant - [Premature Optimization](http://programmers.stackexchange.com/a/80092/64132) – Dan Pichelman Jul 14 '14 at 15:53
  • Related, almost a duplicate: http://programmers.stackexchange.com/questions/43151/should-you-sacrifice-code-readability-with-how-efficient-code-is – Doc Brown Jul 14 '14 at 15:55
  • @LukeMadhanga every bit does help, theoretically. But it may not have a noticeable affect. If you are going to optimize, you should measure. There's no point in trying to save 4 bytes when it would not result in any perceivable improvement by the user. – GrandmasterB Jul 14 '14 at 15:58
  • @GrandmasterB All great and valid points from you guys, thanks! By 'every little helps' I mean like when it's a big file. Like in some of my minified code, I've reached 70% compression levels, which can be great if you're not in London and on a mobile and only have 'H' on your mobile broadband! :v – Luke Madhanga Jul 14 '14 at 16:01
  • @Luke Madhanga I think delnan meant that there are automated tools to turn code into static symbol tree and then from that symbol tree, the code can be minimized. In other word, if you want to do code minimization, you should take a book about compiler, interpreter, that will help you. – InformedA Jul 14 '14 at 17:35
  • 1
    Links to 2 free books about compiler that I have seen recently: http://www.stack.nl/~marcov/compiler.pdf and http://www.ethoberon.ethz.ch/WirthPubl/CBEAll.pdf – InformedA Jul 14 '14 at 17:37
  • Note that there's a bit of a contradiction in " the author doesn't expect the end user to read) be designed so that it takes up as little space as possible, or so that it readable by the end user." as written – Michael Durrant Jul 20 '14 at 12:08
  • If your code is all HTML-y then you should look into something like Dust.js -- with a little finaggling you can produce huge strings of HTML from js objects quite easily. – Mark Jul 28 '14 at 04:18

2 Answers2

2

If code were perfect, there would be no need for documentation because it is simple and straightforward, hence there would be no need to optimize for anything other than performance.

However, code is not perfect, and if you're like me, you'll have passed several days pulling your hair out trying to resolve a silly issue with a javascript library. I think the best solution is simply to not decide on behalf of the programmer who is downloading it, but offer both versions equally. The readable version is for those who wish to change existing code and the minified version would be to optimize performance because the code depending on it already does what it is supposed to.

Rarely will you see a programmer want to have code readable to debug, yet fast enough to put into production. If you can get it faster still by reducing it beyond readable levels, you will see that version used in production instead.

The minified version can simply be your readable version that has been minified, so focus simply on writing readable code since the objective is to make your code, well,... readable. Lets do a thought experiment for a moment.

Suppose you can minify your code from 50kb to 10kb. This is a 80% reduction in size, and you could say that, from a bandwidth standpoint, this is 80% more performant. Now suppose you can further reduce this reduction from 10k to 9k if you replace all if statements with tertiary operators. Now rather than an 80% reduction in size, you've managed to achieve an 82% reduction in size.

This said, if you could gauge the readability of your code before and after this change, do you think you would have suffered only 2% change in readability? Possibly, but I would argue that you've lost more. Even if it were only 2% difference, readability is the scope here, not performance. Most of the difference in performance comes from that 40k reduction using minified, and very little is gained for that single change.

That said, maybe don't create large blocks of code that will never be run.

Neil
  • 22,670
  • 45
  • 76
1

By doing this, you actually are reducing both the readability and the extent to which the plugin can be minified.

Let's take your example of your HTML string by getting a HTML file with some <div> tags. Running some sample code through a minifier, we get 380 bytes before gzip for the first one:174

var a="<div>a</div><br><div>bc</div><br><div>def</div><br><div>ghij</div><br><div>klmno</div><br><div>pqrsjt</div><br><div>uvwxyzA</div><br><div>BCDEFGHI</div><br><div>JKLMNOPQR</div><br><div>S</div>",b="<div>T</div><br><div>UV</div><br><div>WXY</div><br><div>Z`12</div><br><div>34567</div><br><div>890-=`</div><br><div>!@#$%^*</div><br><div>()_+[]{</div><br><div>}|;':,./</div>";

For the second one, we get 347 bytes before gzip, a slight improvement:

var c='replace',a="<!>a</!><br><!>bc</!><br><!>def</!><br><!>ghij</!><br><!>klmno</!><br><!>pqrsjt</!><br><!>uvwxyzA</!><br><!>BCDEFGHI</!><br><!>JKLMNOPQR</!><br><!>S</!>"[c](/\!/g,"div"),b="<!>T</!><br><!>UV</!><br><!>WXY</!><br><!>Z`12</!><br><!>34567</!><br><!>890-=`</!><br><!>!@#$%^*</!><br><!>()_+[]{</!><br><!>}|;':,./?</!>"[c](/\!/g,"div");

However, what you have to understand is that what's important most of the time important is the size of the file after being gzipped, not before. This is because most servers and browsers support sending files which have been compressed in this manner, reducing bandwidth usage.

When compressed, the DEFLATE algorithm (what gzip uses to compress files) already does what you would do manually, however you would have to have the additional size and loss of performance associated with the replacement code. As well, it's able to recognise string patterns which aren't easy to see with regular code without making your code completely unreadable.

With this example, what we end up finding is that after running compression on it (I used Zopfli to test this), the first script actually compresses down to 172 bytes, while the second can only be compressed down to 199 bytes, which is worse. The declaration for var c="replace" and [c](/\!/g,"div") takes up bytes in itself, and since gzip already places backreferences in the compressed file, it actually increases the size of the code.

Not only that, the performance is slightly worse because you'd have to replace each of that during runtime, which is worse than the time needed to unpack the gzipped file natively.

In fact, most minifiers actually do the opposite of what you've done, so that the gzipped size is reduced. See this discussion on the Closure Compiler Discuss group.

An FAQ for the Closure Compiler also covers this:

Closure Compiler inlined all my strings, which made my code size bigger. Why did it do that?

Most people compare code size by looking at two uncompressed JavaScript files. But that's a misleading way to look at code size, because your JavaScript files should not be served uncompressed. It should be served with gzip compression.

Closure Compiler assumes that you are using gzip compression. If you do not, you should. Configuring your server to gzip your code is one of the most effective and easiest optimizations that you can possibly do. The gzip algorithm works by trying to alias sequences of bytes in an optimal way. Aliasing strings manually almost always makes the compressed code size bigger, because it subverts gzip's own algorithm for aliasing. So Closure Compiler will (almost) always inline your strings when it can, because that will make your compressed code smaller.

If you know your client doesn't support gzip, the Java API has an aliasAllStrings option on the CompilerOptions class. Turning this on will make the compiler alias all your strings in the global scope.

Qantas 94 Heavy
  • 268
  • 1
  • 3
  • 11
  • Great and very valid points, but in complete files, I've managed to reduce file size by about 70%. I'm sure that all things considered, 3kb is better than 10kb – Luke Madhanga Jul 19 '14 at 16:04
  • @LukeMadhanga: if you're talking about the storage space on disk, yes it will be larger if you don't use compression or if you use on-the-fly compression. In my experience, the main issue is usually bandwidth or data transfer limits, rather than space available on the server. On Google's CDN, only 32855 bytes are needed for transport of jquery.min.js because of gzip compression, but when saved on disk, it's 95786 bytes. I've added a link to my answer for more details. – Qantas 94 Heavy Jul 20 '14 at 03:29
  • I'll take this as the correct answer. Good references etc. – Luke Madhanga Jul 20 '14 at 12:15