Skip to content

Conversation

@b1ink0
Copy link
Contributor

@b1ink0 b1ink0 commented Aug 21, 2025

Summary

Fixes #2124

Relevant technical choices

This PR adds a warning notice when users try to enable speculative loading for logged-in users without having a persistent object cache set up. The warning shows up right away when clicked on the "Administrators and logged-out visitors" or "Any user" options.

Demo2.mp4

@b1ink0 b1ink0 added this to the speculation-rules n.e.x.t milestone Aug 21, 2025
@b1ink0 b1ink0 requested a review from westonruter August 21, 2025 19:29
@b1ink0 b1ink0 added [Type] Enhancement A suggestion for improvement of an existing feature [Plugin] Speculative Loading Issues for the Speculative Loading plugin (formerly Speculation Rules) labels Aug 21, 2025
@codecov
Copy link

codecov bot commented Aug 21, 2025

Codecov Report

❌ Patch coverage is 97.91667% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 68.74%. Comparing base (3d88f7b) to head (639bd9d).
⚠️ Report is 17 commits behind head on trunk.

Files with missing lines Patch % Lines
plugins/speculation-rules/settings.php 97.91% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##            trunk    #2144      +/-   ##
==========================================
+ Coverage   68.61%   68.74%   +0.13%     
==========================================
  Files          91       91              
  Lines        7956     7996      +40     
