I contemplated using the instant.page techniques a while back, and took version 1.2.2 and stripped it to its bones, removing configurability that I’m never going to use, and golfed it down to 981 bytes/532 gzipped (873/456 sans license comment).
No way would I go past 1.2.2, though, because all it does is introduce more configurability that I don’t want, complications, bugs and misfeatures. (I call triggering load on mouse down catastrophically wrong, 100% dealbreaker with prejudice.)
Here’s the ECMAScript Module (I call it a module so I can skip an IIFE without polluting globals) that I ended up with, in case anyone’s interested. It uses uncommon tricks like reusing variables for different purposes to save a couple of bytes, which will tend to make JITs unhappy, but the JIT would turn up its nose at this lightly-called functionality anyway.
/*! instant.page v1.2.2, (C) 2019 Alexandre Dieulot, https://instant.page/license, shrunk by Chris Morgan */var e,t,a,r=document,n=r.createElement("link"),s=n.relList,o=()=>{e=n.removeAttribute("href")},i=e=>{e.relatedTarget&&e.target.closest("a")==e.relatedTarget.closest("a")||(t?(clearTimeout(t),t=0):o())},c=t=>!(!t||!t.href)&&(e!=(t=t.href)&&((t=new URL(t)).origin==location.origin&&(!t.hash||t.pathname+t.search!=location.pathname+location.search)));!(s&&s.supports&&s.supports(n.rel="prefetch"))||(s=navigator.connection)&&s.saveData||(r.head.appendChild(n),r.addEventListener("touchstart",t=>{a=performance.now(),c(s=t.target.closest("a"))&&(s.addEventListener("touchcancel",o,{passive:!0}),s.addEventListener("touchend",o,{passive:!0}),n.href=e=s.href)},s={capture:!0,passive:!0}),r.addEventListener("mouseover",r=>{performance.now()-a<1100||c(s=r.target.closest("a"))&&(s.addEventListener("mouseout",i,{passive:!0}),e=s.href,t=setTimeout(()=>{n.href=s.href,t=0},65))},s))
I have the golfed-but-not-uglified code too, but I won’t share it here at this time. It’s more fun this way.(No warranty whatsoever, don’t think I’ve even run the code.)