Why JavaScript is Struggling in The Modern Web

Applications on the Web… it’s a mess, to be honest.

But in order to understand why, we first need to go back. Way back…

Grab my hand, I’m about to take you on a journey

There was a time when the Web was simple…

A green (macho, pure, #00FF00) font on a dark, bulky monitor. Some IRC chat messages scrolling upwards. Fancy 56Kbps internet speeds for the rich folks. You know, the usual.

It was around 1993, though, when W3C had a baby that changed it all forever. Actually it was long before that, on 1989 that Tim Berners-Lee at CERN proposed the idea first and somehow, sometime after that, W3C got pregnant (honestly you don’t wanna know how, let’s just say they were into some very kinky stuff). Anyway they went on calling this kid “Hypertext Markup Language”. But that was a mouthful, so all the cool bros down the ghetto called it “HTML”.

Great kid, could do all sorts of stuff. But really its main game was showing data on a screen. Semantically structured data by the way and could very easily link some specific word from some page onto another wholly different page that was all about that specific word. One click and you are there. Hot damn! If the world ever saw one, that was a paradigm shift right there. Especially coming at a time when people were using 500 page dictionaries and 60 tome encyclopedias to learn about stuff.

But… to be honest with you, those pages were ugly. Like, real ugly. Like, please-freeze-me-and-keep-me-there-until-1996 kind of ugly.

Microsoft’s glorious website circa 1994

The age of the rainbows

Guys, it’s 1996, unfreeze yourselves, the magic has started happening. Cascading Style Sheets (or CSS if you’re ghetto) entered the web standards and using it you could take all the data of an HTML page and make ‘em purty.

Like, real purty. Like so so much…

mhm, yeah baby, that’s what I’m talking about…

See all these planets and and colors and stars and shit? This is stellar CSS, folks. In fact it’s still live, standing pristine and proud on spacejam.com, no kidding. :P

So CSS was cool and all. You could do all sorts of visual things, style buttons, move things around, make the page a glorious, animating, seizure-inducing rainbow of colors… But soon enough, people realized something was missing (not more seizures, seizures where going great).

The Web platform was missing something integral, all others at the time had. Its two languages HTML and CSS were not really meant for actual programming. They were merely markup languages, sort of meta-languages meant to be easy to code, so that all the hard programming is done by a few smart people who build the browsers that run these markup languages. The web was ultimately missing the variables and the if/else’s; the building blocks of any algorithm, really. You need both a memory store, and the abilities to compare and branch in order to build one. Without these ingredients, no worthwhile logic could ever be constructed.


Enter…

Oh, boy!

JavaScript joined the web in late 1995. JavaScript was da bomb, y’all. With JS you could, for the first time, code actual logic in your websites. You would push a button and things would move around, change color, disappear, conditionally even. You could alter HTML and CSS on demand, asynchronously. Hell, then why not lazily fetch things from the network as well and plug them into the website whenever they are available, we’ll call it “AJAX”. Great, now we can add buttons everywhere, buttons that do all sorts of stuff, fetch all sorts of data, displayed in all sorts of graphs, media and rich user experiences. Let’s make them be like a single-page app wherein you can do everything, fuck the desktop, who uses that anyway. You’re out of RAM cause your browser is hogging 4GB again? We got’s RAM for you here sir, download more RAM. You want web workers, service workers, real-time video conferencing, 3D accelerated graphics, augmented reality, all right here sir, step right in. Just use Javascript and you’re a few lines away from fame and money and glory!

But as it turns out, building all of that from scratch every time was hard… :(

Oh, I know, I know! We’ll make a build automation tool (more like 3–4 of them) and we’ll build a frontend framework (more like 10–15 of them, about half being react variants) and we’ll set up a couple global package registries and a couple more package managers and now you can javascriptly download your JavaScript into your existing JavaScript to run even more JavaScript! That will def’o not run like crap on all the machines, hog all the RAMs and chew all the batteries… No, sir, step right in!

“But wait, there’s this new EZsquizyLightning.js that is a safe, fast and asynchronous embed code, intended for third-party Javascript that makes your existing code run in the browser like a sysadmin under DDOS running to his laptop.”
Please no more something.js, just leave me alone.

OK…

Let’s breath…

Let’s analyze what happened here, and most importantly why it happened, m’kay?

This boom happened for a reason. Apparently the market has an ever-growing demand for complex logic on the Web. Apparently the Web hasn’t had the chance to adjust with all this craziness going on. And the Web — and its only native programming language being JavaScript — is the only truly open, cross-device platform left. It’s not Android, it’s definitely not iOS, not Windows, macOS or hell, not even Linux (despite the fact that it’s the most free and accessible platform in the rest of the bunch).

The Web is the one dominant platform and that’s good, because the Web is nobody’s and that means the Web is everyone’s.

Sure there are niches where other technologies do thrive, but in this day and age, if you want to code something that your users can run everywhere, you make it a web app and preferably you make it a Progressive Web App (more on that some other time).

JavaScript is slow and suboptimal. It always will be.

But the problem with the web still remains. And the problem, sadly, is its soul and that is JavaScript.

The whole ecosystem is a big mess. Moreover, JavaScript is bloated and as a result, JavaScript is slow. Sure, if you plug, and scrape and drill and glue and sweat like a pig in front of a computer screen for weeks and months and years you can maybe learn to make descent, performant, beautiful web applications. But that’s you, and you, little snowflake, are one in the thousands out there. It’s not me, nor the average Joe hammering the keyboard. Now go count how many of us are pushing JavaScript code out there every day and make an educated guess on the production quality of the Web. Not so good me thinks.

The big sites you usually visit are fancy and great because they can afford to hire these one-in-thousands snowflake programmers, but the hard reality is that most of the web stinks. Security, design, performance, usability, too often being sub-par. Which is why you don’t visit them and only go to the big sites, which reinforces your skewed perception of the quality of the web out there.

JavaScript was never designed to handle entire multi-megabyte-sized applications elegantly nor optimally.

JavaScript was designed to add logic to a Web, which until before JS was introduced, was nothing but a pair of markup languages. JS was designed to add small chunks of code with very specific purpose that will incrementally enhance a website’s functionality. That’s precisely why its designers called it JavaScript. JavaScript was never meant to do what we shoehorn it to do today.

One thing is crystal clear by now: JavaScript’s problem isn’t what you can do with it, it isn’t library availability and it isn’t popularity. JavaScript’s Achilles’ heel is its performance, and as expected it shares the same performance problems that all dynamically typed languages share.

And the reason is simple. Take this JavaScript function for example:

function add (a, b) {
return a + b;
}

Simple enough, right?

“Boy, this is gonna slide through the CPU like butter on a frying pan!”

Well hold on right there, Gordon Ramsey…

This is what the popular JavaScript runtime V8 (the one used in Chrome, Opera and other browsers) has to go through to slide your butter on its pan:

Taken from the talk “Compiling for the Web with WebAssembly” from Google I/O ’17. It’s a cool watch.

The reason for this complication is simple: JavaScript is untyped. There is an a + b in the code, but how is JavaScript supposed to know what type a and b is going to be each time you call the function so that it performs the appropriate action onto them? These two could be numbers, strings, booleans, undefined, objects, class instances (since ES6), or any combination of the above. JavaScript has no idea what to expect here, so there is no way to get prepared to run it optimally. And while it’s true that the brilliant engineers behind these engines go to immense lengths to optimize this inherent issue that is by design in this kind of languages, no untyped language will ever even come close to the runtime determinism that having typings can provide.

In fact, statically typed, compiled languages go even further down the optimization path, because they can. Since a compiler knows in advance that you have declared some variable c to be of type number which for example needs 4 Bytes of memory to be stored and another variable d declared as boolean that needs just 1 Byte, it can then run through all your code once at compile time (Ahead of Time), conjure some pitch black engineering voodo and spit an executable out the other end with specific memory addresses ready for the CPU to digest in a pinch. This is memory, computational and power efficience at it’s optimal level and it’s totally different to how untyped languages like Javascript operate.

Now at this point it’s worth clarifying that not all compiled languages are targeted to hardware-friendly machine code (e.g. x86_64 that your CPU probably understands). It’s true that C and C++ executables, compiled down to machine code, translate pretty much 1–1 to your CPU’s internal wiring. Java and Typescript on the other hand, do not. They are both compiled into some intermediate language. A compatible runtime engine can then load the compiled intermediate executable and do the final interpretation on the fly (often using the optimised JIT technique) into the machine language your CPU understands.

In Java’s case the compilation intermediate target is a pseudo-assembly bytecode that can be executed on any machine with a program called Java Virtual Machine. In Typescript’s case, the compilation target is, hold on to your pants, JavaScript which can be executed on any machine that has, well, a browser. And there’s quite a lot of such machines out there, most of which come with a browser pre-installed. Since a few years ago even, JavaScript can also be executed on any machine that has Node.js installed, irrespective of having a browser available or not, which is awesome and a total paradigm shift.

Actually C++ and Java can already experimentally be compiled into a brand new and entirely different target platform we briefly mentioned before; an intermediate called WebAssembly. Wasm is a new low-level binary compilation target, that loads much faster than JavaScript and is meant to join the Web platform and be part of tomorrow’s browsers. In fact all major browsers already support it and it runs 10–50x faster than JS, mainly due to having those typed definitions. You can learn more about it and view stunning demos in Mozilla’s announcement article.

Dynamically typed languages (JavaScript, Python, php) when compared apples-to-apples, will almost always prove inferior in complex production applications against statically typed languages (Typescript, Java, C/C++).

Untyped, interpreted languages actually prove inferior in both maintainability and performance. Working with an untyped language is like getting wasted the night at the bar: it’s pure fun when you’re doing it; you feel free, agile and powerful. That is until you wake up the next day in a terrible headache having to clean up a pile of your own puke and confront embarrassing Facebook photos of what you did last night. So you can think of untyped languages like a loan you take as a programmer: take it, be responsible and it may work out for you and have more fun than you would otherwise, but go too far with it and you’re going to end up in an ugly spot. And trust me, I know about loans gone wrong, I’m Greek. Γεια σου μαμά!

Honestly, and I’m totally spit-balling here, I think the untyped language thing is a fad that begun in the 90’s when computer scientists of the time wanted to ascend to even higher level languages, ultimately writing English in one end and getting an executable out the other. Even worse, they expected programmers of the future to be responsible, reasonable beings. Only we sadly are not, more often than we would like to admit. And worse, we get tired and make even more mistakes and for these reasons and more, most of us are not worthy of coding without a safety net. And even if you can do it, know that I cannot. And if you’re unlucky enough to be stuck with someone like me coding in the same team, then enjoy maintaining my “rebellious” code.

Having a compiler scream whenever we mess up might not necessarily help write better code, however setting the --noImplicitAny Typescript compiler flag for example, along with a descent TSLint ruleset can go a long way to get a team started along a more righteous road of web development.

So maybe try Typescript?

I guess? I don’t know, you choose for yourself.

Typescript, created by Microsoft, has already made it into Google’s list of official languages and we might also have it compiled directly into WebAssembly sometime in the future, instead of JavaScript, for a performance boost, which the good ol’ untyped vanilla JS just can’t ever even dream of approaching.

These are all strong indicators of the language’s present offerings and its future to come.

Personally I like Typescript for all the aforementioned reasons, so there’s that for what it’s worth. I don’t really get any runtime performance boost yet, since I compile down to JavaScript, usually ES6. But it makes refactoring a breeze, I get all the latest ECMAScript features first (async/await), typings give me powerful editor intellisense and also make my code easier for others (or my future self) to read and maintain.

Actually for these reasons exactly, Google has been coding in what they called Clojure for over 10 years. Closure is practically JavaScript with annotated typings in the form of JSDoc. And yup, it is compiled down to good ol’ JavaScript too and always has been all these 10 years. No runtime performance boost for them either, but the productivity and code quality boost was enough to justify building and using it. In the end they teamed up with Microsoft and got all the features they needed into Typescript, so they ended up switching to that altogether about one month ago. Point being, the need for typed JavaScript has been there for whoever was serious about his code, since a very long time.

Wrapping up

You wouldn’t now, would you? :)

Please don’t get me wrong, I have no beef with JavaScript. JS has done for me, and all of us web developers, so much and has already contributed enough to where we are today to earn our respect for it in full. In fact, we’ve forced the poor thing do for us way more than it was designed to do 21 freakin years ago, and that’s to no one’s gain.

I don’t care if it’s WebAssembly or Closure or Typescript or something else entirely new, but I feel that the Web is in need of some long-awaited adjustment deep within its core technology in order for it to support optimally and elegantly the demands of the current markets and of those that are to come. And that adjustment needs to be statically typed and it needs to be compiled, not interpreted. JavaScript can and should still keep its place in the web but as a scripting language to glue things together fast. For the heavy lifting we need something designed from the ground up to be able to handle heavy lifting.

I still love you, JavaScript. If anyone’s read all the way until here, I’m sure he can attest at least to that. Hang on, baby. Hang on just a little more.


If you found this was worth your time, please click the 👏 below so that other people may see it here on Medium.
Thank you for your attention.
-- maninak