The other day a tweet by Ken Wheeler caught my eye.
Frontend: Where we plan like the code is gonna stick around for 20 years, but rewrite everything bi-yearly anyway— Ken Wheeler (@ken_wheeler) July 22, 2018
He put the situation succinctly - why add all these abstractions and tools for something we’re going to throw away in 2 years?
The Zen of CSS
As a wizened (read: old) developer, I still remember when CSS took off. The big selling point was that you could separate your site’s markup and content from the styling. The promise was that you could re-design your site without ever changing the HTML! And if you doubted that promise, you could just head over to CSS Zen Garden and take a look for yourself.
CSS Zen Garden’s concept was simple. They had a reference set of markup, and people could submit various CSS treatments for it. The goal was to show you how the same page could be designed totally differently, just using CSS. It’s amazing to see how different one version looks from another. Those sites both use the same HTML! With CSS, we were told, the marketing team could have a new design every month if they wanted. Re-branding a site? No problem, just tweak some classes. Alas…
A Big Zero
That’s the answer to the number of times I’ve seen anyone re-design a real production site, changing only CSS. It just doesn’t make sense. Inevitably a site re-design isn’t just changing the look - it’s changing the user experience and behavior. Often it’s easier and more cost effective to throwaway the markup and CSS, and write everything new. Like I said, the web is changing fast. If you were using floats before, you’re using flexbox now. Or maybe you’re already using CSS grid. No one who’s learned flexbox wants to go back to the
Too Much of a Good Thing
While progress has undeniably been made, there are signs that we’re going too far. Getting an Angular or React project set up from scratch in 2018 is an exercise in frustration. You have to know all about
webpack. You have to figure out arcane transpiler/bundling/plugin options and understand chunking, loaders and tree-shaking. You better have a state management solution sorted, because even though you’re managing all your application state on the backend, you have to manage it on the frontend now too.
Because things have become so complex, both Angular and React provide a shortcut. Angular CLI hides the pure magic from developers and “just works” to set up a new project. Similarly, create-react-app will get you moving with a “basic” React application in no time.
But does this abstraction really help? All that complexity still exists, we’re just hiding it behind a glossy veneer (and in the case of create-react-app, we’re hiding 23,000 files and 125MB of node_modules, good gracious)
The Web, Enterprise Edition
I hear you saying, “but Eric, everything in computer programming is an abstraction, we don’t write 1’s and 0’s anymore!” Of course not, but I’d argue that most abstractions are bad. They all leak, and most leak very badly. Good abstractions are arrived at through relentless and countless iterations. We’re still evolving frontend tools and techniques at a rapid pace, so any abstraction today is going to be supplanted in a few months.
It used to be considered “good practice” to separate your JS from your markup. Now we’re putting those two together like peanut butter and chocolate. Concatenating all your scripts together was mandatory until HTTP2 changed the game. Server rendering was the de-facto way to render a site. Then it was hip to client render everything. Now we’re seeing a shift back to server rendering for speed, ease of development, and SEO.
The “best” way to build a web app changes every few years. Frameworks like Angular and React are heavy. They require gobs of supporting tools and libraries. Conceptually simple things, like getting the back button to work reliably, are no longer technically simple. Staying on the upgrade treadmill and dealing with deprecations is a full time job. I’m reminded of the J2EE days when I think about the current crop of SPA frameworks. Drowning in complexity without getting commensurate value in return.
By the time your build toolchain is dialed in, you’ve figured out deterministic builds in
npm, how to chunk your bundles correctly, and get tree-shaking to work, you’re going to have to start all over. In two years the marketing department will re-brand and change the UX of the site. All those carefully abstracted component libraries you built will be useless and destined for the digital scrap heap. That Webpack 4 config that took weeks to get right will be thrown out since Webpack 9 will have a new, “much improved”, loader architecture that is not backwards compatible.
Move Fast, Ship UIs
So I think instead of focusing on hot-reloading, immutable reducers, time-travel-debugging, or higher order components, we should just focus on time-to-market. Get the frontend done and out the door as quickly as possible. Maybe that still means React, or maybe it just means vanilla JS and server rendered templates. Maybe it means a metric ton of copy and pasting, DRY be damned. If you know you’re going to re-write the UI every few years, why spend time and money building cathedrals you’re just going to tear down? Maybe a lean-to will do.
The thinking that’s pervasive in web development today is that our frontends are going to last forever. They aren’t. They’ve got a three year shelf-life max (unless you work at Craigslist or E-trade). By the time three years is over, there will be better (or at least different) ways to solve the same problems. You don’t see anyone building brand new Backbone apps today do you? It’s great that the frontend is evolving, but we should put our focus back on delivering value and results, not overcoming needless technical complexity.
Regardless of what you build, it’s going to break from time to time. You’ll need a way to know when it fails. TrackJS can help! Grab a 30-day free trial, and know when that fancy React app, or your simple vanilla JS site breaks.