sandywp / plugins / speculation-rules
Speculative Loading
Enables browsers to speculatively prerender or prefetch pages to achieve near-instant loads based on user interaction.
Ready in seconds.
v1.7.0 70,000+ installs WP 6.9+ PHP 7.4+

About this plugin
This plugin adds support for the Speculation Rules API, which allows defining rules by which certain URLs are dynamically prefetched or prerendered. This core Speculative Loading functionality was merged into WordPress 6.8, but it only prefetches with conservative eagerness by default. In contrast, this plugin defaults to prerendering with moderate eagerness (i.e. when interacting with a link), and it provides a user interface to customize the mode and eagerness via the “Speculative Loading” section on the Settings > Reading admin screen.
By default, speculative loading is only enabled for logged-out users, since unauthenticated pages are typically only eligible for caching and so more efficient to prefetch/prerender. This means that sites with frequent logged-in users on the frontend—such as e-commerce, forums, or membership sites—will not benefit from the feature. If your server can handle the additional load (for example, with persistent object caching), you can opt in to enable speculative loading for all logged-in users or for administrators only. This setting exclusively affects frontend pages; admin screens are always excluded.
A filter can be used to exclude certain URL paths from being eligible for prefetching and prerendering (see FAQ section). Alternatively, you can add the no-prerender CSS class to any link (<a> tag) that should not be prerendered. See FAQ for more information.
Browser support
The Speculation Rules API is a new web API, and the functionality used by the plugin is supported in Chromium-based browsers such as Chrome, Edge, or Opera using version 121 or above. Other browsers such as Safari and Firefox will ignore the functionality with no ill effects; they will simply not benefit from the speculative loading. Note that certain browser extensions may disable preloading by default.
- Browser support for the Speculation Rules API in general
- Information on document rules syntax support used by the plugin
This plugin was formerly known as Speculation Rules.
Questions
- How can I prevent certain URLs from being prefetched and prerendered?
Not every URL can be reasonably prerendered. Prerendering static content is typically reliable, however prerendering interactive content, such as a logout URL, can lead to issues. For this reason, certain WordPress core URLs such as
/wp-login.phpand/wp-admin/*are excluded from prefetching and prerendering. Additionally, any URLs generated withwp_nonce_url()(or which contains the_wpnoncequery var) andnofollowlinks are also ignored. You can exclude additional URL patterns by using theplsr_speculation_rules_href_exclude_pathsfilter.The following example ensures that URLs like
https://example.com/cart/orhttps://example.com/cart/fooare excluded from prefetching and prerendering:<?php add_filter( 'plsr_speculation_rules_href_exclude_paths', function ( array $exclude_paths ): array { $exclude_paths[] = '/cart/*'; return $exclude_paths; } );Keep in mind that sometimes it may be useful to exclude a URL from prerendering while still allowing it to be prefetched. For example, a page with client-side JavaScript to update user state should probably not be prerendered, but it would be reasonable to prefetch.
For this purpose, the
plsr_speculation_rules_href_exclude_pathsfilter receives the current mode (either “prefetch” or “prerender”) to provide conditional exclusions.The following example ensures that URLs like
https://example.com/products/...cannot be prerendered, while still allowing them to be prefetched:<?php add_filter( 'plsr_speculation_rules_href_exclude_paths', function ( array $exclude_paths, string $mode ): array { if ( 'prerender' === $mode ) { $exclude_paths[] = '/products/*'; } return $exclude_paths; }, 10, 2 );As mentioned above, adding the
no-prerenderCSS class to a link will prevent it from being prerendered (but not prefetched). Additionally, links withrel=nofollowwill neither be prefetched nor prerendered because some plugins add this to non-idempotent links (e.g. add to cart); such links ideally should rather be buttons which trigger a POST request or at least they should usewp_nonce_url().- Are there any special considerations for speculative loading behavior?
For safety reasons, the entire speculative loading feature is disabled by default for logged-in users and for sites that do not use pretty permalinks. The latter is the case because plugins often use URLs with custom query parameters to let users perform actions, and such URLs should not be speculatively loaded. For sites without pretty permalinks, it is impossible or at least extremely complex to differentiate between which query parameters are Core defaults and which query parameters are custom.
If you are running this plugin on a site without pretty permalinks and are confident that there are no custom query parameters in use that can cause state changes, you can opt in to enabling speculative loading via the
plsr_enabled_without_pretty_permalinksfilter:<?php add_filter( 'plsr_enabled_without_pretty_permalinks', '__return_true' );- How will this impact analytics and personalization?
Prerendering can affect analytics and personalization.
For client-side JavaScript, is recommended to delay these until the prerender is activated (for example by clicking on the link). Some solutions (like Google Analytics) already do this automatically, see Impact on Analytics. Additionally, cross-origin iframes are not loaded until activation which can further avoid issues here.
Speculating with the default
moderateeagerness decreases the risk that the prerendered page will not be visited by the user and therefore will avoid any side effects of loading such a link in advance. In contrast,eagerspeculation increases the risk that prerendered pages may not be loaded. Alternatively, the plugin offers to only speculate on mouse/pointer down (conservative) which reduces the risk even further and is an option for sites which are concerned about this, at the cost of having less of a lead time and so less of a performance gain.A prerendered page is linked to the page that prerenders it, so personalisation may already be known by this point and changes (e.g. browsing other products, or logging in/out) often require a new page load, and hence a new prerender, which will then take these into account. But it definitely is something to be aware of and test! Prerendered pages can be canceled by removing the speculation rules
<script>element from the page using standard JavaScript DOM APIs should this be needed when state changes without a new page load.- Where can I submit my plugin feedback?
Feedback is encouraged and much appreciated, especially since this plugin may contain future WordPress core features. If you have suggestions or requests for new features, you can submit them as an issue in the WordPress Performance Team’s GitHub repository. If you need help with troubleshooting or have a question about the plugin, please create a new topic on our support forum.
- Where can I report security bugs?
The Performance team and WordPress community take security bugs seriously. We appreciate your efforts to responsibly disclose your findings, and will make every effort to acknowledge your contributions.
To report a security issue, please visit the WordPress HackerOne program.
- How can I contribute to the plugin?
Contributions are always welcome! Learn more about how to get involved in the Core Performance Team Handbook.
sandywp / also on the shelf
Try another plugin
Shortcoder — Create Shortcodes for Anything
4.9 · 100K+ installs
Create custom "Shortcodes" easily for HTML, JavaScript, CSS code snippets and use the shortcodes within posts, pages & widgets
4.7 · 70K+ installs
Async Javascript lets you add 'async' or 'defer' attribute to scripts to exclude to help increase the performance of your…
4.4 · 30K+ installs
This plugin allows Admin users to individually add HTML, custom CSS, Classes and JavaScript directly to Post, Pages or any other…
Spin up a real WordPress site in seconds.
Test plugins, build a demo, hand a client a link — then squash it and start again. No local setup, no Docker.