Soft pages
A page fetched on intent, its wait drawn by the mark, and a bar that holds still while the page cross-fades.
The specimen
The part is in review for the next Shared release; the specimen is here so the design can be seen.
- 1Reach for a link
A same-site link is fetched on pointer down, or after 80 ms of hover on a computer. Never on Save-Data or a 2G/3G connection; at most four in flight; never sign-in, auth, API, a post, a download, a query or an in-page anchor. A page can opt a link out with
data-ov-no-prefetch. - 2Press
The mark's O starts its wait (
OVMark.navStart('page')) at pointer down, and the arriving page finishes it at first paint. The bar's ring is the wait, not a spinner. - 3Arrive
Where the browser has cross-document view transitions, the shared bar is named once and held still while the rest of the page cross-fades: 180 ms, Calm 120 ms, Off none. A page with its own
script[type="speculationrules"]keeps it.
One line opts a site in, in <head> after theme-loader.js and not deferred: <script src="/shared/soft.js"></script>. A site that does not opt in is unchanged. window.OpenVibeSoft = { on(), off(), exclude(selector) }.
What shipped
The soft page is in review for the next Shared release (soft.js). A same-site link is fetched on pointer down or after 80 ms of hover, never on Save-Data or 2G/3G, at most four in flight. The mark’s wait starts on the press and ends at first paint; cross-document view transitions hold the shared bar still and fade the rest (180 ms; Calm 120 ms; Off none). Measured on production pages at 390 px: press to first paint 1632 ms → 994 ms median.
“soft.js: prefetch on intent, the mark on the press, cross-document view transitions” — the change; 39% / ~0.64 s less press-to-first-paint in five throttled runs
The rules it carries out
87 First paint never depends on another service.90 Assets are addressed by their content, so people always get the current one.27 The only thing that goes round is the mark’s own O.4 Calm makes motion smaller and slower. Only Off removes it.
Build it
<!-- in <head>, after theme-loader.js, not deferred -->
<script src="/shared/soft.js"></script>
// a page can turn one link off, or the whole thing:
<a href="/next" data-ov-no-prefetch>Next</a>
OpenVibeSoft = { on(), off(), exclude(selector) };