==========================================
+ Hits         5459     5497      +38     
- Misses       2497     2499       +2     
Flag Coverage Δ
multisite 68.74% <97.91%> (+0.13%) ⬆️
single 35.45% <91.66%> (-0.23%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@westonruter
Copy link
Member

I think the warning should be added below the radio buttons, as otherwise this causes a layout shift in the UI and makes it difficult to undo the change. Alternatively, what if the notice is always displayed but as info, and then if someone switches to the non-default option, it then becomes a warning?

),
'authentication' => array(
'description' => __( 'Only unauthenticated pages are typically served from cache. So in order to reduce load on the server, speculative loading is not enabled by default for logged-in users. If your server can handle the additional load, you can opt in to speculative loading for all logged-in users or just administrator users only. This only applies to pages on frontend; admin screens remain excluded.', 'speculation-rules' ),
'description' => __( 'Only unauthenticated pages are typically served from cache. So in order to reduce load on the server, speculative loading is not enabled by default for logged-in users. If your server can handle the additional load, you can opt in to speculative loading for all logged-in users or just administrator users only. For optimal performance when enabling authenticated user support, ensure you have a persistent object cache configured. This only applies to pages on frontend; admin screens remain excluded.', 'speculation-rules' ),
Copy link
Member

Choose a reason for hiding this comment

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

Maybe the same string from below could be used, but then pass it through strip_tags()?

Copy link
Member

Choose a reason for hiding this comment

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

Aside: It is unfortunate to have these translations strings duplicated in this file. Maybe there should be a helper function that returns a translation string for a given key which can then be used in both places.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in 6969eae.

Comment on lines 327 to 343
<script>
( function () {
const authRadios = document.querySelectorAll( '.plsr-auth-radio' );
const warningDiv = document.getElementById( 'plsr-auth-warning' );
const authenticatedOptions = <?php echo wp_json_encode( $authenticated_options ); ?>;

if ( ! authRadios.length || ! warningDiv ) {
return;
}

authRadios.forEach( function ( radio ) {
radio.addEventListener( 'change', function ( e ) {
warningDiv.hidden = ! authenticatedOptions.includes( e.target.value );
} );
} );
} )();
</script>
Copy link
Member

Choose a reason for hiding this comment

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

This should use wp_print_inline_script_tag() along with type="module". This will ensure it is compatible with CSP and the use of script modules will eliminate the need for the IIFE wrapper, since modules do not pollute the global scope.

Copy link
Member

@westonruter westonruter Aug 21, 2025

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in 33eee8e.

But this change caused the JavaScript to lose syntax highlighting.

<?php
printf(
/* translators: %s: URL to persistent object cache documentation */
esc_html__( 'Enabling speculative loading for authenticated users without a persistent object cache may significantly increase server load. Consider setting up a %s before enabling this feature for logged-in users.', 'speculation-rules' ),
Copy link
Member

Choose a reason for hiding this comment

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

This may be easier for translators, since "persistent object cache" appears inline with the sentence it is related to. For example, in some languages, "persistent object cache" would be translated differently if it is a subject or an object.

__( 'Enabling speculative loading for authenticated users without a persistent object cache may significantly increase server load. Consider setting up a <a href="%s" target="_blank">persistent object cache</a> before enabling this feature for logged-in users.', 'speculation-rules' ),

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in 33eee8e.

@westonruter
Copy link
Member

Alternatively, what if the notice is always displayed but as info, and then if someone switches to the non-default option, it then becomes a warning?

The benefit here is that it adds more visibility to the lack of a persistent object cache, which is important also for Speculative Loading generally when there is a page cache MISS.

<p>
<strong id="plsr-notice-label" <?php echo $show_warning ? '' : 'hidden'; ?>><?php esc_html_e( 'Warning: ', 'speculation-rules' ); ?></strong>
<?php
echo wp_kses(
Copy link
Contributor Author

@b1ink0 b1ink0 Aug 22, 2025

Choose a reason for hiding this comment

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

Alternatively, what if the notice is always displayed but as info, and then if someone switches to the non-default option, it then becomes a warning?

The benefit here is that it adds more visibility to the lack of a persistent object cache, which is important also for Speculative Loading generally when there is a page cache MISS.

Makes sense. I’ve now added the persistence notice as shown below:

demo1.mp4

I have added a bold Warning: text when there is a warning. Do you think the change of color in the notice is enough, or should the Warning: text be included as well? It does make the text slide.

cc: @westonruter

Copy link
Member

Choose a reason for hiding this comment

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

I think the warning text is a nice touch, but it may be over the top. The main downside I see is that it causes the text to reflow. Let's try removing.

Also, I think the warning could be placed above the description so that it doesn't get missed when the user hasn't scrolled down enough to see it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in 3ced504.

Now it looks like this:

Demo2.mp4

Copy link
Member

Choose a reason for hiding this comment

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

That looks good.

'const authRadios = document.querySelectorAll( ".plsr-auth-radio" );
const noticeDiv = document.getElementById( "plsr-auth-notice" );
const noticeLabel = document.getElementById( "plsr-notice-label" );
const authenticatedOptions = %s;
Copy link
Member

Choose a reason for hiding this comment

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

I think this can be avoided simply by checking by checking the index of the radio input. Index 0 is the first and default. Any index other than that is for an authenticated option.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in 980c484.

Comment on lines 351 to 373
$js = <<<'JS'
const authRadios = document.querySelectorAll( "input[name='plsr_speculation_rules[authentication]']" );
const noticeDiv = document.getElementById( "plsr-auth-notice" );
if ( authRadios.length && noticeDiv ) {
authRadios.forEach( function ( radio, index ) {
radio.addEventListener( "change", function ( e ) {
// Index 0 is logged_out, any other index is authenticated option.
const isAuthOption = index > 0;
if ( isAuthOption ) {
noticeDiv.classList.remove( "notice-info" );
noticeDiv.classList.add( "notice-warning" );
} else {
noticeDiv.classList.remove( "notice-warning" );
noticeDiv.classList.add( "notice-info" );
}
} );
} );
}
JS;
// 👆 This can only be indented two tabs when minimum PHP version is increased to 7.3+.
wp_print_inline_script_tag( $js, array( 'type' => 'module' ) );
Copy link
Member

@westonruter westonruter Aug 22, 2025

Choose a reason for hiding this comment

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

In PhpStorm:

Before After
Screenshot 2025-08-22 at 08 54 42 Screenshot 2025-08-22 at 09 00 40

Copy link
Member

Choose a reason for hiding this comment

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

@github-actions
Copy link

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: b1ink0 <[email protected]>
Co-authored-by: westonruter <[email protected]>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@westonruter
Copy link
Member

Capturing videos of mobile and desktop for the latest state:

Screen.Recording.2025-08-22.at.15.35.14.mov
Screen.Recording.2025-08-22.at.15.35.53.mov

Copy link
Member

@westonruter westonruter left a comment

Choose a reason for hiding this comment

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

Thank you!

@westonruter westonruter merged commit 15e51bc into WordPress:trunk Aug 22, 2025
16 checks passed
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] Enhancement A suggestion for improvement of an existing feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Speculative Loading setting for authenticated users should include warning if persistent object cache is not present

2 participants