Make your site’s pages instant in 1 minute and improve your conversion rate by 1%.
ℹ️ Info is on the website.
Changes of this fork:
🚀 Added prerender
for Blink based browsers, which improves performance even more than prefetch
🧪 For Chrome only (mobile/desktop): this fork implements the PrerenderV2 speculationrules
script tag.
✨ Support for Safari, where only preload
is supported at the moment *
⏱️ Sets the prefetch
fetch priority to high
on click/touch (recently added by the original instant.page too)
The new flow is as follows:
- On desktop, hover:
prefetch
(preload
in Safari) afterHOVER_DELAY
ms (65 ms by default, can be set by addingdata-instant-intensity
to the body) - On desktop, click:
prerender
+speculationrules prerender
- On mobile, hover & click:
prerender
+speculationrules prerender
(since hover is most likely a click on mobile) - On mobile, if network is slower than 4G (LTE) or
Save-Data
is enabled, we cancel previous fetches when a new link is hovered
When using this fork, you need to be careful since PrerenderV2 uses a <script>
tag to add the rules to the document; here's an article on how to deal with it.
In general, you should avoid prefetching/preloading/prerendering for SEO bots, see this analysis and the NextJS PR.
See this and this document for helpful tips on what not to prefetch and prerender. You should exclude:
- Logout URLs
- "Switch language" URLs
- "Add to cart" URLs
- Login flow pages where the server (not JavaScript) causes an SMS to be sent
- Pages where fetching them causes server-side consumption of a user's allowance (e.g., X free articles per month)
- A URL to a page that causes server-side ad conversion tracking
- Large resources (e.g. zip files, mp4, ...)
cache-control
(including no-store
) header for prefetch/prerender and generally caches prefetched pages for ~5 minutes. This might change in the future.
Maybe interesting: Recently-Logged-In technique.
Add data-no-instant
to the <a>
tag.
It is recommended to use POST
requests to make state changes (e.g. using <form>
submits) instead of a regular GET
navigation.
As alternative, you can check the request for the Sec-Purpose
HTTP header, which will contain prefetch
.
See this article from the Chrome DevRels Team.
A quick note for testing: Switching tabs currently cancels any prerenders, keep this in mind while debugging.
In older Chromes (< 116), prefetch and prerender did not use the same in-flight request, so they created two separate requests.
Navigational requests will re-use the in-flight request or request the remaining bytes of a request.
- Prerender/prefetch is disabled if the user has OS-level data-saver or battery-saver turned on, or if the user has "preload pages" turned off in chrome://settings
- PrerenderV2 consumes 30 - 100 MiB per prerendered page
- For background tabs, PrerenderV2 keeps prerendered pages in memory for up to 180 seconds
- Maximum of 10 prerenders are allowed at once (source), removing the
speculationrule
removes the prerendered process and frees up a slot in the 10-prerender limit - In older Chromes (< 117), prerendering is disabled when Chrome uses over 10% of the total RAM available of the device (source)
- PrerenderV2 is possibly disabled on Android devices with less than 1.7 GB of memory
Preloads in Safari are sent using as=fetch
, which makes them ineligible for navigational requests (in other words: when a user clicks on the link, it won't re-use the preload request). However, the requests can still be used to e.g. prime CDN cache.
With Node, run:
node test/app.js
And access http://127.0.0.1:8000/. Or specify another port with an argument after the filename.
To minify instantpage.js into dist/instantpage.min.js install terser globally (npm i terser -g
) then run npm run minify
.