The Three Cs: 🤝 Concatenate, 🗜️ Compress, 🗳️ Cache
When serving and storing files on the web, there are a number of different things we need to take into consideration in order to balance ergonomics, performance, and effectiveness. In this post, I’m going to break these processes down into each of:
- 🤝 Concatenating our files on the server: Are we going to send many smaller files, or are we going to send one monolithic file? The former makes for a simpler build step, but is it faster?
- 🗜️ Compressing them over the network: Which compression algorithm, if any, will we use? What is the availability, configurability, and efficacy of each?
- 🗳️ Caching them at the other end: How long should we cache files on a user’s device? And do any of our previous decisions dictate our options?
- at low (or no) compression, many smaller files is faster than one large one;
- at medium compression, one large file is marginally faster than many smaller ones;
- at higher compression, one large file is markedly faster than many smaller ones.
My advice:
- Ship as little as you can get away with in the first place.
- It’s better to send no code than it is to compress 1MB down to 50KB.
- If you’re running HTTP/1.1, try upgrade to HTTP/2 or 3.
- If you have no compression, get that fixed before you do anything else.
- If you’re using Gzip, try upgrade to Brotli.
- Once you’re on Brotli, it seems that larger files fare better over the network.
- Opt for fewer and larger bundles.
- The bundles you do end up with should, ideally, be based loosely on rate or likelihood of change.
If you have everything in place, then:
- Bundle infrequently-changing aspects of your app into fewer, larger bundles.
- As you encounter components that appear less globally, or change more frequently, begin splitting out into smaller files.
- Fingerprint all of them and cache them forever.
- Overall, err on the side of fewer bundles.