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

[Experiment] Full-page navigations using Speculation Rules #60959

Draft
wants to merge 5 commits into
base: trunk
Choose a base branch
from

Conversation

michalczaplinski
Copy link
Contributor

@michalczaplinski michalczaplinski commented Apr 22, 2024

What?

Trying to leverage the Speculation Rules API (https://make.wordpress.org/core/2024/04/09/speculative-loading-in-wordpress/#comment-46576) to do full-page navigations using the Interactivity API.

Testing Instructions

You'll need to:

  • Enable the full-page navigations experiment in Gutenberg
  • Use the Speculative Loading WP plugin (https://wordpress.org/plugins/speculation-rules/). Ideally, set it to prerender "eagerly".
  • Use an interactive block that has some state. It can just be a simple counter block.
@michalczaplinski michalczaplinski added [Type] Technical Prototype Offers a technical exploration into an idea as an example of what's possible [Feature] Interactivity API API to add frontend interactivity to blocks. labels Apr 22, 2024
Comment on lines +82 to +83
// add the listener for when the user leaves the page
window.addEventListener( 'beforeunload', storeStore );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As opposed to only updating the store when the user unloads the page, what if it is consistently updated throughout the life of the page? Imagine then if you had two windows open side-by-side. As you make changes in one window, you could then see them update in the other window. Naturally this would involve adding a storage event and not just a prerenderingchange. And performance would need to be protected against, given that sessionStorage is a synchronous API. Also, this could be annoying to a user as it could very well be that they want the state to differ between two windows (e.g. comparing flights for two different vacation options).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So nevermind 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right :)

I'm becoming more convinced that we might want to offer a separate "MPA mode" and "SPA mode" for full-page navigations.

It might even be possible to mix and match the two modes on the same site. So you can imagine that navigating around product pages in an e-commerce site uses SPA mode, but then navigating to the "about us" or "shipping rates" pages uses the MPA mode.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the client-side state is preserved in MPA mode (e.g. using some approach as in this PR), would there then need to be an SPA mode?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be tough to reliably preserve the client-side state in MPA mode. The current PR does it for the state from the store but we would need to do the same for context and getElement(). (link).

Perhaps there might be some way to expose the context in the Interactivity API and let the framework merge it upon navigation. That would need quite a bit of work though 😄 .

That said, choosing between SPA and MPA for navigation in an application is an architectural decision. So, we can't slap SPA navigation on a site that assumes it was built for MPA or vice versa. Because of this, even if preserving all client-side state (state, context & element) can be done, we would still need the user to decide between SPA mode and MPA mode.

@westonruter
Copy link
Member

To prefetch or to prerender eagerly? Note that in prefetch no JS is executed on the page as only the HTML is fetched and cached.

Beware that if you have more than 10 links on the page then those after 10 won't get prerendered, at least in Chrome's limits.

The moderate eagerness (e.g. activate on hover) I think is preferable to the eager eagerness (e.g. activated on the first 10 links on the page right away).

@michalczaplinski
Copy link
Contributor Author

To prefetch or to prerender eagerly? Note that in prefetch no JS is executed on the page as only the HTML is fetched and cached.

Right! I meant "prerender", thanks for catching this.

Beware that if you have more than 10 links on the page then those after 10 won't get prerendered, at least in Chrome's limits.

The moderate eagerness (e.g. activate on hover) I think is preferable to the eager eagerness (e.g. activated on the first 10 links on the page right away).

Totally, makes sense. I only meant that for testing this PR it's easier to crank up the eagerness so that you the pages prerender as soon as you load the initial page so you don't have to hover manually 🙂 .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Interactivity API API to add frontend interactivity to blocks. [Type] Technical Prototype Offers a technical exploration into an idea as an example of what's possible
4 participants