[{"data":1,"prerenderedAt":1054},["ShallowReactive",2],{"content:\u002Fnetwork-protocol-optimization\u002Fspeculative-loading-and-prefetching\u002Fspeculation-rules-for-instant-navigations":3,"surroundings:\u002Fnetwork-protocol-optimization\u002Fspeculative-loading-and-prefetching\u002Fspeculation-rules-for-instant-navigations":1045},{"id":4,"title":5,"body":6,"description":1024,"extension":1025,"meta":1026,"navigation":1038,"path":1039,"seo":1040,"stem":1043,"__hash__":1044},"content\u002Fnetwork-protocol-optimization\u002Fspeculative-loading-and-prefetching\u002Fspeculation-rules-for-instant-navigations\u002Findex.md","Speculation Rules for Instant Navigations",{"type":7,"value":8,"toc":1006},"minimark",[9,14,29,61,216,221,256,260,266,272,278,284,288,293,411,415,421,453,457,468,472,475,578,692,696,710,714,717,721,724,787,791,797,801,827,831,837,843,849,855,859,873,882,891,900,917,926,943,952,965,969,992,996,999,1002],[10,11,13],"h1",{"id":12},"how-to-use-speculation-rules-for-instant-navigations","How to Use Speculation Rules for Instant Navigations",[15,16,17,18,23,24,28],"p",{},"This guide is part of ",[19,20,22],"a",{"href":21},"\u002Fnetwork-protocol-optimization\u002Fspeculative-loading-and-prefetching\u002F","Speculative Loading & Prefetching",", within ",[19,25,27],{"href":26},"\u002Fnetwork-protocol-optimization\u002F","Network & Server Response Optimization",". The Speculation Rules API lets a page tell the browser which URLs to prefetch or prerender, and when. A prerendered page loads in an invisible tab with all its resources and scripts; when the user navigates to it, the browser activates it in milliseconds. For content sites, search pages and e-commerce listings, where the next click is often predictable, speculation rules can make a large share of navigations effectively instant.",[15,30,31,32,36,37,40,41,44,45,49,50,49,53,56,57,60],{},"Rules come in two forms: ",[33,34,35],"strong",{},"list rules"," with explicit URLs, and ",[33,38,39],{},"document rules"," that match links in the page by URL pattern or CSS selector. Each rule has an ",[33,42,43],{},"eagerness"," that determines the trigger: ",[46,47,48],"code",{},"immediate",", ",[46,51,52],{},"eager",[46,54,55],{},"moderate"," (hover around 200ms, or pointer down) and ",[46,58,59],{},"conservative"," (pointer or touch down). Getting good results is mostly about choosing patterns and eagerness, excluding unsafe URLs, and checking what actually happens in DevTools.",[15,62,63],{},[64,65,71,72,71,79,71,83,71,86,71,95,71,101,71,112,71,117,71,125,71,132,71,138,71,142,71,146,71,151,71,156,71,162,71,166,71,171,71,177,71,181,71,185,71,189,71,193,71,197,71,201,71,205,71,209,71],"svg",{"viewBox":66,"width":67,"role":68,"ariaLabel":69,"style":70},"0 0 760 200","100%","img","Timeline showing a prerender starting on hover and the navigation activating instantly on click.","height:auto;max-width:760px;display:block;margin:1.75rem auto;font-family:inherit;color:var(--fp-svg-ink)"," ",[73,74],"rect",{"className":75,"x":77,"y":77,"width":67,"height":67,"fill":78},[76],"svg-canvas","0","#ffffff",[80,81,82],"title",{},"Moderate-eagerness prerender on hover",[84,85,69],"desc",{},[73,87],{"x":88,"y":88,"width":89,"height":90,"rx":91,"fill":92,"stroke":93,"style":94},"1","758","198","10","none","currentColor","stroke-opacity:0.18",[96,97,82],"text",{"x":98,"y":99,"fill":93,"style":100},"28.0","34.0","font-size:16px;font-weight:700",[102,103],"line",{"x1":104,"y1":105,"x2":104,"y2":106,"stroke":107,"strokeWidth":108,"strokeDashArray":109,"style":111},"710.1","72.0","156.0","#b8860b","1.5",[110,110],"4","stroke-opacity:0.9",[96,113,116],{"x":98,"y":114,"fill":93,"style":115},"96.0","font-size:12.5px;font-weight:700","User",[73,118],{"x":119,"y":120,"width":121,"height":122,"rx":123,"fill":93,"stroke":93,"style":124},"92.5","78.0","77.8","26.0","3","fill-opacity:0.06;stroke-opacity:0.4",[96,126,131],{"x":127,"y":128,"fill":93,"style":129,"textAnchor":130},"131.4","95.5","font-size:11.5px","middle","hover",[73,133],{"x":134,"y":120,"width":135,"height":122,"rx":123,"fill":136,"stroke":136,"style":137},"588.0","58.0","#0466c8","fill-opacity:0.14;stroke-opacity:0.9",[96,139,141],{"x":140,"y":128,"fill":93,"style":129,"textAnchor":130},"617.0","click",[96,143,145],{"x":98,"y":144,"fill":93,"style":115},"134.0","Browser",[73,147],{"x":148,"y":149,"width":150,"height":122,"rx":123,"fill":136,"stroke":136,"style":137},"171.8","116.0","394.9",[96,152,155],{"x":153,"y":154,"fill":93,"style":129,"textAnchor":130},"369.2","133.5","prerender in background",[73,157],{"x":158,"y":149,"width":159,"height":122,"rx":123,"fill":160,"stroke":107,"style":161},"647.5","61.9","#ffc300","fill-opacity:0.24;stroke-opacity:0.9",[96,163,165],{"x":164,"y":154,"fill":93,"style":129,"textAnchor":130},"678.4","shown",[102,167],{"x1":168,"y1":106,"x2":169,"y2":106,"stroke":93,"style":170},"91.8","726.0","stroke-opacity:0.4",[96,172,176],{"x":173,"y":174,"fill":175,"style":129,"textAnchor":130},"102.5","173.0","#51617a","0ms",[96,178,180],{"x":179,"y":174,"fill":175,"style":129,"textAnchor":130},"171.1","200ms",[96,182,184],{"x":183,"y":174,"fill":175,"style":129,"textAnchor":130},"250.3","400ms",[96,186,188],{"x":187,"y":174,"fill":175,"style":129,"textAnchor":130},"329.6","600ms",[96,190,192],{"x":191,"y":174,"fill":175,"style":129,"textAnchor":130},"408.9","800ms",[96,194,196],{"x":195,"y":174,"fill":175,"style":129,"textAnchor":130},"488.2","1000ms",[96,198,200],{"x":199,"y":174,"fill":175,"style":129,"textAnchor":130},"567.4","1200ms",[96,202,204],{"x":203,"y":174,"fill":175,"style":129,"textAnchor":130},"646.7","1400ms",[96,206,208],{"x":207,"y":174,"fill":175,"style":129,"textAnchor":130},"712.3","1600ms",[96,210,215],{"x":211,"y":212,"fill":213,"style":214,"textAnchor":130},"699.6","68.0","#8a6608","font-size:12px;font-weight:700","page visible",[217,218,220],"h2",{"id":219},"rapid-diagnosis","Rapid Diagnosis",[222,223,224,231,244,250],"ul",{},[225,226,227,230],"li",{},[33,228,229],{},"Open DevTools → Application → Speculative loads"," to see rules, candidates and status (not triggered, running, ready, failure with reason).",[225,232,233,239,240,243],{},[33,234,235,236],{},"Check ",[46,237,238],{},"document.prerendering"," in a prerendered page and ",[46,241,242],{},"activationStart"," in its navigation entry.",[225,245,246,249],{},[33,247,248],{},"Check navigation types"," in RUM to see how many navigations were prerendered.",[225,251,252,255],{},[33,253,254],{},"Check failure reasons",": unsupported features, memory limits, cross-origin restrictions, or server errors.",[217,257,259],{"id":258},"root-cause-analysis-why-rules-underperform","Root Cause Analysis: Why Rules Underperform",[15,261,262,265],{},[33,263,264],{},"1. Wrong eagerness."," Too conservative gives little lead time; too eager wastes resources.",[15,267,268,271],{},[33,269,270],{},"2. Patterns that miss real links."," Rules do not match the URLs users click.",[15,273,274,277],{},[33,275,276],{},"3. Prerender failures."," Pages using features disallowed during prerender, or responses with errors.",[15,279,280,283],{},[33,281,282],{},"4. Limits."," Browsers cap concurrent prerenders and skip speculation under data saver or low memory.",[217,285,287],{"id":286},"step-by-step-resolution","Step-by-Step Resolution",[289,290,292],"h3",{"id":291},"_1-start-with-document-rules-at-moderate-eagerness","1. Start with document rules at moderate eagerness",[294,295,300],"pre",{"className":296,"code":297,"language":298,"meta":299,"style":299},"language-html shiki shiki-themes github-light-high-contrast github-dark-high-contrast github-light-high-contrast","\u003Cscript type=\"speculationrules\">\n{\n  \"prerender\": [{\n    \"where\": { \"and\": [\n      { \"href_matches\": \"\u002F*\" },\n      { \"not\": { \"href_matches\": [\"\u002Flogout\", \"\u002Fcart\u002F*\", \"\u002F*\\\\?*add-to-cart=*\"] } },\n      { \"not\": { \"selector_matches\": \".no-speculate, [download]\" } }\n    ]},\n    \"eagerness\": \"moderate\"\n  }]\n}\n\u003C\u002Fscript>\n\u003C!-- trade-off: matching all same-site links is simple and safe at moderate\n     eagerness, but heavy pages still prerender on hover; exclude them explicitly. -->\n","html","",[46,301,302,328,334,340,346,352,358,364,370,376,382,388,398,405],{"__ignoreMap":299},[303,304,306,310,314,318,321,325],"span",{"class":102,"line":305},1,[303,307,309],{"class":308},"saISM","\u003C",[303,311,313],{"class":312},"sZBmE","script",[303,315,317],{"class":316},"sPXB4"," type",[303,319,320],{"class":308},"=",[303,322,324],{"class":323},"sZ8jY","\"speculationrules\"",[303,326,327],{"class":308},">\n",[303,329,331],{"class":102,"line":330},2,[303,332,333],{"class":308},"{\n",[303,335,337],{"class":102,"line":336},3,[303,338,339],{"class":308},"  \"prerender\": [{\n",[303,341,343],{"class":102,"line":342},4,[303,344,345],{"class":308},"    \"where\": { \"and\": [\n",[303,347,349],{"class":102,"line":348},5,[303,350,351],{"class":308},"      { \"href_matches\": \"\u002F*\" },\n",[303,353,355],{"class":102,"line":354},6,[303,356,357],{"class":308},"      { \"not\": { \"href_matches\": [\"\u002Flogout\", \"\u002Fcart\u002F*\", \"\u002F*\\\\?*add-to-cart=*\"] } },\n",[303,359,361],{"class":102,"line":360},7,[303,362,363],{"class":308},"      { \"not\": { \"selector_matches\": \".no-speculate, [download]\" } }\n",[303,365,367],{"class":102,"line":366},8,[303,368,369],{"class":308},"    ]},\n",[303,371,373],{"class":102,"line":372},9,[303,374,375],{"class":308},"    \"eagerness\": \"moderate\"\n",[303,377,379],{"class":102,"line":378},10,[303,380,381],{"class":308},"  }]\n",[303,383,385],{"class":102,"line":384},11,[303,386,387],{"class":308},"}\n",[303,389,391,394,396],{"class":102,"line":390},12,[303,392,393],{"class":308},"\u003C\u002F",[303,395,313],{"class":312},[303,397,327],{"class":308},[303,399,401],{"class":102,"line":400},13,[303,402,404],{"class":403},"sjfSM","\u003C!-- trade-off: matching all same-site links is simple and safe at moderate\n",[303,406,408],{"class":102,"line":407},14,[303,409,410],{"class":403},"     eagerness, but heavy pages still prerender on hover; exclude them explicitly. -->\n",[289,412,414],{"id":413},"_2-add-list-rules-for-high-confidence-next-pages","2. Add list rules for high-confidence next pages",[15,416,417,418,420],{},"For the top search result or the next article in a series, an ",[46,419,48],{}," list rule gives maximum lead time.",[294,422,424],{"className":296,"code":423,"language":298,"meta":299,"style":299},"\u003Cscript type=\"speculationrules\">\n{ \"prerender\": [{ \"urls\": [\"\u002Farticles\u002Fpart-2\u002F\"], \"eagerness\": \"immediate\" }] }\n\u003C\u002Fscript>\n",[46,425,426,440,445],{"__ignoreMap":299},[303,427,428,430,432,434,436,438],{"class":102,"line":305},[303,429,309],{"class":308},[303,431,313],{"class":312},[303,433,317],{"class":316},[303,435,320],{"class":308},[303,437,324],{"class":323},[303,439,327],{"class":308},[303,441,442],{"class":102,"line":330},[303,443,444],{"class":308},"{ \"prerender\": [{ \"urls\": [\"\u002Farticles\u002Fpart-2\u002F\"], \"eagerness\": \"immediate\" }] }\n",[303,446,447,449,451],{"class":102,"line":336},[303,448,393],{"class":308},[303,450,313],{"class":312},[303,452,327],{"class":308},[289,454,456],{"id":455},"_3-deliver-rules-via-header-for-many-pages","3. Deliver rules via header for many pages",[15,458,459,460,463,464,467],{},"The ",[46,461,462],{},"Speculation-Rules"," response header can point to an external JSON file (served with ",[46,465,466],{},"Content-Type: application\u002Fspeculationrules+json","), so rules can be updated centrally without changing templates.",[289,469,471],{"id":470},"_4-make-pages-prerender-safe","4. Make pages prerender-safe",[15,473,474],{},"Delay analytics, ads and side effects until activation; avoid triggering permission prompts or media playback before activation.",[294,476,480],{"className":477,"code":478,"language":479,"meta":299,"style":299},"language-javascript shiki shiki-themes github-light-high-contrast github-dark-high-contrast github-light-high-contrast","function whenActivated(cb) {\n  if (document.prerendering) document.addEventListener('prerenderingchange', cb, { once: true });\n  else cb();\n}\nwhenActivated(() => { sendPageView(); startChat(); });\n\u002F\u002F trade-off: deferring everything to activation delays work for prerendered pages\n\u002F\u002F slightly after display; keep rendering work in the prerender, defer side effects only.\n","javascript",[46,481,482,502,527,538,542,568,573],{"__ignoreMap":299},[303,483,484,488,492,495,499],{"class":102,"line":305},[303,485,487],{"class":486},"sPARh","function",[303,489,491],{"class":490},"smZ65"," whenActivated",[303,493,494],{"class":308},"(",[303,496,498],{"class":497},"sQw3B","cb",[303,500,501],{"class":308},") {\n",[303,503,504,507,510,513,515,518,521,524],{"class":102,"line":330},[303,505,506],{"class":486},"  if",[303,508,509],{"class":308}," (document.prerendering) document.",[303,511,512],{"class":490},"addEventListener",[303,514,494],{"class":308},[303,516,517],{"class":323},"'prerenderingchange'",[303,519,520],{"class":308},", cb, { once: ",[303,522,523],{"class":316},"true",[303,525,526],{"class":308}," });\n",[303,528,529,532,535],{"class":102,"line":336},[303,530,531],{"class":486},"  else",[303,533,534],{"class":490}," cb",[303,536,537],{"class":308},"();\n",[303,539,540],{"class":102,"line":342},[303,541,387],{"class":308},[303,543,544,547,550,553,556,559,562,565],{"class":102,"line":348},[303,545,546],{"class":490},"whenActivated",[303,548,549],{"class":308},"(() ",[303,551,552],{"class":486},"=>",[303,554,555],{"class":308}," { ",[303,557,558],{"class":490},"sendPageView",[303,560,561],{"class":308},"(); ",[303,563,564],{"class":490},"startChat",[303,566,567],{"class":308},"(); });\n",[303,569,570],{"class":102,"line":354},[303,571,572],{"class":403},"\u002F\u002F trade-off: deferring everything to activation delays work for prerendered pages\n",[303,574,575],{"class":102,"line":360},[303,576,577],{"class":403},"\u002F\u002F slightly after display; keep rendering work in the prerender, defer side effects only.\n",[15,579,580],{},[64,581,71,584,71,587,71,590,71,592,71,595,71,597,71,602,71,608,71,612,71,616,71,619,71,623,71,627,71,631,71,633,71,637,71,639,71,642,71,644,71,648,71,650,71,653,71,655,71,658,71,661,71,665,71,667,71,670,71,672,71,675,71,678,71,682,71,684,71,687,71,689,71],{"viewBox":582,"width":67,"role":68,"ariaLabel":583,"style":70},"0 0 760 228","Comparison of speculation rules that list URLs explicitly and rules that match links in the document.",[73,585],{"className":586,"x":77,"y":77,"width":67,"height":67,"fill":78},[76],[80,588,589],{},"List rules vs document rules",[84,591,583],{},[73,593],{"x":88,"y":88,"width":89,"height":594,"rx":91,"fill":92,"stroke":93,"style":94},"226",[96,596,589],{"x":98,"y":99,"fill":93,"style":100},[73,598],{"x":98,"y":599,"width":600,"height":601,"rx":77,"fill":93,"stroke":93,"style":124},"56.0","149.2","30.0",[96,603,607],{"x":604,"y":605,"fill":93,"style":115,"textAnchor":606},"38.0","75.5","start","Aspect",[73,609],{"x":610,"y":599,"width":611,"height":601,"rx":77,"fill":93,"stroke":93,"style":124},"177.2","277.4",[96,613,615],{"x":614,"y":605,"fill":93,"style":115,"textAnchor":130},"315.9","List rules",[73,617],{"x":618,"y":599,"width":611,"height":601,"rx":77,"fill":93,"stroke":93,"style":124},"454.6",[96,620,622],{"x":621,"y":605,"fill":93,"style":115,"textAnchor":130},"593.3","Document rules",[73,624],{"x":98,"y":625,"width":600,"height":601,"rx":77,"fill":92,"stroke":93,"style":626},"86.0","stroke-opacity:0.35",[96,628,630],{"x":604,"y":629,"fill":93,"style":115,"textAnchor":606},"105.5","How URLs are chosen",[73,632],{"x":610,"y":625,"width":611,"height":601,"rx":77,"fill":92,"stroke":93,"style":626},[96,634,636],{"x":614,"y":629,"fill":93,"style":635,"textAnchor":130},"font-size:12px","explicit URLs",[73,638],{"x":618,"y":625,"width":611,"height":601,"rx":77,"fill":92,"stroke":93,"style":626},[96,640,641],{"x":621,"y":629,"fill":93,"style":635,"textAnchor":130},"links matching patterns or selectors",[73,643],{"x":98,"y":149,"width":600,"height":601,"rx":77,"fill":92,"stroke":93,"style":626},[96,645,647],{"x":604,"y":646,"fill":93,"style":115,"textAnchor":606},"135.5","Best for",[73,649],{"x":610,"y":149,"width":611,"height":601,"rx":77,"fill":136,"stroke":136,"style":137},[96,651,652],{"x":614,"y":646,"fill":93,"style":635,"textAnchor":130},"known next page",[73,654],{"x":618,"y":149,"width":611,"height":601,"rx":77,"fill":136,"stroke":136,"style":137},[96,656,657],{"x":621,"y":646,"fill":93,"style":635,"textAnchor":130},"many possible links",[73,659],{"x":98,"y":660,"width":600,"height":601,"rx":77,"fill":92,"stroke":93,"style":626},"146.0",[96,662,664],{"x":604,"y":663,"fill":93,"style":115,"textAnchor":606},"165.5","Typical eagerness",[73,666],{"x":610,"y":660,"width":611,"height":601,"rx":77,"fill":92,"stroke":93,"style":626},[96,668,669],{"x":614,"y":663,"fill":93,"style":635,"textAnchor":130},"immediate or eager",[73,671],{"x":618,"y":660,"width":611,"height":601,"rx":77,"fill":92,"stroke":93,"style":626},[96,673,674],{"x":621,"y":663,"fill":93,"style":635,"textAnchor":130},"moderate or conservative",[73,676],{"x":98,"y":677,"width":600,"height":601,"rx":77,"fill":92,"stroke":93,"style":626},"176.0",[96,679,681],{"x":604,"y":680,"fill":93,"style":115,"textAnchor":606},"195.5","Maintenance",[73,683],{"x":610,"y":677,"width":611,"height":601,"rx":77,"fill":93,"stroke":93,"style":124},[96,685,686],{"x":614,"y":680,"fill":93,"style":635,"textAnchor":130},"generate per page",[73,688],{"x":618,"y":677,"width":611,"height":601,"rx":77,"fill":136,"stroke":136,"style":137},[96,690,691],{"x":621,"y":680,"fill":93,"style":635,"textAnchor":130},"one rule for the site",[217,693,695],{"id":694},"verification","Verification",[15,697,698,699,701,702,705,706,709],{},"In DevTools' Speculative loads panel, hover a matching link and watch the status move to \"Running\" then \"Ready\"; click and check that the navigation entry shows a non-zero ",[46,700,242],{},". Use the panel's failure reasons to fix pages that cannot be prerendered. In RUM, track the share of navigations with ",[46,703,704],{},"type: prerender"," (web-vitals reports ",[46,707,708],{},"navigationType","), their LCP, and hit rates.",[217,711,713],{"id":712},"worked-example-a-documentation-platform","Worked Example: A Documentation Platform",[15,715,716],{},"A documentation platform added a single moderate-eagerness prerender rule for all same-site documentation links, excluding API playground pages (which opened WebSocket connections) and downloads. Within a week, 44% of subsequent navigations were prerendered, LCP p75 for subsequent navigations dropped from 1.2 seconds to 0.3 seconds, and INP improved slightly because startup JavaScript had already run. Server requests increased by 11%; since documentation HTML was cached at the CDN with a 95% hit ratio, origin load was nearly unchanged.",[217,718,720],{"id":719},"common-failure-reasons","Common Failure Reasons",[15,722,723],{},"DevTools lists specific reasons when a prerender is cancelled. Frequent ones include: the page used a feature not allowed in prerender before activation (some APIs are deferred, others cause cancellation); the response was not a 200 (redirects to other origins, errors); the user's device was low on memory; too many prerenders were in progress; the prerendered page was navigated cross-origin; or the user has a data saver setting. Many of these are expected and harmless. Persistent failures for a URL pattern indicate a page that needs fixing or excluding.",[15,725,726],{},[64,727,71,730,71,733,71,736,71,738,71,741,71,743,71,750,71,756,71,761,71,765,71,770,71,774,71,778,71,783,71],{"viewBox":728,"width":67,"role":68,"ariaLabel":729,"style":70},"0 0 760 163","Bar chart of prerender outcomes showing used, unused and failed prerenders for one site over a week.",[73,731],{"className":732,"x":77,"y":77,"width":67,"height":67,"fill":78},[76],[80,734,735],{},"Prerender outcomes over one week (moderate eagerness)",[84,737,729],{},[73,739],{"x":88,"y":88,"width":89,"height":740,"rx":91,"fill":92,"stroke":93,"style":94},"161",[96,742,735],{"x":98,"y":99,"fill":93,"style":100},[96,744,749],{"x":745,"y":746,"fill":93,"style":747,"textAnchor":748},"148.0","70.0","font-size:13px","end","Activated (used)",[73,751],{"x":752,"y":599,"width":753,"height":754,"rx":123,"fill":160,"stroke":107,"style":755},"160.0","508.0","19","fill-opacity:0.7;stroke-opacity:0.9",[96,757,760],{"x":758,"y":746,"fill":93,"style":759},"674.0","font-size:12px;font-weight:600","63% of started",[96,762,764],{"x":745,"y":763,"fill":93,"style":747,"textAnchor":748},"101.0","Not clicked (expired)",[73,766],{"x":752,"y":767,"width":768,"height":754,"rx":123,"fill":136,"stroke":136,"style":769},"87.0","250.0","fill-opacity:0.55;stroke-opacity:0.9",[96,771,773],{"x":772,"y":763,"fill":93,"style":759},"415.9","31% of started",[96,775,777],{"x":745,"y":776,"fill":93,"style":747,"textAnchor":748},"132.0","Failed or cancelled",[73,779],{"x":752,"y":780,"width":781,"height":754,"rx":123,"fill":92,"stroke":93,"style":782},"118.0","48.4","fill-opacity:0.7;stroke-opacity:0.35",[96,784,786],{"x":785,"y":776,"fill":93,"style":759},"214.3","6% of started",[217,788,790],{"id":789},"rolling-out-rules-gradually","Rolling Out Rules Gradually",[15,792,793,794,796],{},"Start with conservative prefetch for all same-site links: it is cheap, safe and gives a baseline of how often speculation is used. Then add moderate prerender for one well-understood pattern — articles, documentation pages or product pages — and watch hit rates, failure reasons and server load for a week. Expand to further patterns one at a time. Because rules are just JSON, they can be served from a central file via the ",[46,795,462],{}," header and adjusted without redeploying templates, which makes tuning fast. Keep a list of excluded URL patterns with the reason for each exclusion, so future changes do not accidentally re-enable speculation on side-effecting URLs. Review the list whenever new routes are added.",[217,798,800],{"id":799},"common-mistakes","Common Mistakes",[222,802,803,809,815,821],{},[225,804,805,808],{},[33,806,807],{},"Prerendering logout, add-to-cart or one-time links."," Side effects happen without a click.",[225,810,811,814],{},[33,812,813],{},"Firing analytics during prerender."," Inflated page views.",[225,816,817,820],{},[33,818,819],{},"Immediate eagerness on broad patterns."," Large waste and memory pressure.",[225,822,823,826],{},[33,824,825],{},"Assuming all browsers prerender."," Non-Chromium browsers ignore rules.",[217,828,830],{"id":829},"edge-cases","Edge Cases",[15,832,833,836],{},[33,834,835],{},"Single-page applications."," Speculation rules apply to document navigations; SPA route changes use the framework's own prefetching.",[15,838,839,842],{},[33,840,841],{},"Cookies and state."," Prerendered pages see cookies at prerender time; state changes before activation may make content stale.",[15,844,845,848],{},[33,846,847],{},"Cross-origin."," Cross-origin prerender is limited; prefetch can work cross-site with restrictions.",[15,850,851,854],{},[33,852,853],{},"Rules added dynamically."," Rules inserted by script are honoured, useful for injecting predictions after load.",[217,856,858],{"id":857},"faq","FAQ",[860,861,864,868],"details",{"className":862},[863],"faq-item",[865,866,867],"summary",{},"What eagerness should I start with?",[15,869,870,872],{},[46,871,55],{}," for prerender with document rules. It speculates on hover or pointer down and achieves high hit rates with modest waste.",[860,874,876,879],{"className":875},[863],[865,877,878],{},"How many pages can be prerendered at once?",[15,880,881],{},"Browsers limit concurrent prerenders per eagerness level; for immediate and eager rules the limit is small, and moderate\u002Fconservative prerenders replace older ones.",[860,883,885,888],{"className":884},[863],[865,886,887],{},"Can I use speculation rules on a static site?",[15,889,890],{},"Yes. A script block in the page template is all that is needed, and static pages are usually safe to prerender.",[860,892,894,897],{"className":893},[863],[865,895,896],{},"Do speculation rules work with service workers?",[15,898,899],{},"Yes. Prerendered and prefetched navigations can be served by a service worker, which can make them cheaper.",[860,901,903,906],{"className":902},[863],[865,904,905],{},"How does the server know a request is speculative?",[15,907,908,909,912,913,916],{},"Speculative requests carry a ",[46,910,911],{},"Sec-Purpose: prefetch"," header (with ",[46,914,915],{},";prerender"," for prerenders), which servers can log or use to deprioritise.",[860,918,920,923],{"className":919},[863],[865,921,922],{},"Does prerendering use the user's data plan?",[15,924,925],{},"Yes, for the resources it loads. Browsers disable or reduce speculation in data saver modes.",[860,927,929,932],{"className":928},[863],[865,930,931],{},"Can I exclude a single link?",[15,933,934,935,938,939,942],{},"Yes, with a ",[46,936,937],{},"not"," condition on a selector (for example a class like ",[46,940,941],{},".no-speculate",") or URL pattern.",[860,944,946,949],{"className":945},[863],[865,947,948],{},"Are prerendered pages counted in Core Web Vitals?",[15,950,951],{},"Yes. Their metrics are measured from activation, so they usually report excellent LCP, which improves the page's field data.",[860,953,955,958],{"className":954},[863],[865,956,957],{},"Do I need a server change to use speculation rules?",[15,959,960,961,964],{},"No. A script block in the HTML is enough. The header form and ",[46,962,963],{},"Sec-Purpose"," handling are optional refinements.",[217,966,968],{"id":967},"related","Related",[222,970,971,978,985],{},[225,972,973,977],{},[19,974,976],{"href":975},"\u002Fnetwork-protocol-optimization\u002Fspeculative-loading-and-prefetching\u002Fprerender-vs-prefetch-cost-trade-offs\u002F","Prerender vs prefetch cost trade-offs"," — choosing the right action.",[225,979,980,984],{},[19,981,983],{"href":982},"\u002Fnetwork-protocol-optimization\u002Fspeculative-loading-and-prefetching\u002Favoiding-analytics-double-counting-on-prerender\u002F","Avoiding analytics double counting on prerender"," — prerender-safe measurement.",[225,986,987,991],{},[19,988,990],{"href":989},"\u002Frendering-css-performance\u002Fanimation-and-compositing-performance\u002Fview-transitions-api-performance\u002F","View Transitions API performance"," — animating instant navigations.",[313,993,995],{"type":994},"application\u002Fld+json","\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"HowTo\",\n  \"name\": \"How to Use Speculation Rules for Instant Navigations\",\n  \"description\": \"A practical guide to writing, deploying and debugging speculation rules so likely next pages load instantly.\",\n  \"step\": [\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 1,\n      \"name\": \"Start with document rules at moderate eagerness\",\n      \"text\": \"Start with document rules at moderate eagerness\"\n    },\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 2,\n      \"name\": \"Add list rules for high-confidence next pages\",\n      \"text\": \"For the top search result or the next article in a series, an immediate list rule gives maximum lead time.\"\n    },\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 3,\n      \"name\": \"Deliver rules via header for many pages\",\n      \"text\": \"The Speculation-Rules response header can point to an external JSON file (served with Content-Type: application\u002Fspeculationrules+json), so rules can be updated centrally without changing templates.\"\n    },\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 4,\n      \"name\": \"Make pages prerender-safe\",\n      \"text\": \"Delay analytics, ads and side effects until activation; avoid triggering permission prompts or media playback before activation.\"\n    }\n  ]\n}\n",[313,997,998],{"type":994},"\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"TechArticle\",\n  \"headline\": \"How to Use Speculation Rules for Instant Navigations\",\n  \"description\": \"A practical guide to writing, deploying and debugging speculation rules so likely next pages load instantly.\",\n  \"datePublished\": \"2026-10-06\",\n  \"dateModified\": \"2026-10-06\",\n  \"author\": {\n    \"@type\": \"Organization\",\n    \"name\": \"frontend-performance.com\"\n  },\n  \"publisher\": {\n    \"@type\": \"Organization\",\n    \"name\": \"frontend-performance.com\"\n  },\n  \"mainEntityOfPage\": {\n    \"@type\": \"WebPage\",\n    \"@id\": \"https:\u002F\u002Ffrontend-performance.com\u002Fnetwork-protocol-optimization\u002Fspeculative-loading-and-prefetching\u002Fspeculation-rules-for-instant-navigations\u002F\"\n  }\n}\n",[313,1000,1001],{"type":994},"\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"BreadcrumbList\",\n  \"itemListElement\": [\n    {\n      \"@type\": \"ListItem\",\n      \"position\": 1,\n      \"name\": \"Home\",\n      \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002F\"\n    },\n    {\n      \"@type\": \"ListItem\",\n      \"position\": 2,\n      \"name\": \"Network & Server Response Optimization\",\n      \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fnetwork-protocol-optimization\u002F\"\n    },\n    {\n      \"@type\": \"ListItem\",\n      \"position\": 3,\n      \"name\": \"Speculative Loading & Prefetching\",\n      \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fnetwork-protocol-optimization\u002Fspeculative-loading-and-prefetching\u002F\"\n    },\n    {\n      \"@type\": \"ListItem\",\n      \"position\": 4,\n      \"name\": \"Speculation Rules for Instant Navigations\",\n      \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fnetwork-protocol-optimization\u002Fspeculative-loading-and-prefetching\u002Fspeculation-rules-for-instant-navigations\u002F\"\n    }\n  ]\n}\n",[1003,1004,1005],"style",{},"html pre.shiki code .saISM, html code.shiki .saISM{--shiki-default:#0E1116;--shiki-dark:#F0F3F6;--shiki-light:#0E1116}html pre.shiki code .sZBmE, html code.shiki .sZBmE{--shiki-default:#024C1A;--shiki-dark:#72F088;--shiki-light:#024C1A}html pre.shiki code .sPXB4, html code.shiki .sPXB4{--shiki-default:#023B95;--shiki-dark:#91CBFF;--shiki-light:#023B95}html pre.shiki code .sZ8jY, html code.shiki .sZ8jY{--shiki-default:#032563;--shiki-dark:#ADDCFF;--shiki-light:#032563}html pre.shiki code .sjfSM, html code.shiki .sjfSM{--shiki-default:#66707B;--shiki-dark:#BDC4CC;--shiki-light:#66707B}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html pre.shiki code .sPARh, html code.shiki .sPARh{--shiki-default:#A0111F;--shiki-dark:#FF9492;--shiki-light:#A0111F}html pre.shiki code .smZ65, html code.shiki .smZ65{--shiki-default:#622CBC;--shiki-dark:#DBB7FF;--shiki-light:#622CBC}html pre.shiki code .sQw3B, html code.shiki .sQw3B{--shiki-default:#702C00;--shiki-dark:#FFB757;--shiki-light:#702C00}",{"title":299,"searchDepth":330,"depth":330,"links":1007},[1008,1009,1010,1016,1017,1018,1019,1020,1021,1022,1023],{"id":219,"depth":330,"text":220},{"id":258,"depth":330,"text":259},{"id":286,"depth":330,"text":287,"children":1011},[1012,1013,1014,1015],{"id":291,"depth":336,"text":292},{"id":413,"depth":336,"text":414},{"id":455,"depth":336,"text":456},{"id":470,"depth":336,"text":471},{"id":694,"depth":330,"text":695},{"id":712,"depth":330,"text":713},{"id":719,"depth":330,"text":720},{"id":789,"depth":330,"text":790},{"id":799,"depth":330,"text":800},{"id":829,"depth":330,"text":830},{"id":857,"depth":330,"text":858},{"id":967,"depth":330,"text":968},"A practical guide to writing, deploying and debugging speculation rules so likely next pages load instantly.","md",{"slug":1027,"type":1028,"breadcrumb":1029,"datePublished":1037,"dateModified":1037},"speculation-rules-for-instant-navigations","article",[1030,1033,1034,1035],{"name":1031,"url":1032},"Home","\u002F",{"name":27,"url":26},{"name":22,"url":21},{"name":5,"url":1036},"\u002Fnetwork-protocol-optimization\u002Fspeculative-loading-and-prefetching\u002Fspeculation-rules-for-instant-navigations\u002F","2026-10-06",true,"\u002Fnetwork-protocol-optimization\u002Fspeculative-loading-and-prefetching\u002Fspeculation-rules-for-instant-navigations",{"title":1041,"description":1042},"Speculation Rules API for Instant Navigations","Write speculation rules that prerender and prefetch likely next pages: list and document rules, eagerness, exclusions, the Speculation-Rules header and debugging.","network-protocol-optimization\u002Fspeculative-loading-and-prefetching\u002Fspeculation-rules-for-instant-navigations\u002Findex","8llyoEW7-WW0mKm1fBW1ShtZzQYlEA_5aadmYmjpvqg",[1046,1050],{"title":1047,"path":1048,"stem":1049,"children":-1},"Prerender vs Prefetch Cost Trade-Offs","\u002Fnetwork-protocol-optimization\u002Fspeculative-loading-and-prefetching\u002Fprerender-vs-prefetch-cost-trade-offs","network-protocol-optimization\u002Fspeculative-loading-and-prefetching\u002Fprerender-vs-prefetch-cost-trade-offs\u002Findex",{"title":1051,"path":1052,"stem":1053,"children":-1},"Viewport Prefetching with Quicklink","\u002Fnetwork-protocol-optimization\u002Fspeculative-loading-and-prefetching\u002Fviewport-prefetching-with-quicklink","network-protocol-optimization\u002Fspeculative-loading-and-prefetching\u002Fviewport-prefetching-with-quicklink\u002Findex",1791308069638]