The Ferryman's Single Oar: On the Unbalanced Rhythm of a Single HTTP/2 Stream
There’s a scene from old riverside towns I’ve always pictured: a lone ferryman, his small skiff cutting through still water with one long oar. The rhythm is everything. A deep pull on one side, a recovery, then another pull on the same side. It’s a workable method for a narrow channel, but it demands constant, careful correction. The boat never glides with the balanced efficiency of two oars; it moves in a series of forward lurches, each followed by a slight, inevitable veer off course that must be corrected on the next stroke.
This came to mind recently while staring at a waterfall chart for a client’s homepage. The page, on the surface, was ‘modern’. It used HTTP/2, that protocol celebrated for its multiplexing magic—the ability to send many files down a single connection simultaneously, like a boat with a dozen oarsmen rowing in unison. Yet, the chart told a story of a solitary oarsman. A massive, unbudged JavaScript bundle sat squarely in the first stream, blocking the dozens of tiny, essential CSS files, font requests, and hero image fetches queued politely behind it. The multiplexed highway had a single-lane toll booth right at the on-ramp.
We talk about HTTP/2 in the abstract, as a blanket performance good. But its benefit isn’t a given; it’s a potential that our own architecture can quietly undermine. The protocol allows for parallel streams, but it also enforces a strict order-of-importance within each stream. Place a monolithic, render-blocking script first in your HTML, and you’ve effectively handed your ferryman a single, impossibly heavy oar. Every other resource—every stylistic cue, every glyph of text waiting for its font—must wait for its first stroke to complete. The page doesn’t load in parallel; it loads in a stumbling, sequential stagger, each veer manifesting as a blank white screen or a jarring, unstyled flash.
The Corrective Stroke
The fix is not to abandon the boat or curse the river. It’s to recognize the rhythm we’ve imposed and re-balance the load. It means wielding the tools HTTP/2 provides with intention. Deferring that monolithic oar. Slicing the script into smaller, non-blocking strokes that can be interleaved with other requests. Using preload hints to give priority to the critical font or the hero image, effectively adding a second, simultaneous oar to the water. It’s about composing the order of requests not as a simple list, but as a symphony of interdependent parts, where the woodwinds don’t have to wait for the entire brass section to finish their fanfare before they can play a note.
Watching the waterfall chart re-draw after these adjustments is like seeing the second oar appear. The streams fan out, a true multiplex. The blocking bundle shrinks and moves, its tyranny over the connection broken. The page begins to paint meaningfully in pieces, a coherent image emerging from coordinated effort rather than a desperate, lurching scramble toward the far shore. The ferryman, now with a balanced craft, finds a smoother, faster, and far more direct rhythm. The journey isn't just quicker; it's finally steady.
Notes & further reading
A few pages I came back to while writing this:
- a practical rundown
- The Librarian's Shelved Volume: On the Patient Heft of an Awaited Module
- Huntsville, AL
- The Winter's First Snowfall: On the Sudden, Silent Accumulation of Third-Party Scripts
- Little Rock, AR
- The Watchmaker's Tiny Spring: On the Quiet Order of a CSS Containment Property
- Gilbert, AZ
- Peoria, AZ
- Scottsdale, AZ
- Surprise, AZ
- Tucson, AZ
- Elk Grove, CA
- Fullerton, CA