Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issues on Cart/Checkout, add page exceptions to Speculative Loading plugin #1774

Open
masvil opened this issue Jan 5, 2025 · 9 comments
Open
Labels
[Plugin] Speculative Loading Issues for the Speculative Loading plugin (formerly Speculation Rules) [Type] Bug An existing feature is broken

Comments

@masvil
Copy link

masvil commented Jan 5, 2025

Consider adding page exceptions to Speculative Loading plugin, at least for WooCommerce's Cart and Checkout. Scenarios:

  • On Cart page, the Checkout page is prefetched or prerendered. After that, the user change the quantity for any product, then proceed to the Checkout page where the order details are outdated.
  • On Checkout page, the Cart page is prefetched or prerendered. After that, the user change the Billing/Shipping data, then go to the Cart page where the Shipping calculation is outdated.

I intentionally created this issue as Bug Report instead of Feature Request.

@masvil masvil added the [Type] Bug An existing feature is broken label Jan 5, 2025
@github-project-automation github-project-automation bot moved this to Not Started/Backlog 📆 in WP Performance 2024 Jan 5, 2025
@mukeshpanchal27 mukeshpanchal27 added the [Plugin] Speculative Loading Issues for the Speculative Loading plugin (formerly Speculation Rules) label Jan 6, 2025
@westonruter
Copy link
Member

Are you reporting this after having seen problems with the Cart and Checkout pages? If so, which plugin?

@masvil
Copy link
Author

masvil commented Jan 7, 2025

I'm reporting this after having seen problems with WooCommerce's Cart and Checkout pages. I just edited my report.

I temporarily fixed it by preventing the Speculative Loading plugin from being executed on both pages.

@westonruter
Copy link
Member

We had previously fixed issues related to WooCommerce:

The issue you're reporting here isn't preloading links which shouldn't be preloaded, but rather that the preloaded content is outdated. So this is indeed something which should be addressed.

As a workaround, which you may already be doing, the following should omit Speculation Rules from being printed on the Cart or Checkout pages:

add_action(
	'wp',
	static function () {
		if ( 
			( function_exists( 'is_cart' ) && is_cart() ) || 
			( function_exists( 'is_checkout' ) && is_checkout() ) 
		) {
			remove_action( 'wp_footer', 'plsr_print_speculation_rules' );
		}
	}
);

cc @felixarntz

@westonruter
Copy link
Member

Unfortunately, this issue is not limited to the Cart and Checkout pages. If you remove an item from the mini cart in the header, this can result in the item still showing up when going to the cart:

Screen.recording.2025-01-07.11.30.58.webm

Note in this video that hovering over the header to cause the mini cart to appear is hovering over a link that takes you to the cart. So the prefetch is happening when I first hover over the cart in the header, not when I hover over the button later in the video.

@westonruter
Copy link
Member

Therefore, I think a better approach than to disable Speculative Loading from adding the speculationrules script to the Cart and Checkout pages is to instead exclude those URLs specifically from being speculated:

add_filter(
	'plsr_speculation_rules_href_exclude_paths',
	static function ( $paths ) {
		if ( function_exists( 'wc_get_cart_url' ) ) {
			$paths[] = wp_parse_url( wc_get_cart_url(), PHP_URL_PATH );
		}
		if ( function_exists( 'wc_get_checkout_url' ) ) {
			$paths[] = wp_parse_url( wc_get_checkout_url(), PHP_URL_PATH );
		}
		return $paths;
	}
);

@masvil Please give that a try.

If that works, we may need to consider either adding such third-party integrations to the plugin, or else contribute this code to WooCommerce.

@westonruter westonruter moved this from Not Started/Backlog 📆 to Definition ✏️ in WP Performance 2024 Jan 7, 2025
@westonruter
Copy link
Member

However, @tunetheweb pointed out to me that there is another case that won't be accounted for with this.

  1. You go to Product A and add it to the cart.
  2. You go to Product B and add it to the cart, hover over a link to Product C to cause that page to prefetch/prerender, and then remove Product A from the mini cart.
  3. You then that click on the link to Product C.

At this point, if you open the mini cart you'll see Product A still present even though you removed it before.

This situation shouldn't arise as commonly as going to the Cart or Checkout pages, except if immediate eagerness mode was being used in which case it would happen even without needing to hover over the link to Product C above.

This issue would be mitigated if WooCommerce would populate the mini cart only when the page displayed via the visibilitychange event (if it the page was first loaded with document.hidden being true). This would have other benefits as well, such as if you opened X tabs for various products in the background: when you actually click to open one of these tabs, then you'd see the cart populate with the latest information. In this way, it's solving not just a Speculation Rules prefetch/prerender problem but also a background tabs problem. This appears to be straightforward to aco would also allow for product pages to be cached. In looking at the source code it seems this would be straightforward to implement, by just delaying the mini cart initialization until the visibilitychange event if the page is originally document.hidden. Currently it initializes on the window load event. Naturally this is out of scope for the Speculative Loading plugin.

@westonruter
Copy link
Member

Note also that the contents of the cart are stored in sessionStorage:

Image

And, if I understand correctly, it seems the mini cart is supposed to be updating whenever the sessionStorage changes. But that this doesn't seem to be working with Speculation Rules.

@tunetheweb
Copy link
Contributor

And, if I understand correctly, it seems the mini cart is supposed to be updating whenever the sessionStorage changes. But that this doesn't seem to be working with Speculation Rules.

SessionStorage is special for Speculation Rules:

Session storage: Window.sessionStorage can be used, but the behavior is very specific, to avoid breaking sites that expect only one page to access the tab's session storage at a time. A prerendered page therefore starts out with a clone of the tab's session storage state from when it was created. Upon activation, the prerendered page's storage clone is discarded, and the tab's main storage state is used instead. Pages that use session storage can use the prerenderingchange event to detect when this storage swap occurs.

@masvil
Copy link
Author

masvil commented Jan 8, 2025

@masvil Please give that a try.

It works perfectly, also checked on DevTools > Application > Speculation panel.

If that works, we may need to consider either adding such third-party integrations to the plugin

Pre-built third-party integrations would be fine, but I still think we should be able to manually configure exclusions/inclusions in the plugin at page and URL level to handle any situation (not just WooCommerce and other supported third-party).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Plugin] Speculative Loading Issues for the Speculative Loading plugin (formerly Speculation Rules) [Type] Bug An existing feature is broken
Projects
Status: Definition ✏️
Development

No branches or pull requests

4 participants