The web is embedded programming

Node.js certainly shook things up, didn’t it? Among other things, it brought isomorphic universal Javascript, and a strong preference for modular code. They’re both pretty sweet things in and of themselves, but when used together and coupled with tools like browserify they can sometimes conspire against users behind your back. Back-end programmers are used to finding modules that seem to fit their needs, requiring them into the code, and concentrating on the actual application parts of the application. Node has long encouraged this sort of usage and when coupled with a package manager like npm it’s a cozy place to be. You can rely on the exports object, let module authors shoulder some of the burden, and get on with building things that make sense for users instead. Write once, run everywhere. The future is here!

So you bundle your beautiful Javascript and put it in people’s browsers, and suddenly everyone’s mad at you.

The browser is an embedded platform

On the client side, you need to watch your performance budget like a hawk. This is not going to change anytime soon. Handheld devices don’t have very much memory or CPU, server round trips are expensive and can carry big latency hits, data transfer can be slow, etc etc. You need to be really careful about what you send down the line to the client. In this way, the web reminds me of coding homebrew games for the Game Boy Advance. If you put too much stuff in your DMA transfer queue the CPU would pause, your game would stutter and fall over, and you’d have to remove things until you were back within the limits of your frame budget. One of the first things you learned as a GBA developer was to pretend that the C Standard Library didn’t exist. It would have been awesome to be able to use the string manipulation functions, the date library, or the random number generator. But they were too memory hungry, too slow, not at all adapted to the constraints imposed by the little GBA device. The goal of the standard library was to be robust, versatile, portable, and cover most use cases. And that priority was completely wrong in a resource-starved environment.

A problem of priority

The standard web pattern of doing things used to be that the server was the source of truth. A user could sneak a wrongly formatted e-mail address into a field, the server would catch it on POST, and return an error message. The server would probably have a huge, bulletproof component that did nothing but analyze e-mail addresses, handle the Unicode 💩 , check against blacklists, etc. The client code would be optimized to get the user through the form in as quick and hassle-free a way as possible and stay out of the way. So for the server, the most important thing would be the correctness of the data, not the execution time, memory usage, or code size. For the client, since the faulty email address would be caught by the server anyway, the most important thing would instead be for the form to be responsive and fast.

This priority clash is going to be hard to resolve. When requiring stuff on the server, it makes sense to optimize for sturdy catch-all libraries that can handle every edge case for you. On the browser, it’s usually more prudent to assume that since it’s the web, everything’s going to break anyway, and optimize for speed and fault tolerance. Using the same code for these environments means one of them will have to come second.

The dream of DRY

It would be excellent if you could just require() things on the server and have them magically resolve on the browser. Many intelligent people are doing their best to turn that dream into reality. And a modular approach is still a good idea - it’s not hard to imagine a scenario where a library can be swapped depending on runtime, or has specific optimizations depending on platform, or a long-distant future where the DOM and the server converge into something that works for everyone, regardless of WiFi quality or CPU speed. Right now, though, the Javascript may be universal but the platforms aren’t. You still have to do your homework, know your environments, and always keep a watchful eye on your load times.