navbandit
v0.3.0
Published
Adaptive prefetching — learns which pages to prefetch using Bayesian Thompson Sampling + Speculation Rules API
Maintainers
Readme
navbandit
Learns which pages to prefetch by watching how users navigate your site. One script tag, zero config, under 3KB gzipped.
Quick Start
<script src="https://unpkg.com/navbandit"></script>That's it. NavBandit will automatically:
- Discover safe same-origin links on each page
- Learn which links users actually click (per page)
- Prefetch the most likely next pages before the user clicks
- Get smarter with every navigation
How it works
NavBandit uses Thompson Sampling — a Bayesian algorithm that balances exploration (trying uncertain links) with exploitation (prefetching links that have been clicked before). Each page maintains its own set of arms — so predictions from /pricing are independent of predictions from /docs. A UCB1 strategy is also available as a drop-in alternative.
Prefetch strategy (best available method, detected automatically):
- Speculation Rules API on Chrome/Edge 121+
<link rel="prefetch">on browsers that support itfetch()with low priority as a universal fallback
Bandwidth-aware: Respects navigator.connection.saveData and effectiveType. Backs off or disables prefetching on slow connections — the model still learns from clicks, so it's ready when bandwidth returns.
State: Persists in browser storage with automatic expiry. Each arm stores just 3 numbers (alpha, beta, lastSeen), so the footprint is tiny.
Safety defaults: NavBandit skips cross-origin links, links with query strings or fragments, non-_self targets, download links, and clearly destructive route patterns like logout/delete. Add data-navbandit-prefetch="true" to explicitly allow a safe route that would otherwise be skipped, or data-navbandit="false" to opt out of discovery.
npm Install
npm install navbanditimport 'navbandit'Or reference the built file directly:
<script src="node_modules/navbandit/dist/navbandit.global.js"></script>Advanced: Service Worker Mode
For sites that want contextual learning (predictions based on time of day, session depth, scroll behavior, connection type), NavBandit also offers a Service Worker mode using a LinUCB contextual bandit with IndexedDB persistence.
Service Worker (sw.ts):
import { createBanditSW } from 'navbandit/sw'
const bandit = createBanditSW({ discount: 0.95, alpha: 1.0 })
self.addEventListener('fetch', (e) => bandit.handleFetch(e))
self.addEventListener('message', (e) => bandit.handleMessage(e))handleFetch never calls respondWith(). It only observes navigations via waitUntil(), so it works alongside your existing fetch handlers.
Main thread (main.ts):
import { createBanditClient } from 'navbandit/client'
const cleanup = createBanditClient()SW Mode Config
| Option | Default | Description |
|--------|---------|-------------|
| alpha | 1.0 | Exploration weight; higher values try more uncertain options |
| discount | 0.95 | DUCB discount factor; lower values adapt faster |
| dimensions | 8 | Context vector size |
| topK | 3 | URLs to prefetch per navigation |
| pruneAfter | 50 | Drop arms not seen in this many navigations |
| maxStateAgeMs | 2592000000 | Expire persisted SW state after this many ms |
| maxTrackedLinks | 100 | Maximum validated links accepted from a discovery message |
Browser support
- Chrome/Edge 121+: Speculation Rules API with eagerness levels
- Other modern browsers:
<link rel="prefetch">fallback - Everything else:
fetch()with low priority
License
MIT
