WordPress / performance

Performance plugin from the WordPress Performance Group, which is a collection of standalone performance modules.
https://wordpress.org/plugins/performance-lab/
GNU General Public License v2.0
338 stars 90 forks source link

Kick off speculative preload/prerender when searching #1291

Open westonruter opened 2 weeks ago

westonruter commented 2 weeks ago

Feature Description

See https://x.com/tunetheweb/status/1800104005873655924 from @tunetheweb

tunetheweb commented 2 weeks ago

So the problem is that Speculation Rules is really only for safe, idempotent, requests (i.e. simple links that make GET requests).

Forms, by their very nature usually aren't guaranteed to be see (even if they result in GET requests that should in theory be idempotent). So currently the speculation rules API doesn't activate a prerender page even if it matches a <form>'s action URL. Which is a shame since search results, despite often being from a form, are usually safe to prerender—they are an exception to the usual rule that says forms aren't usually safe.

Now the original poster from the above tweet (Tim) gets around this with a little bit of cleverness by utilising prerender, even if he doesn't directly use that:

  1. Prerendering the search result page with JavaScript
  2. It stores both the search results page AND all the thumbnail images in the HTTP Cache.
  3. When the form is submitted, the prerendered page cannot be used because (as per above) forms are not supported by the Speculation Rules API. The prerender is wasted.😔
  4. The page is then loaded. However it first checks the HTTP Cache and finds everything it needs there because of the previous "wasted" prerendered attempt. 😀

So it's a fast load, even if not an instant one.

However, this depends on the Search Results page being cacheable (at least for a short period) so the earlier prerender isn't completely wasted and is resuable from the HTTP Cache. And in my experience a lot of WordPress sites don't make the HTML document cacheable 😔 For a prefetch or prerender that's used directly that's OK as the Speculation Rules API specifically allows non-cacheable resources to be speculation. But for an indirect usage, which is basically just prefilling the HTTP cache for you, this is not OK.

WDYT? Am I being overly pessimistic or does this mean we potentially can't enhance the plugin to do this?

westonruter commented 2 weeks ago

@tunetheweb I got instant loading working: https://github.com/WordPress/performance/pull/1297

As noted there:

It seems the key is how the form submit event is handled. If the default form submission handling is done, then the speculative prerender is not reused. However, if the submit event handler does preventDefault and then manually navigates to the URL that the search submission was going to go to anyway, then it works!

https://github.com/WordPress/performance/blob/d45eb1c9455915e1fa32aeb29da5d7b7679a9453/plugins/speculation-rules/search-form.js#L65-L72

This seems like a hacky workaround for something the browser should be doing automatically for GET form submissions.

tunetheweb commented 2 weeks ago

This seems like a hacky workaround for something the browser should be doing automatically for GET form submissions.

Agreed. Raised this: https://github.com/WICG/nav-speculation/issues/322

Also as noted in the PR I think you'll need to use history.pushState to add a history entry to navigate back. But not sure I like this overall approach anyway to be honest...

westonruter commented 2 weeks ago

Also as noted in the PR I think you'll need to use history.pushState to add a history entry to navigate back.

@tunetheweb Why would that be needed? It's not navigating via location.replace(). If you try that test page you can see the back button works just fine.

tunetheweb commented 2 weeks ago

Ah ignore me then. Been a while since I use this to update a URL! :-)