Why is JavaScript not compiled to bytecode before sending over the network?

Background: I was on the ECMAScript technical committee in the late 1990s and one of the implementers of Microsoft's JScript engine.

Let me begin by saying what I always say when faced with a "why not?" question: language designers are not required to give good reasons why they did not spend hundreds of millions of other people's dollars on a feature that someone happens to like. Rather, the person pitching the feature is required to give good reasons why that's the best way to spend that time, effort and money. You've made an argument with no numbers attached to it that bytecode would be a cost savings in terms of bandwidth. I would encourage you to work up some actual numbers, and compare that to the costs of creating yet another language; those costs are significant. Remember in your analysis that "implementation" is one of the smallest costs. Also in your analysis include who saves the money vs who spends the money, and you will find that the people spending the money are not the ones saving it; incentives matter.

That said, this is one of the more reasonable "why not?" questions because it is a feature we considered and rejected for reasons.

We considered such a scheme, both within Microsoft and at the TC level; since JScript was already implemented as compiling to a well-designed, principled bytecode language, it would have been straightforward for us to propose it as a standard and we considered doing so.

We decided not to, for a variety of reasons including:

Holy goodness it was hard enough to standardize JavaScript. Everyone and their dog would have an opinion about what the ideal characteristics of a bytecode language were, and it would be multiple years of bikeshedding. No one really wanted to go there.

It was an expensive solution with no associated costly problem. There's no reason to suppose that a bytecode language would be more efficient in either size or speed. JavaScript already minifies reasonably well and is highly compressible.

It would have created an enormous amount of work for browser providers, who were already vexed by the expense of producing an efficient, compliant JS implementation.

Creating a secure JS implementation that resists attacks by bad actors is hard enough; should we double the surface area available to attack? Probably not.

Standards are an impediment to innovation. If we discovered that a small change to our bytecode language would make a big difference in some previously-unforeseen or previously-unimportant user scenario, we were free to make that change. If it was a standard, we would not be free to create that user benefit.

But that analysis presupposes that the reason to do the feature at all is performance. Interestingly enough, the customer requests that motivated considering this feature back in the 1990s were not primarily about performance.

Why not? The 1990s was a very different time for JS than today; scripts were mostly tiny. The notion that there would someday be frameworks with hundreds of thousands of lines was not even close to being on our radar. Downloading and parsing JS was a tiny fraction of the time spent downloading and parsing HTML.

Nor was the motivation the extension to other languages, though that was of interest to Microsoft as we had VBScript running in the browser as well, which used a very similar bytecode language. (Being developed by the same team and compiled out of the same sources and all.)

Rather, the primary customer scenario for motivating bytecode in the browser was to make the code harder to read, understand, decompile, reverse-engineer and tamper with. That a bytecode language is hardly any additional work to understand for any attacker with reasonable resources was major points against doing this work; we did not want to create a false sense of security.

Basically there were lots of expenses and precious few benefits, so it did not get done. Something must have changed between 1998 and 2015 that made WebAssembly have a reasonable price-to-benefit; what those factors are, I do not know. You'd have to ask an expert on WebAssembly.