Guide

Prefetching

Every page Quillo serves asks for the pages it links to before they are clicked. Point at a link, and the page it leads to is fetched; by the time the click lands, the page is already there. There is nothing to write or set up: it is on for every page.

Try it here. This site is a Quillo program, and its pages prefetch. Open DevTools on the Network panel (filter: All) and clear it, then point at a page in the sidebar for a moment. A request for that page appears before you click: of type prefetch in Chrome and Edge, fetch in Firefox and Safari. Click, and the page shows at once. Chrome also lists each one under Application → Speculative loads.

These links are left alone:

Prefetching changes nothing

A route asked for ahead of a click may read (the database, files, other servers) but not write. Writing to the database, assigning a global variable, setting cookies or the session, writing files, publish, http.post and the like, and calls to services stop it, and the server answers "not prefetched" (503, cache-control: no-store), which the browser drops; a 204 would leave it where it was. The page is then made as usual when the link is followed.

route GET /count with db {    db.exec("insert into visits values (1)")     // a write: a prefetch stops here    <html><body>counted</body></html>}route GET /logout {    end_session()                                // a cookie: not prefetched either    redirect("/")}

Pointing at a link to either does nothing: /count counts only when it is followed, and pointing at "Log out" logs no one out. A prefetch can be made by hand, as the browsers other than Chrome and Edge make it:

curl -i -H "x-quillo-prefetch: 1" localhost:8080/count# 503, cache-control: no-store, and no row inserted; the log says GET /count -> 503 prefetchcurl localhost:8080/count# counted: followed, the route runs

The same holds for prefetches the browser makes on its own (Sec-Purpose: prefetch, from <link rel="prefetch"> or speculation rules a page writes itself). A page prerendered runs none of its components, server fns or live updates until someone opens it.

Keeping up with changes

A request that changes something, or logs someone in or out, answers with Clear-Site-Data: "prefetchCache", "prerenderCache", so a page kept for a click is not shown out of date. Chrome obeys it from version 138. A GET does not send it, nor a POST that only reads, so a page that counts its visits keeps its prefetches. Elsewhere, a change that is not a login can be up to 30 seconds old on the click.

When the server is busy

A prefetch is work nobody has asked for yet. If anyone is waiting, it is answered "not prefetched" before it runs, and the page is made if the link is followed. So prefetches never go ahead of a visitor.

Turning it off

When you see no requests

Seeing what it does

The request log marks a prefetch: GET /docs -> 200 (0.4ms) prefetch, and "prefetch": true when started with quillo run main.qwe --log json, so what counts the log does not count pages nobody saw. With --metrics (quillo run main.qwe --metrics), quillo_prefetches_total counts those answered, refused, and used by a click, which a page reports when it was landed on from a prefetch (in Chrome and Edge).

Behind a CDN or on a static host

Quillo marks only prefetched pages as keepable for 30 seconds, by the request header. A cache or a static file server in front may not tell the two kinds of request apart, and then the browsers that fetch in the background re-ask on the click. Chrome and Edge do not depend on it.

A static copy of a site (as export.sh makes of this one) is served with a file's headers whatever the request, so every page is sent with cache-control: private, max-age=30, and may be up to 30 seconds old after a change. This site is now served by quillo run itself, so it answers each kind of request as described above.

HTML files served with file(), files() or quillo serve go out as they are on disk: the prefetch script is added only to pages a route makes, so a file's ETag and a Range of it are of its own bytes. Such pages do not prefetch.

Thread
16Useful? Like it, or add to its thread below.

Thread 0 posts

On Prefetching: questions, tips, corrections, and code that uses it.

No posts yet. The first one opens the thread.