Skip to content

Hunt for the 0ms load time

Static sites are fast by default. It's kind of difficult to make things slow when the server only serves files and the client doesn't need to wait for another round of queries after loading the content. But how fast can we go?

Simple idea: what if we preload the content when the user is about to interact with a link? So I started searching around the internet, with queries like "preload link on hover" (and a ton of variations). I was a bit confused that there was no simple pre-existing solution to be found. I found a bunch of resources and nothing fit the bill.

  • Most of the results were for NextJS. I don't use NextJS.
  • I found some resources to make Turbolinks cache pages on hover, but that whole solution is much more intrusive than I'd like. It's also unmaintained.
  • I found InstantClick, which is actually exactly what I want. However, it has extreme bugs (like not pushing the correct address to browser history, so you can't navigate back). Aaand it has not been maintained since 2017 (last release in 2014, even).
  • After the disappointment with InstantClick, I found the author has started a new project called instant.page. It is actively maintained, which got me excited for a bit. However, to my dismay, I could not manage to get it to do anything on any browser. Even their tests didn't work for me. ¯\_(ツ)_/¯

As a side note, this wouldn't be that hard of a problem to solve myself, but I'm genuinely shocked there's no commonly used pre-existing solution. I somewhat even expected there might be something similar to the <link rel="preload"> mechanism.

Eventually I ran to the preload extension for htmx. And it looked perfect (so did InstantClick and instant.page at first tbf). I had never tried htmx, for it has always seemed like a bit of a meme, but for this site - a mostly static blog with a tiny bit of interactivity sprinkled in for a better experience - it just might make sense. So I tried it. And I loved it. You are running htmx right now.

The home link in the header bar looks like this:

<a href="{{ config.base_url }}" preload="mouseover" preload-images="true">
  {{ config.title }}
</a>

If you open the network tab in developer tools and observe what happens when you hover the link, you'll see a request for https://seequ.dev/ pop up. This request is actually all we need! The server returns a Cache-Control header instructing the browser to assume the page will be valid even if it takes the user a moment to actually click through. Without the header, the browser will ask nginx if the etag it received previously is still valid - and that costs precious milliseconds!

The preload-images attribute adds a little bit of extra sauce in that it instructs the extension to scan the fetched document for img tags and preload those in the same fashion. Handy when opening a page with images

What about first load?

Currently, opening the front page transfers 24kB of data. 16.5kB of that is htmx, which is not ideal. But, the amount of data is clearly not an issue.

While investigatihg this, I noticed my ping to aeequ.dev is 60ms(!). I don't know why. World ping test says my ping to about everywhere in Central Europe is ~60ms.

So that leaves us with 120ms of pure delay in principle. 60ms to get the html and another 60ms to get linked resources. The load is so low that that should be all we get. So why does htmx.min.js have a consistent 130ms delay from request start to transfer?

Screenshots

Screenshot of network statistics Screenshot of network timing

If you have any idea, please let me know. I've bashed my head against the wall for hours, trying to understand what's going on here and I have no idea.