@prefix sioc: <http://rdfs.org/sioc/ns#> .
@prefix dc: <http://purl.org/dc/elements/1.1/> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix content: <http://purl.org/rss/1.0/modules/content/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .

<https://lhero.org/?post_type=lh-portfolio-doc&#038;p=150178>
  a sioc:Post ;
  dc:title "Notes" ;
  dcterms:identifier 150178 ;
  dc:modified "2026-10-13T17:16:36Z"^^xsd:dateTime ;
  dc:created "2026-10-13T17:02:34Z"^^xsd:dateTime ;
  sioc:link <https://lhero.org/portfolio/lh-jumpstart/notes/> ;
  sioc:has_creator <https://lhero.org/author/1/#account> ;
  sioc:has_container <https://lhero.org/#posts> ;
  content:encoded """<ul class="lh_portfolio-meta"><li><strong>Part of:</strong> <a href="https://lhero.org/portfolio/lh-jumpstart/">LH Jumpstart</a></li></ul>
<h2 class="wp-block-heading">Who gets what</h2>



<ul class="wp-block-list">
<li><strong>Logged out, browser supports speculation rules:</strong> native eager prerender.</li>



<li><strong>Logged in, browser supports speculation rules:</strong> native prefetch on hover or pointer-down (moderate eagerness). Prefetch fetches the document without running its scripts, so analytics, Heartbeat and similar page JavaScript do not fire.</li>



<li><strong>Browser without speculation rules, or a page with none</strong> (for example a site without pretty permalinks): the fallback script.</li>
</ul>



<h2 class="wp-block-heading">Fallback script</h2>



<ul class="wp-block-list">
<li>The script runs only if <code>HTMLScriptElement.supports('speculationrules')</code> is false or missing (Firefox before 94, Safari before 16, older Chromium), or the page contains no <code>script[type="speculationrules"]</code>. Otherwise it does nothing and the native rules do the work.</li>



<li>Hovered and touched links go into a priority queue, and links in the viewport (rescanned 100 ms after scrolling stops, and when a <code>dialog</code> opens) into a normal queue. Every 2 seconds up to <code>maxRPS</code> URLs (default 3) are prefetched, priority first, and the timer stops once both queues are empty.</li>



<li>A URL is prefetched with <code>&lt;link rel="prefetch" as="document"&gt;</code> where the browser supports it, otherwise with a credentialed <code>fetch()</code>. URLs already prefetched, including <code>rel="prefetch"</code> links other plugins put in the page, are not fetched again, and the current page is never prefetched.</li>



<li>It skips URLs with a query string, any URL containing <code>nonce</code>, and URLs matching the ignore lists.</li>



<li><code>maxRPS</code> can be overridden by defining <code>window.FPConfig</code> before the script runs.</li>
</ul>



<h2 class="wp-block-heading">Gotchas</h2>



<ul class="wp-block-list">
<li><strong>GET requests with side effects.</strong> Core keeps speculation off for logged-in users largely because some page views change state. Action links carry nonces and query strings, so they are already excluded. Plain views that mark things read are not, which is why a member&#8217;s own BuddyPress profile area (messages, notifications, mentions, friend requests, group invites) is excluded. Any other plugin with a view that changes state should add its URLs to <code>lh_jumpstart_return_ignore_prefix_urls</code>, or skip the side effect when the request carries <code>Sec-Purpose: prefetch</code>.</li>



<li>Before 1.1.0 the ignore lists were passed to core as an <code>href_exclude</code> key on the configuration, which core discards, so they only ever reached the fallback script.</li>



<li>The script is registered through the bundled <code>LH_Register_file_class</code> (<code>includes/lh-register-file-class.php</code>), whose retirement across the lh- plugins is tracked in lh-tasks #148564.</li>
</ul>
"""^^rdf:XMLLiteral ;
  sioc:content """Part of: LH Jumpstart
Who gets what




Logged out, browser supports speculation rules: native eager prerender.



Logged in, browser supports speculation rules: native prefetch on hover or pointer-down (moderate eagerness). Prefetch fetches the document without running its scripts, so analytics, Heartbeat and similar page JavaScript do not fire.



Browser without speculation rules, or a page with none (for example a site without pretty permalinks): the fallback script.




Fallback script




The script runs only if HTMLScriptElement.supports('speculationrules') is false or missing (Firefox before 94, Safari before 16, older Chromium), or the page contains no script[type="speculationrules"]. Otherwise it does nothing and the native rules do the work.



Hovered and touched links go into a priority queue, and links in the viewport (rescanned 100 ms after scrolling stops, and when a dialog opens) into a normal queue. Every 2 seconds up to maxRPS URLs (default 3) are prefetched, priority first, and the timer stops once both queues are empty.



A URL is prefetched with &lt;link rel="prefetch" as="document"&gt; where the browser supports it, otherwise with a credentialed fetch(). URLs already prefetched, including rel="prefetch" links other plugins put in the page, are not fetched again, and the current page is never prefetched.



It skips URLs with a query string, any URL containing nonce, and URLs matching the ignore lists.



maxRPS can be overridden by defining window.FPConfig before the script runs.




Gotchas




GET requests with side effects. Core keeps speculation off for logged-in users largely because some page views change state. Action links carry nonces and query strings, so they are already excluded. Plain views that mark things read are not, which is why a member&#8217;s own BuddyPress profile area (messages, notifications, mentions, friend requests, group invites) is excluded. Any other plugin with a view that changes state should add its URLs to lh_jumpstart_return_ignore_prefix_urls, or skip the side effect when the request carries Sec-Purpose: prefetch.



Before 1.1.0 the ignore lists were passed to core as an href_exclude key on the configuration, which core discards, so they only ever reached the fallback script.



The script is registered through the bundled LH_Register_file_class (includes/lh-register-file-class.php), whose retirement across the lh- plugins is tracked in lh-tasks #148564.

""" ;
  sioc:topic <https://lhero.org/?taxonomy=author&term=cap-1> .

<https://lhero.org/author/1/#account> rdfs:seeAlso <https://lhero.org/author/1/?feed=lhrdf&format=turtle> .
<https://lhero.org/?taxonomy=author&term=cap-1> rdfs:seeAlso <https://lhero.org/?taxonomy=author&term=cap-1&feed=lhrdf&format=turtle> .
