We now have great tools to deal with this. Code Splitting + Lazy Loading allows us to split our bundles into a primary bundle and asynchronously load the rest of our code as needed. Tree Shaking allows us to only include the code that is explicitly imported to be used in our applications. With these at our disposal, our initial package size can be more than manageable.
But what has me writing is the trend for libraries to advertise “______ in just 2kb”. Obviously being small is great, and coming up with small solutions is a challenge in itself. But I wonder if it is gone too far. I’ve seen libraries sacrifice performance and even correctness in the goal to shave fractions of kilobytes. I’ve seen incomplete or inconsistent solutions to fit a certain size target. As a library writer of myself, I feel this pressure to constantly cut extra checks and deoptimize my code to reduce output size and I feel a bit disgusted.
The next section is a personal reflection. If you want to skip ahead to the technical part. Scroll down to Size & Performance.
…13 Years Ago
Surprisingly this feeling felt a bit familiar and I don’t say this to trivialize other people's struggles by making a comparison to a real health condition. But 13 years ago I was obese. I was a developer who did not exercise. I sat at my computer at work, and I came home and sat at my computer some more. I ate like I did as a teenager but I wasn’t a teenager anymore. I was 23. My body fat percentage was about 29%. At some point, something clicked and I knew I needed to make a change.
It was really difficult at first. Exercise was difficult and uninteresting. I loved the food I ate, and I was a big guy so I couldn’t really picture eating less. I wanted to but I felt hungry. It was like a craving. But all I really needed was a place to start. My dad took me hiking as a kid, and when he put it out there to hike again, the nostalgia was enough to get me started. It was hard. Really hard. I couldn’t even make it up to the top of the trail the first time. I had hiked it as a kid effortlessly, and it was depressing. But I kept with it. Before long I was doing the local trail 2–3 times a week and I had lost 25lbs. But I wasn’t done yet.
I had hit a plateau though. I wasn’t losing any more weight and I was still overweight. I wasn’t interested in doing other exercises. I liked hiking at first as a nostalgia trip, and something I could do with my dad, but I had grown to love the tranquillity. It became that escape from modern technology. When I could unplug and focus on reflecting on my thoughts. So I decided to change my diet, mostly to eat less. I learned that what I thought was hunger was carb craving. I refused to give up what I liked but ate a lot less of it. Eventually, I had lost another 30 lbs.
I’m a bit meticulous so the only way I got there was counting calories. Calories I ate. Calories I burned. I projected goal weight. I loved that I complete control. It was math. I love math. I decided I wanted to do more so I started running. Trained for quarter marathon. Hiked bigger mountains. It became my whole life at that time. I lost another 12lbs and was now at about 7% body fat. I felt good and was healthy. I started dating my future wife during this time period and for all intents and purposes had turned my life around in an 18 month time period.
After a couple of years like this though I didn’t recognize myself anymore. Not the way I looked, but that I was obsessed. It wasn’t necessarily a bad obsession. I wasn’t doing anything unhealthy physically. But it wasn’t natural for me. At a certain point, I just stopped counting and scaled back a bit. I stopped focusing so much on cardio. Now 10 years later, I might not be the specimen I once was. 10 years and a couple of kids brings out the dad bod a bit in any of us. I’ve gained back 30 of those lbs, but I am much stronger than I used to be. I could probably afford to shave a few pounds. But I’ve also learned there was more to living healthy than losing weight. And most importantly I don’t feel guilty anymore for living the way I want to.
Size & Performance
It’s unfortunate that some of the most egregious examples are comparisons based on widely used demo apps like TodoMVC or RealWorld Demo. Those applications are great examples of what it takes to use common patterns with popular libraries. Alongside measuring Lines of Codes gives a good feel for the developer experience. But as performance tests very limited. I can’t stomach reading another performance comparison based on them. Like here is the RealWorld Demo Comparison. Performance is almost completely based on initial render times. Size is almost as uninteresting since not all the implementations use techniques like code-splitting or tree-shaking. And since the whole focus here tends to be the size and initial time, implementations are incentivized to do things like writing minimal APIs for XHR for the demo rather than just use the libraries they would have.
The JS Framework Benchmark on the other hand actually looks at performance on a wider range. It’s hardly the only test to look at but here’s something to chew on. Here’s a list of some libraries ranked from smallest kilobyte size to largest. I’ve included a wide spectrum from compilers(Svelte), to tagged template literals(lit-html), to blazing Virtual DOM (Inferno). I’ve even included my own library (Solid) and Web Assembly Vanilla implementation (wasm-bindgen) for good order:
Here is the same list, in the same order showing performance metrics. I want you especially focus on the first row. This is the time it takes to draw 5000 DOM elements(1000 rows) on the page. The difference here is greater than that of the previous table. The previous benchmark was rendering a mostly empty page with a few buttons. I wonder how it changes if the page actually loaded with content. What if those 5000 DOM elements were part of the load, does Svelte’s smaller bundle make up less performance? Truthfully I can’t say definitively. But it definitely isn’t so cut and dry. Less size isn’t always worth the sacrifice.
After you do the initial render, you still have to live with the performance. Row 2 and 3 showing updates, and appending more elements, respectively. Again the same sort of trend appears. Sure a few milliseconds is nothing. But neither is 10kb.
There is much more to life than how slim you are. And much more to your library of choice than the last couple kilobytes.