Skip to content
This repository has been archived by the owner on Jul 28, 2023. It is now read-only.

Limit the hydration to block when client-side navigations are deactivated #124

Merged
merged 32 commits into from
Dec 23, 2022

Conversation

luisherranz
Copy link
Member

@luisherranz luisherranz commented Dec 20, 2022

What

This PR will limit the hydration so it only happens in the interactive blocks.

Fixes #93.

Why

To avoid the cost of the Directives Hydration when it's strictly not necessary. Full explanation in #93.

How

It keeps using the same meta tag mechanism to know if client-side navigations are enabled or not. If they are not, instead of doing the Directives Hydration, it looks for the interactive blocks and hydrates only those. Interactive blocks opt-in using a supports.interactivity property in their block.json and they are marked with a wp-island attribute in the HTML.

Tasks

  • Add a block example
  • Add wp-island attribute to blocks with supports.interactivity
  • Limit the hydration to the blocks with the wp-island attribute
  • Add wp-ignore attribute
  • Add inner blocks to the blocks
  • Stop the hydration in the wp-ignore nodes
  • Add support for interactive block parents (as explained in Limit the hydration of the Directives Hydration when the site doesn't support client-side navigations #93)
  • Don't stop the hydration for interactive block parents
  • Fix syntax (switch from prettier-php to phpcs)
  • Don't hydrate interactive blocks that are inside interactive block parents twice
  • Support hydration of interactive blocks that are also inner blocks
  • Add e2e tests
  • Don't add wp-island and wp-ignore when client-side navigations are enabled
  • Don't stop in wp-ignore when client-side navigations are enabled

Additional comments

  • I've refactored the admin page because it was not saving the setting, I don't know why.
  • I've fixed a problem in the deepsignal code, which was broken in the main branch.

It's still not working, at least in my local environment, but at least
I didn't change it.
@SantosGuillamot
Copy link
Contributor

Thanks for opening the Pull Request!

Something I was wondering about: Would it make sense, and would it be possible, to automatically detect if a block is using directives and add the wp-interactive-block attribute even if the block developer didn't add the supports.interactivity property in the block.json? Now that we are planning to use the WP_HTML_Tag_Processor, it seems feasible to me, but I am not sure if it would be safe or if it even makes sense. Any thoughts?

Btw, it could be something to do in the future and it may be out of the scope of this PR.

@luisherranz
Copy link
Member Author

automatically detect if a block is using directives and add the wp-interactive-block attribute

Yes, it would be possible 🙂

What is not possible is to differentiate between an "isolated" and a "parent" block. But maybe we could do the opposite and treat every interactive block as a parent block unless it specifies that it is isolated? That way it'd be safer to automatically detect the directives.

@SantosGuillamot
Copy link
Contributor

I've just watched again the video you shared in the issue, and you mentioned it. I knew I had heard the idea somewhere 😄

But maybe we could do the opposite and treat every interactive block as a parent block unless it specifies that it is isolated?

Maybe not every interactive block but the ones including directives that could imply it needs inter-block communication like wp-context, error-boundaries, etc.? As a block developer, I believe I would prefer to use the block.json to opt-out and not having to include a property for each interactive block I create. It could also help for plugins modifying the markup of a specific block to add some directives and not have to modify the block.json as well.

@luisherranz
Copy link
Member Author

the ones including directives that could imply it needs inter-block communication like wp-context, error-boundaries, etc.?

Yeah, good point. That would require declaring it somehow on the directive declaration, but directive declarations will be used way less often so we can push that complexity there 🙂

It could also help for plugins modifying the markup of a specific block to add some directives and not have to modify the block.json as well.

True!


Let's do that then, but in a subsequent PR.

@luisherranz luisherranz changed the title WIP: Limit the hydration to block when client-side transitions are deactivated Limit the hydration to block when client-side transitions are deactivated Dec 22, 2022
@luisherranz
Copy link
Member Author

luisherranz commented Dec 22, 2022

This should be ready for review.

https://www.loom.com/share/78003554808d492b819794170e95f38a
https://excalidraw.com/#json=yPz4d84xWWLZR-KqTQ0_K,-FjTu31WIkjU4HSTDfh5jQ

Some notes:

@luisherranz luisherranz marked this pull request as ready for review December 22, 2022 17:42
@luisherranz
Copy link
Member Author

By the way, once this is merged, I want to add it to #103 to compare the querySelectorAll with createTreeWalker to see if what Manu from Qwik said in this tweet is true in our use case as well.

This is already done with createTreeWalker() which we found even faster than doing a querySelectAll()

@SantosGuillamot
Copy link
Contributor

SantosGuillamot commented Dec 23, 2022

I started taking a look at the PR. It looks great! I have a couple of comments so far:

  • I was testing the blocks, as you do in the video, and it seems that when it is isolated, it only adds the wp-ignore attribute to the first children of the same block. Maybe we have to iterate somehow here? For example, adding the following custom HTML in an isolated block doesn't seem to work as expected because only the paragraph gets the attribute:
<p>Isolated block</p>
<div><wp-show when="state.dontShow">hide me</wp-show></div>

@luisherranz
Copy link
Member Author

it only adds the wp-ignore attribute to the first children of the same block

Yes, the requirement for blocks to have a single wrapper node extends to inner blocks as well. Maybe the Custom HTML block should have a default wrapper: <div class="wp-block-custom-html">...</div>.

But maybe something can be done with the new capabilities of the WP_HTML_Tag_Processor to overcome this limitation.

Regarding the potential issue with querySelectorAll returning the children before the parent, it seems the method returns the NodeList in document order

Wonderful. Thanks for checking it out, Mario!

wp-directives.php Outdated Show resolved Hide resolved
Copy link
Contributor

@SantosGuillamot SantosGuillamot left a comment

Choose a reason for hiding this comment

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

Yes, the requirement for blocks to have a single wrapper node extends to inner blocks as well. Maybe the Custom HTML block should have a default wrapper.

Okay, I didn't remember that part. Then everything looks great to me 🙂 Although it would be great if someone else can double check the code.

Comment on lines +131 to +137
function wp_directives_get_client_side_transitions() {
static $client_side_transitions = null;
if ( is_null( $client_side_transitions ) ) {
$client_side_transitions = apply_filters( 'client_side_transitions', false );
}
return $client_side_transitions;
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we here just call the function that gets the options instead of creating a new filter? get_option() by default uses filter and return false in case it does not exist.

Something like

$directive_plugins_settings = get_option('wp_directives_plugin_settings');
is_array($directive_plugins_settings) return $directive_plugins_settings['client_side_transitions'];
return $false;

Copy link
Member Author

Choose a reason for hiding this comment

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

It's very unlikely that we will start storing that option in a plugin's setting. It will likely be an experimental feature that will need to be turned on using the filter, so I'd rather keep it as it is 🙂

@luisherranz
Copy link
Member Author

Merging now so we can continue. If there's something broken, we'll fix it later 🙂

@luisherranz luisherranz merged commit 168d09a into main-wp-directives-plugin Dec 23, 2022
@luisherranz luisherranz deleted the limit-hydration branch December 23, 2022 11:03
@SantosGuillamot
Copy link
Contributor

Btw, should we open a new issue to automate this with the HTML_Tag_Processor? Or is there a better place to keep track of that?

@luisherranz
Copy link
Member Author

Done!

@luisherranz luisherranz changed the title Limit the hydration to block when client-side transitions are deactivated Limit the hydration to block when client-side navigations are deactivated Jan 30, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Limit the hydration of the Directives Hydration when the site doesn't support client-side navigations
3 participants