v152 · origin trial · performance · speculation rules
Speculation Rules - moderate viewport heuristics controls
A ruleset-level moderate_viewport_heuristics object for the Speculation Rules API that lets developers tune the three parameters of Chrome’s mobile “moderate”-eagerness viewport heuristic — the distance-from-last-tap band, the largest-anchor dominance threshold, and the dwell delay — so they can experiment with better values and report results back to Chrome. Android-only origin trial in Chrome 152–157; there is no specification and no plan to ship the syntax as is.
This feature exists purely to gather heuristic-parameter data. The Intent to Experiment states there is no spec (“this is an experiment-only feature”), no TAG review (“as we’re not intending to ship this feature”), and “no plans to ship it as is” — do not build production dependencies on this grammar. To use it:
- Register your origin for the
SpeculationRulesModerateViewportHeuristicsControltrial at developer.chrome.com/origintrials and serve the token (<meta http-equiv="origin-trial"> tag orOrigin-Trialresponse header). The trial runs Chrome 152–157 inclusive (“LGTM to experiment M152-M157 inclusive” — API-owner approval), Android only: the runtime flag record setsorigin_trial_os: ["Android"]because the viewport heuristic only runs on Android. Third-party tokens are allowed (origin_trial_allows_third_party: true) so cross-origin performance libraries that inject speculation rules can opt in. - For local development, launch Chrome for Android with
--enable-blink-features=SpeculationRulesModerateViewportHeuristicsControl(the runtime feature is statusexperimentalwithorigin_trial_feature_nameset, per the runtime flag record). The intent records no about://flags entry (“No information provided”); the Finch name isSpeculationRulesModerateViewportHeuristicsControl. - The heuristic itself (not the controls) also requires the device to be in the mobile viewport-heuristics population — the base
kPreloadingModerateViewportHeuristicsfeature that shipped the behavior in Chrome 138 (see how it works).
at a glance
| What it is | An optional moderate_viewport_heuristics object at the top level of a speculation-rules rule set, carrying up to three numeric overrides for the mobile “moderate” viewport heuristic: distance_from_pointer_down, largest_anchor_threshold, delay |
|---|---|
| Milestone listing | Chrome 152 — Origin trial (listing, verified 2026-07-29; the listing is authoritative per gendn invariant #2. The detail record’s browsers.chrome.status still reads “Proposed” and its OT fields are empty — a stale record, noted for honesty) |
| Applies to | Document-source speculation rules with "eagerness": "moderate", on Android, in documents opted into the origin trial. It does not affect desktop hover heuristics, conservative/eager/immediate eagerness, or list rules |
| Platform | Android only — the intent answers “No” to all-six-platforms support (“this is aimed at mobile viewport heuristics, so Android only”); the runtime flag restricts the trial to origin_trial_os: ["Android"] |
| Runtime feature | SpeculationRulesModerateViewportHeuristicsControl (status experimental, origin-trial-gated, third-party tokens allowed) in runtime_enabled_features.json5 |
| Specification | None — “No spec - this is an experiment-only feature” (intent). The substantive documents are the explainer and the Chromium implementation |
| WPT | No upstream coverage — the intent answers “No” to the WPT question (“not aimed to be a web exposed feature, so unit tests seem sufficient”); no moderate/heuristic/viewport-named test exists under wpt/speculation-rules (checked 2026-07-29). Chromium covers parsing and application in its own unit tests |
| ChromeStatus | 6240467143491584 — Speculation Rules - moderate viewport heuristics controls (blink component Blink>PerformanceAPIs, owner yoavweiss@chromium.org, tracking bug 529423512) |
why it exists
The moderate eagerness level of the Speculation Rules API has proved valuable on desktop — Shopify measured faster storefront navigations with it (Shopify engineering blog) — but less so on mobile, where “moderate” is driven by viewport heuristics that shipped in Chrome 138 (background in the blink-dev PSA). Those heuristics have fixed internal parameters, and the Chrome team suspects they “can be improved on”; giving developers temporary control over the parameters is meant to “tighten the feedback loop” that finds better values (explainer). The intent’s stated experimentation goal: “Allow developers to find and report back mobile-viewport heuristic values that work well for them and enable performance benefits from ‘moderate’ speculation rules” — Shopify is on the record as interested in experimenting (Intent to Experiment).
how it works: the viewport candidate-selection heuristic
On Android, when a document has document-source speculation rules with "eagerness": "moderate", Chrome watches the viewport and, each time the user stops scrolling, runs three checks against the links currently on screen and picks at most one candidate to prefetch or prerender:
- Distance filter. Discard links whose vertical distance from the position of the user’s last
pointerdownfalls outside a[low, high]band, measured as a fraction of screen height. The compiled-in default band is[-0.3, 0.0]— the P12.5/P87.5 bounds of the middle 75% of distances observed for clicked anchors. - Dominance test. Of the remaining links, take the largest by visible area — but only if it is clearly bigger than the runner-up:
(size(largest) − size(second)) / size(second)must exceed a threshold (default0.25). If the two biggest links are about the same size, the browser does not guess. - Dwell delay. Wait a short delay (default
500ms) before acting. If the user scrolls again during that window the candidate is dropped, so links that whip past during a fling never trigger speculation.
The moderate_viewport_heuristics object overrides exactly these three numbers for its document. Two gating layers sit between the JSON and the behavior: the heuristic runs only where the base mobile-heuristics feature (kPreloadingModerateViewportHeuristics) is active, and the author overrides are applied only when the SpeculationRulesModerateViewportHeuristicsControl origin trial is enabled for the document — checked in AnchorElementInteractionTracker::AnchorPositionsUpdated at the moment anchor positions update. The compiled defaults are themselves Finch feature parameters (distance_from_ptr_down_low/hi, largest_anchor_threshold, delay), so the effective default configuration can be adjusted server-side; the values above are the compiled defaults cited by the explainer.
lifecycle and application semantics
| Stage | Contract |
|---|---|
| Parse | The object is parsed unconditionally, even when the origin trial is not (yet) enabled for the document — gating at parse time would be racy for third-party trial tokens registered after the rules were parsed. Whether the parameters have any effect is decided later, at the point the heuristic runs (speculation_rule_set.cc) |
| Multiple rule sets | The first rule set carrying the key wins; such objects on other rule sets are ignored. Chromium deliberately does not merge or reconcile conflicting params across rule sets (“not worth it” for an experiment-only mechanism — document_speculation_rules.cc) |
| Application | Overrides are layered onto the default config each time anchor positions update (a scroll stop), only when the trial is enabled for the document; the use counter is recorded at that apply point, not at parse time |
| Candidate lifetime | A picked candidate is dropped if the user scrolls again during the dwell delay; the delay timer is also reset when new position updates arrive (including programmatic scroll) |
| Scope | Rule-set-wide — one object configures the heuristic for the whole document (subject to first-wins). It has no per-rule variant and no effect on non-moderate eagerness levels |
syntax
An optional top-level key of a speculation-rules rule set, alongside prefetch/prerender (the host grammar is defined by the Speculation Rules specification; this key is an experiment-only extension with no spec text):
{
"moderate_viewport_heuristics": {
"distance_from_pointer_down": [-0.5, 0.2],
"largest_anchor_threshold": 0.1,
"delay": 200
},
"prefetch": [
{
"source": "document",
"where": { "href_matches": "/*" },
"eagerness": "moderate"
}
]
}
| Field | Type | Default | Clamped to |
|---|---|---|---|
distance_from_pointer_down | [number, number] — [low, high] | [-0.3, 0.0] | each end to [-1, 1]; high raised to at least low |
largest_anchor_threshold | number | 0.25 | ≥ 0 |
delay | number (milliseconds) | 500 | 10–5000 per the implementation (the explainer table says 0–5000 — see the field reference for the privacy-review floor) |
All three fields are optional; unspecified fields keep the (Finch-adjustable) defaults. Malformed values and unknown sub-keys are ignored and never fail the rule set. Full per-field contracts: moderate_viewport_heuristics object reference.
Source: explainer — proposal + field table; speculation_rule_set.cc — parsing; anchor_element_interaction_tracker.cc — clampingexamples
Opting a document into wider experimentation: allow links slightly above and further below the last tap, demand less size dominance, and act sooner:
<script type="speculationrules">
{
"moderate_viewport_heuristics": {
"distance_from_pointer_down": [-0.5, 0.2],
"largest_anchor_threshold": 0.1,
"delay": 200
},
"prefetch": [
{
"source": "document",
"where": { "href_matches": "/*" },
"eagerness": "moderate"
}
]
}
</script>
A partial override — only the dwell delay changes; the other two parameters keep their defaults:
<script type="speculationrules">
{
"moderate_viewport_heuristics": { "delay": 1000 },
"prerender": [
{
"source": "document",
"where": { "href_matches": "/products/*" },
"eagerness": "moderate"
}
]
}
</script>
browser compatibility
Interim table. There is no BCD entry for this feature — BCD api/ has no SpeculationRules.json and no moderate_viewport_heuristics key anywhere (checked 2026-07-29) — and the webstatus.dev register covers only the host speculation-rules feature (Baseline limited). Rows below are compiled from the linked primary sources, not from BCD.
| Browser | Support | Evidence |
|---|---|---|
| Chrome for Android | Origin trial 152–157 (first- and third-party tokens) | milestone=152 listing (“Origin trial”); API-owner LGTM M152–M157; runtime flag record (origin_trial_os: ["Android"]) |
| Chrome desktop | Not applicable — the viewport heuristic only runs on Android; the trial is Android-only | Intent (“Android only”); runtime flag record comment (“the heuristic only runs on Android”) |
| Android WebView | Not supported — the trial’s OS restriction does not list WebView, and the intent records no WebView application risk | Intent; runtime flag record |
| Edge | Not separately reported | Chromium-based; no separate position on the ChromeStatus record (2026-07-29) |
| Firefox | No signal | Intent (“No signal, as this is an experiment-only feature”) |
| Safari | No signal | Intent (“No signal”) |
| Web developers | Positive — Shopify interested in experimenting | Intent; Shopify engineering blog |
Non-supporting browsers degrade silently: unknown speculation-rules keys are ignored by design, so a rule set carrying moderate_viewport_heuristics still works everywhere the Speculation Rules API itself works — the controls simply have no effect outside the trial.
security and privacy
- Dwell-delay floor (privacy review). The author-specifiable delay is clamped to a minimum of 10 ms — the implementation comment records that “a nonzero floor is enforced (per privacy review) so that authors cannot configure the heuristic to fire essentially immediately” (anchor_element_interaction_tracker.cc). The explainer’s
0–5000range predates or omits this floor; the implementation is authoritative. - No new data leaves the device. The parameters only retune when and whether the browser issues its own speculative loads for links already present in the page; the destination of a speculative fetch is unchanged. The privacy-relevant surface remains the underlying prefetch/prerender behavior of the Speculation Rules API, not the controls.
- Third-party tokens are deliberate, not an accident. The flag record allows third-party origin-trial tokens “so that scripts injecting speculation rules cross-origin (e.g. performance libraries) can opt in”; parse-time gating was rejected precisely because a third-party token can arrive after parsing (speculation_rule_set.cc).
- Abuse ceiling is bounded. Even the most aggressive legal values cannot exceed the existing
moderate-eagerness behavior class — at most one viewport candidate, only after a scroll stop, subject to the normal speculation-rules eligibility and user-preference constraints — and the experiment gathers parameter data, it does not relax any fetch-credential or cross-origin rules. - Measurement caveat. Because the parameters change prefetch/prerender timing, experiments should be evaluated against the site’s own privacy policy for any resulting change in speculative-request volume; no storage, identifiers, or cross-session state are added by this feature itself.
specifications
| Document | Status |
|---|---|
| “Mobile ‘moderate’ speculation-rules viewport heuristic controls” — explainer (Yoav Weiss, Google; gist, created 2026-06-22) | The only substantive design document: motivation, the three-check heuristic, the proposed grammar, defaults, and clamping |
| No specification | “No spec - this is an experiment-only feature” — Intent to Experiment; TAG review recorded N/A |
| Speculation Rules (WICG/nav-speculation) | The host API this object extends; does not itself define moderate_viewport_heuristics (2026-07-29) |
see also
- moderate_viewport_heuristics object reference — per-field contracts (this site)
- Chrome Platform Status — Speculation Rules - moderate viewport heuristics controls (API record; tracking bug 529423512)
- blink-dev — Intent to Experiment (mail-archive mirror) and the API-owner LGTM (M152–M157)
- blink-dev PSA — Speculation rules: mobile “moderate” eagerness improvements (the Chrome 138 behavior this feature tunes)
- MDN — Speculation Rules API (the host API; MDN does not cover this controls object — zero matches for
moderate_viewport_heuristicson the page and in MDN search, 2026-07-29) - Chrome Platform Showcase — interactive demos for this feature
- Shopify engineering — Faster storefront navigations with moderate speculation rules
- Chrome origin trials console (trial
SpeculationRulesModerateViewportHeuristicsControl)