> Do you write minified code today? Definitely not.

False. I greatly enjoy writing minified code; not only is such golfing fun, you can regularly achieve drastically smaller results.

Automated JavaScript minifiers are a useful tool, but they all miss significant opportunities in even simple things like code reordering, because JavaScript’s semantics just don’t support that sort of thing.

It puzzles me, given how much effort has gone into making a slow language run faster than it has any right to, how little effort has gone into making any kind of optimising compiler, for both runtime performance and bundle size. GCC and LLVM put insane amounts of effort into optimising things, which work best when paired with something like Rust’s ownership model (… so long as rustc isn’t currently being conservative after having uncovered yet another bug in LLVM’s noalias!).

Meanwhile in JavaScript land, the main tool used is Terser, which is both simple and simplistic. It does very little in the way of optimisation, because it basically doesn’t seek to understand the code, and so can’t apply perform any operations that could change the semantics in such-and-such a situation that (if you tried harder) provably cannot occur. Long ago, Google made Closure Compiler, and it’s a good deal better, so long as you’re willing to humour the idiosyncrasies it requires in advanced optimisations mode, but it’s still far, far short of what GCC/LLVM can do. A few years ago, Facebook toyed with symbolic execution in Prepack, an approach with potential for building good tooling, but they gave up on it before it reached the point of being useful.

Then consider other popular tools in the ecosystem: Babel is stupid (by which I mean that it doesn’t attempt to understand the code) and generates significantly bloated code because it’s seeking to match semantics as perfectly as possible without questioning whether it needs to. Bublé demonstrated a different approach, where you say “eh, who cares about exact semantics, let’s just note down the caveats and generate simpler, smaller and faster code”. (For both of these tools, I’m talking about the old ES6+ → ES5 compilations, which are obsolete now; I’m actually not sure what people use Babel for now, and how much this judgement applies.) And for bundling, webpack, which… ugh, the code it generates is just wilfully inefficient. Rollup demonstrated a different approach, where you actually care about minimising code because it makes it smaller and faster.

So returning to the original point: I certainly write minified code sometimes. I have a few <script> blocks on my site (one on all pages, others on pages that use them), and those are hand-written, sometimes with an automated minifier’s help to rename variables for slightly better compression, but other than that, all manual. I’ve got a project I’ve been working on for doing DOM stuff off-thread with a tiny VM on the main thread to execute byte code, and in that I’m working the same way: I know I have to have a little main-thread JavaScript, but when automated minification can reduce my 5KB of nicely-factored code to 1934 bytes (~1185 gzipped), but manual minification can reduce it to 928 bytes (~417 gzipped) that will also run faster due to eliminating abstractions, well, I know which approach I’m going with. My way of working in these sorts of projects is that I maintain expanded and minified source codes simultaneously, and apply any changes to both.

You might say “why not work in semi-minified code, applying whatever minifying transformations you have except for variable naming and whitespace, then use an automated tool for that part?” and you would have a bit of a point, except that then I’d need to worry about naming things, which can be complicated by reusing variables. Eh. I enjoy it. It’s mostly fun.

A byte here, a byte there… ah, fond memories of my Casio CFX-9850GB Plus Color calculator too on which I spent hundreds of hours in my school days, often golfing my programs to save one or two bytes here or there, since I normally had at most a few kilobytes of storage space spare. I discovered at one point that they kind of had two instruction-ending characters, a line break, which was two bytes, and a 𝅍 sort of a character, which was one. Thereafter, all my source code was on one line. Those things were quite astonishing in their battery life, too; I would have racked up over 1,000 hours on it, but only went through four sets of four AA batteries. Meanwhile the newer model almost everyone else used, while about 4–10 times as fast depending on the operation, lacked colour and chewed through batteries around 40 times as fast. Then came CAS calculators, probably using 40 times as much power again…

I’m rambling, aren’t I?