Make WordPress Core

Opened 6 months ago

Closed 3 months ago

Last modified 2 months ago

#62503 closed feature request (fixed)

Add speculative loading support

Reported by: flixos90's profile flixos90 Owned by: flixos90's profile flixos90
Milestone: 6.8 Priority: high
Severity: normal Version:
Component: General Keywords: has-patch has-unit-tests has-dev-note
Focuses: performance Cc:

Description

With the Speculative Loading plugin being successfully used on over 40,000 WordPress sites today, this ticket is about introducing the feature in WordPress Core.

As outlined in the speculative loading announcement post, speculative loading using the Speculation Rules API “can lead to near-instant page load times”. As such, it is a crucial feature in improving load time performance and (in terms of performance metrics) LCP. Please refer to the post for additional context on what the feature does and how it works. Feel free to review the Chrome documentation about the Speculation Rules API as well.

There are several signals that indicate that the feature is ready for WordPress Core:

  • The Speculative Loading plugin has amassed 40,000+ active installs and has been used for over 6 months without major issues, while receiving exclusively 5-star ratings.
  • Based on data queried from HTTP Archive and CrUX datasets over all 6+ months since the plugin launched, the sites that enabled speculative loading improved their LCP passing rate by ~1.9% at the median which, while it may seem a small number, is a huge boost for one specific feature, considering that 100s of sites with various performance implications contribute to the data.
  • Based on Chrome stats on Speculation Rules API usage, speculative loading is already used on over 8% of Chrome page loads.
  • Cloudflare has enabled speculative loading at large scale, providing assurance that even at a large scale like WordPress Core’s the feature would function without issues and lead to great results. In the linked post, they share data that their enabling of the feature led to a “reduction in LCP of 45% on successful prefetches”.
  • Based on data from a joint experiment between Chrome and Shopify, conservative prefetch on Shopify sites gave a 50-60 ms P75 LCP improvement for successful prefetches depending on the platform (for an overall 30-50 ms P75 LCP improvement across the entire origins).

The proposed approach for implementing speculative loading in WordPress Core is to port over most of the code from the Speculative Loading plugin, with some key differences:

  • There should not be any options or UI controls to customize the behavior of the feature. Instead a filter should be introduced for that purpose.
  • The default behavior should “prefetch” URLs instead of “prerender” them, and the eagerness should be “conservative” instead of “moderate”. Basically we would be starting with the safest possible default, which should still give reasonable performance wins per the data above.
    • The plugin would continue to use the more performant yet riskier configuration of “prerender” with “moderate” eagerness, to further assess the implications of that configuration in the long term.
    • Once speculative loading would be merged into Core, the plugin would be modified to rely on Core’s implementation, but alter the default Core configuration as outlined.
  • Rather than explicitly defining “prefetch” and “conservative” as the default values for the filter, a custom value “auto” should be used for the default, with the value signifying that WordPress Core makes the decision on how to speculatively load URLs. This will allow us to refine the default behavior for those sites in the future to achieve even bigger performance wins, e.g. if support of certain speculative loading behaviors across WordPress plugins and/or the web as a whole improves or additional research data suggests a better default.

The differences were informed by the plugin usage as well as the aforementioned Cloudflare’s large-scale enabling of speculative loading. They have rolled out conservative prefetching for now, but anticipate being able to iterate on it in the future.

Change History (33)

This ticket was mentioned in PR #7860 on WordPress/wordpress-develop by @flixos90.


6 months ago
#1

  • Keywords has-patch has-unit-tests added; needs-patch needs-unit-tests removed

This PR adds speculative loading support to WordPress Core, as outlined in the Trac ticket:

  • Introduce function wp_get_speculation_rules_configuration() to get the current speculation rules configuration (consisting of "mode" and "eagerness").
    • The default values for mode and eagerness are auto, which later is evaluated into whatever the current Core default is. For the initial implementation at least, that default is to "prefetch" with "conservative" eagerness.
    • A new filter wp_speculation_rules_configuration can be used to override the behavior, either to change it to something more eager, or to hard-code it to the current default to force-control it, even if Core's default should change in the future.
  • Introduce function wp_get_speculation_rules() to compute the full data for speculation Rules JSON output, based on the given configuration (return value from wp_get_speculation_rules_configuration()).
    • By default, the configuration will lead to speculative loading of all frontend URLs, while excluding patterns like /wp-admin/*, /wp-login.php, etc which should never be speculatively loaded.
    • A new filter wp_speculation_rules_href_exclude_paths can be used to add further URL patterns to exclude, relevant for plugins that may want to customize this. This filter receives the mode (prefetch or prerender) as context, which thus allows to add exclusions depending on which mode is currently used.
    • While the filter can be used to add exclusions, it cannot remove any of the default exclusions. This is because they are simply not safe to prefetch / prerender because of their dynamic nature.
    • The default configuration also excludes prefetching links that use a no-prefetch class on their anchor, as well as excludes prerendering links that use a no-prerender class.
  • Introduce function wp_print_speculation_rules() which is hooked into wp_footer to print the default speculation rules JSON.

Trac ticket: https://core.trac.wordpress.org/ticket/62503

#2 @adamsilverstein
6 months ago

Thanks for opening this ticket @flixos90!

Some additional data from usage of the the Speculative Loading plugin collected from CrUX/httparchive is available in this colab. The data shows improvements across LCP, INP and CLS scores when the plugin is installed, and leads to approximately 6% of navigations getting "prerendered".

Last edited 6 months ago by adamsilverstein (previous) (diff)

#3 follow-up: @westonruter
6 months ago

In an upcoming version of Chromium, page responses with response that disable caching headers will no longer be bypassed for prefetch. I believe this may be a critical point to address as part of any core merge and as part of the Speculative Loading plugin. I've filed more details in the Performance repo: https://github.com/WordPress/performance/issues/1709

#4 in reply to: ↑ 3 @westonruter
5 months ago

Replying to westonruter:

In an upcoming version of Chromium, page responses with response that disable caching headers will no longer be bypassed for prefetch. I believe this may be a critical point to address as part of any core merge and as part of the Speculative Loading plugin. I've filed more details in the Performance repo: https://github.com/WordPress/performance/issues/1709

Thanks to @tunetheweb for confirming this does not impact Speculation Rules: https://github.com/WordPress/performance/issues/1709#issuecomment-2518254334

#5 @swissspidy
5 months ago

#62687 was marked as a duplicate.

#6 @flixos90
4 months ago

I have updated the PR https://github.com/WordPress/wordpress-develop/pull/7860 based on the latest additions to the Speculative Loading plugin:

  • It now excludes URLs with query parameters, as custom query parameters may be used by plugins for "action links" that modify state and therefore should not be speculatively loaded.
  • It also disables speculative loading entirely for logged-in users.

Both of these decisions strengthen the implementation, yet they can be bypassed via the filter in case the site owner is confident that those considerations aren't an issue for their site.

@flixos90 commented on PR #7860:


4 months ago
#7

@swissspidy Feedback applied!

#8 @flixos90
4 months ago

I would appreciate additional reviews on this PR, since this is a new performance feature for WordPress Core.

Any chance some of you could take a look @joemcgill @mukesh27 @desrosj @SergeyBiryukov?

This ticket was mentioned in Slack in #core by joemcgill. View the logs.


4 months ago

This ticket was mentioned in Slack in #core-performance by flixos90. View the logs.


4 months ago

This ticket was mentioned in Slack in #core by joemcgill. View the logs.


4 months ago

This ticket was mentioned in Slack in #core by joemcgill. View the logs.


4 months ago

#13 @joemcgill
4 months ago

  • Priority changed from normal to high

Bumping the priority of this to high to make it easier to track on the release milestone while we collect feedback from reviewers. Technical feedback on the actual approach is welcome on the PR, while general questions and feedback are appreciated on this ticket.

@flixos90 commented on PR #7860:


3 months ago
#14

A few updates here, most importantly related to the discussion in https://github.com/WordPress/performance/issues/1156:

#15 @desrosj
3 months ago

I chatted with @flixos90 a bit today after going through and reviewing everything. here are a few thoughts!

  • Overall, I'm convinced that this will be beneficial the web as a whole despite the API still being only a draft, and despite only Chromium-based browsers supporting the feature. The market share for those browsers is over 80%, so the majority of users would benefit. The fact that other providers (Cloudflare,a few plugins, etc.) have implemented this also speaks to the overall confidence of the API in the wild.
  • I've been trying to think through how this could be abused either intentionally or unintentionally. If site owner has code that switches the eagerness to immediate or eager, it's possible that they inadvertently cause URLs from other plugins to be prefetched or prerendered. These links could be delete user links, subscribe links, etc. Another scenario could be where a plugin filters the list of exclusions and accidentally does not perform a merge and replaces exclude rules from other plugins.
  • The feature as proposed turns off the feature for all logged in users. I think that addresses these concerns even if the second scenario causes something to perform badly (every filter has the potential to be misused), but I'm wondering if it makes sense to prevent this from being turned on for logged-in users.
  • I'm also wondering if it makes sense to support immediate as an eagerness value at all. Perhaps for the initial implementation immediate can only be supported for URL lists?

Last question I have that @flixos90 was going to look into. Can we confirm that if there are multiple instances of <script type="speculationrules">, how is that handled? Are they merged? Is the last one on the page the one that's used? The first one?

An extension of that question is how will this work if a site already has the API implemented either knowingly or unknowingly through a service provider like Cloudflare? Could we work with the bigger providers to ensure the rules provided by WordPress Core in 6.8+ are used instead of the ones that they've implemented separately?

@flixos90 commented on PR #7860:


3 months ago
#16

@desrosj Based on what we discussed and your related point in , I have updated the PR in https://github.com/WordPress/wordpress-develop/pull/7860/commits/a9c52f8f992724d18fdcaf65710ede0eb47f335e to disallow use of immediate eagerness for document-level rules.

This is in line with the plugin that has never supported immediate eagerness. It makes sense to support the value because it is part of the API and certainly can be beneficial for specific URL list rules, but for the broader document rules there is probably little to no justification for using immediate and it's a good safety net to have.

#17 @flixos90
3 months ago

  • Keywords needs-dev-note added

Thanks for the feedback and notes @desrosj.

A few additional notes and replies:

  • Iterating on what you mentioned about "action URLs", the requirements for not being logged-in, requiring use of pretty permalinks, and then excluding any URLs with query parameters should mitigate those concerns.
  • Sites without pretty permalinks or sites that are primarily used by logged-in users (like membership sites) can still override this behavior, for cases where the developer is confident their site would not suffer from such side effects (either because there are no "action URLs" present across their site or because they already added extra exclusions to prevent the issue). This obviously requires caution and should be clearly called out in the dev note. Yet despite the risk, preventing these sites from using WordPress Core's built-in Speculation Rules implementation entirely would be undesirable because developers should certainly be able to make educated decisions on their site's eligibility for that.
  • As you're saying, the immediate eagerness value would amplify that risk and it's actually fair to raise that it should not be allowed for document level speculation rules. The Speculative Loading plugin never supported that value, and I only added support for it to the Core PR because it is more comprehensive than the plugin as it also supports specific URL list speculation rules. For the latter, using immediate can certainly be valuable. But for document rules, while it is technically allowed, I agree with you that the risk of allowing it is probably greater than the benefit. As such, I just amended the PR so that immediate can only be used for specific URL list speculation rules. This also means the overall configuration for WordPress's main rule cannot use immediate eagerness either.

Regarding multiple instances of speculation rules being present from different sources:

  • The browser respects all of them, effectively merging them - whether they come from different <script type="speculationrules"> tags or HTTP headers. So overall there shouldn't be a concern one instance conflicting with another instance, unless specific speculation rules from different sources would conflict with each other. More on that below.
  • If a site was using a plugin which injects a <script type="speculationrules"> tag that configures the browser to prerender, it would effectively override WordPress Core's more conservative implementation of prefetching. That wouldn't be unexpected though if you had that plugin installed, and it would be similar to a plugin modifying WordPress Core's behavior via the provided filters.
  • For WordPress sites using Cloudflare, at a high level there shouldn't be conflicts because the implementations are both using conservative prefetch. If Cloudflare at some point decided to make their implementation more eager, then this would override / build on top of WordPress's behavior, but the end result would be the same as if WordPress didn't have speculation rules at all. Conversely, if WordPress in the future used a more eager implementation, it would override/build on top of Cloudflare's behavior.
  • The only potential caveat with Cloudflare is that it wouldn't have the same exclusion measures in place since it's of course not built for the WordPress stack. In other words, WordPress sites using Cloudflare would not be able to benefit from these exclusions and it may be advisable for these site owners to disable Cloudflare's speculation rules in favor of WordPress Core's ones that are more optimized for its own stack. But even with both present, the behavior of the site remain the same as it already was before WordPress included speculation rules, so there's effectively no problem introduced by this change.
  • Last but not least, it's worth noting that even in case of multiple instances of speculation rules the browser would still keep its overall limits on how many URLs can be prefetched or prerendered, so if that limit was 10, and two different speculation rules implementations would each lead to 8 URLs being prefetched/prerendered, it would only happen for the first 10. But that's how it works even for a single implementation.

@joemcgill commented on PR #7860:


3 months ago
#18

@felixarntz I have just a few questions on the technical approach here before diving too deep into nitpicking, as overall I think this looks pretty good.

  1. This is adding 6 helper functions in src/wp-includes/speculative-loading.php. Could some these be static methods of the class instead? E.g., the wp_is_valid_speculation_rules_* checks could be static methods. Just thinking about how with any new API we need to be careful about introducing architecture that creates a future compat burden.
  2. There's a large helper wp_get_speculation_rules() for parsing a config and returning the class as a JsonSerializable object. Had you considered passing the config directly into the constructor or a separate method of the class instead?
  3. The config that gets loaded is generated from wp_get_speculation_rules_configuration(), but if that config triggers a _doing_it_wrong it seems that this same config is loaded again from wp_get_speculation_rules_configuration() here. Can you explain why?

@flixos90 commented on PR #7860:


3 months ago
#19

@joemcgill

This is adding 6 helper functions in src/wp-includes/speculative-loading.php. Could some these be static methods of the class instead? E.g., the wp_is_valid_speculation_rules_* checks could be static methods. Just thinking about how with any new API we need to be careful about introducing architecture that creates a future compat burden.

I'm not sure about the value of doing that. I'm not opposed, but I also don't see a benefit to it. Both would be public globally available methods, so I think the future compat burden would be similar either way. I went with the functions based on how WordPress Core is largely function based. For static methods, I could see maybe the wp_is_valid_*() methods becoming static methods on WP_Speculation_Rules, but not the others because they would conceptually fit: Note that WP_Speculation_Rules is not a "wrapper" class for the entire feature, but rather a class that represents a set of specific speculation rules. More like e.g. WP_Post represents a post but is not an entry point to all post related functionality.

There's a large helper wp_get_speculation_rules() for parsing a config and returning the class as a JsonSerializable object. Had you considered passing the config directly into the constructor or a separate method of the class instead?

This relates to my above reply: The WP_Speculation_Rules class represents a set of speculation rules. It's built agnostic to any specific rules used by WordPress Core and could be instantiated several times in principle. wp_get_speculation_rules() on the other hand is for the specific speculation rules configuration that WordPress Core will use by default, that's why I don't think it would be suitable to be included in the class.

The config that gets loaded is generated from wp_get_speculation_rules_configuration(), but if that config triggers a _doing_it_wrong it seems that this same config is loaded again from wp_get_speculation_rules_configuration() here. Can you explain why?

This is present because anyone could call the wp_get_speculation_rules() and pass anything they'd like. So it's not relevant for how Core uses the function, but we need to validate that someone else doesn't pass something into it that's not supported. FWIW this function is marked private and should only be used by Core, but it's technically still publicly available. That's why this validation is present there too.

This ticket was mentioned in Slack in #core-performance by flixos90. View the logs.


3 months ago

@joemcgill commented on PR #7860:


3 months ago
#21

Thanks for explaining your thinking, @felixarntz, particularly conceptually how you see the WP_Speculation_Rules class working.

For now, my main criticism is about how the wp_get_speculation_rules() function is designed. Currently, it looks like this function can accept a configuration and return a WP_Speculation_Rules object. In core, this is only being used to load the default configuration from wp_get_speculation_rules_configuration(). As you mentioned:

This is present because anyone could call the wp_get_speculation_rules() and pass anything they'd like. So it's not relevant for how Core uses the function, but we need to validate that someone else doesn't pass something into it that's not supported.

Is there a use case you have in mind where someone would want to use this function to generate a WP_Speculation_Rules object manually? If not, then I don't see the need to accept a configuration at all, and instead just use the config from Core internally. If there is a valid reason, then it seems undesirable that if I were to pass an invalid config that I would get Core's default config loaded in it's place.

I do think that the validation helpers conceptually fit better as methods on the class, as they are all referenced within the add_rule() method as well. In Core's usage, it seems redundant to validate the config before loading the rule, and also during execution of the add_rule() method. You could have a single static WP_Speculation_Rules::is_valid() method that accepts a config and uses private methods of the class to test the mode, source, and eagerness properties of the config to reduce the public footprint of the feature.

In fact, you could even allow a config to be passed to the constructor of the class, which would first validate the config before adding the rule (or rules) to the class, in which case wp_get_speculation_rules() could be simplified to something like this (pseudocode):

function wp_get_speculation_rules() {
  $config = wp_get_speculation_rules_configuration();

  // Include any required logic we don't want to be filterable here.

  $speculation_rules = new WP_Speculation_Rules( $config );
  
  if ( $speculation_rules->is_valid() ) {
    do_action( 'wp_load_speculation_rules', $speculation_rules );

    return $speculation_rules;
  }

  return false;
}

@flixos90 commented on PR #7860:


3 months ago
#22

@joemcgill

Is there a use case you have in mind where someone would want to use this function to generate a WP_Speculation_Rules object manually? If not, then I don't see the need to accept a configuration at all, and instead just use the config from Core internally. If there is a valid reason, then it seems undesirable that if I were to pass an invalid config that I would get Core's default config loaded in it's place.

That's fair. I did it that way for better separation of concerns and making wp_get_speculation_rules() easier to test, since you can just provide an input and run assertions on the output. But we can also achieve that by filtering the configuration, so I'm happy to update this accordingly. That way it doesn't expose an interface for something that no external developer should be doing in the first place.

I do think that the validation helpers conceptually fit better as methods on the class, as they are all referenced within the add_rule() method as well. In Core's usage, it seems redundant to validate the config before loading the rule, and also during execution of the add_rule() method. You could have a single static WP_Speculation_Rules::is_valid() method that accepts a config and uses private methods of the class to test the mode, source, and eagerness properties of the config to reduce the public footprint of the feature.

In fact, you could even allow a config to be passed to the constructor of the class

I think this mixes up multiple concerns and makes the code too messy. The concepts of "speculation rules" and "speculation rules configuration" are separate concepts:

  • Speculation rules are in line with the browser API's definition. A WordPress site can have multiple speculation rules, via the wp_load_speculation_rules action. Though by default, there will only be a single rule.
  • The speculation rules configuration concept was "invented" purely for WordPress Core's implementation, to simplify control over the default behavior for developers. The most important pieces of configuration here are the mode (whether to prefetch or prerender) and the eagerness. This could be achieved by simply modifying the default rule, but it would be unnecessarily complex because of the very flexible and verbose format the speculation rules syntax of the browser API uses. So the speculation rules configuration controls the one speculation rule that WordPress Core will add by default.

For this distinction, I think intertwining the WP_Speculation_Rules class with the wp_get_speculation_rules_configuration() function would not be the right approach.

@flixos90 commented on PR #7860:


3 months ago
#23

@joemcgill

Is there a use case you have in mind where someone would want to use this function to generate a WP_Speculation_Rules object manually? If not, then I don't see the need to accept a configuration at all, and instead just use the config from Core internally. If there is a valid reason, then it seems undesirable that if I were to pass an invalid config that I would get Core's default config loaded in it's place.

That's fair. I did it that way for better separation of concerns and making wp_get_speculation_rules() easier to test, since you can just provide an input and run assertions on the output. But we can also achieve that by filtering the configuration, so I'm happy to update this accordingly. That way it doesn't expose an interface for something that no external developer should be doing in the first place.

I do think that the validation helpers conceptually fit better as methods on the class, as they are all referenced within the add_rule() method as well. In Core's usage, it seems redundant to validate the config before loading the rule, and also during execution of the add_rule() method. You could have a single static WP_Speculation_Rules::is_valid() method that accepts a config and uses private methods of the class to test the mode, source, and eagerness properties of the config to reduce the public footprint of the feature.

In fact, you could even allow a config to be passed to the constructor of the class

I think this mixes up multiple concerns and makes the code too messy. The concepts of "speculation rules" and "speculation rules configuration" are separate concepts:

  • Speculation rules are in line with the browser API's definition. A WordPress site can have multiple speculation rules, via the wp_load_speculation_rules action. Though by default, there will only be a single rule.
  • The speculation rules configuration concept was "invented" purely for WordPress Core's implementation, to simplify control over the default behavior for developers. The most important pieces of configuration here are the mode (whether to prefetch or prerender) and the eagerness. This could be achieved by simply modifying the default rule, but it would be unnecessarily complex because of the very flexible and verbose format the speculation rules syntax of the browser API uses. So the speculation rules configuration controls the one speculation rule that WordPress Core will add by default.

For this distinction, I think intertwining the WP_Speculation_Rules class with the wp_get_speculation_rules_configuration() function would not be the right approach.

@flixos90 commented on PR #7860:


3 months ago
#24

@joemcgill Based on your feedback, I've updated the PR:

#25 @flixos90
3 months ago

  • Resolution set to fixed
  • Status changed from assigned to closed

In 59837:

General: Add speculative loading support via the Speculation Rules API.

This changeset adds support for the Speculation Rules API and configures it by default to prefetch certain links with an eagerness of conservative, leading to improved performance by starting to load URLs before the user lands on them.

The new WP_Speculation_Rules class is a container class representing the set of used speculation rules. By default, WordPress Core will only add a single speculation rule, which results in most links being prefetched conservatively.

The behavior of that main speculation rule can be altered by using the new wp_speculation_rules_configuration filter, which receives an associative array with mode and eagerness keys, or null. Both mode and eagerness have a default value of auto, which for now will result in the aforementioned behavior. The value null is used by default in certain scenarios such as when the current user is logged in. Developers can explicitly provide supported mode values (prefetch or prerender) and other supported eagerness values (conservative, moderate, or eager) to override and enforce the respective behaviors, or return null to disable speculative loading feature (either unconditionally or for certain situations). The Speculative Loading feature plugin for example, which this feature is based on, will make use of this filter to continue to use mode prerender and eagerness moderate by default. Developers can call the wp_get_speculation_rules_configuration() function to check how speculative loading is configured on the WordPress site.

Another important filter introduced is wp_speculation_rules_href_exclude_paths, which allows to expand the list of URL patterns that are excluded from being prefetched or prerendered per WordPress Core's main speculation rule configuration. Several URL patterns such /wp-admin/* (any URL within WP Admin) or /*\\?(.+) (any URL that includes query parameters) are already excluded by default. Plugins that use content that would be preferable not to prefetch or prerender can use the filter to provide corresponding URL patterns.

More advanced customization is possible by adding further speculation rules that will be loaded in addition to WordPress Core's main speculation rule. This can be achieved via the new wp_load_speculation_rules action, which receives the WP_Speculation_Rules class instance and can amend it as needed.

Props flixos90, westonruter, joemcgill, desrosj, mukesh27, tunetheweb, thelovekesh, adamsilverstein, swissspidy, domenicdenicola, jeremyroman.
Fixes #62503.

@mukesh27 commented on PR #7860:


3 months ago
#26

Hi just notice that the performance number on GHA shows some regression https://github.com/WordPress/wordpress-develop/actions/runs/13400657032

@flixos90 commented on PR #7860:


3 months ago
#27

@mukeshpanchal27 Which specific metric(s) are you referring to?

@desrosj commented on PR #7860:


3 months ago
#28

@mukeshpanchal27 Just pinging again for clarification to make sure we can ideally address this prior to Beta 1, if necessary.

@mukesh27 commented on PR #7860:


3 months ago
#29

### Single Site Default summary

<b>Homepage › Theme: twentytwentyone, Locale: en_US</b>

Metric Before After Diff abs. Diff % STD MAD
timeToFirstByte 43.85 ms 45.15 ms 1.30 ms 2.88 % 1.98 ms 1.25 ms
largestContentfulPaint 95.80 ms 101.95 ms 6.15 ms 6.03 % 3.88 ms 2.40 ms
lcpMinusTtfb 51.85 ms 56.80 ms 4.95 ms 8.71 % 2.78 ms 1.20 ms
wpBeforeTemplate 14.27 ms 14.34 ms 0.07 ms 0.52 % 1.20 ms 0.60 ms
wpTemplate 27.39 ms 28.38 ms 0.98 ms 3.45 % 1.24 ms 0.73 ms
wpTotal 41.85 ms 42.98 ms 1.13 ms 2.64 % 1.97 ms 0.96 ms
wpMemoryUsage 3.55 MB 3.62 MB 0.07 MB 1.82 % 0.00 MB 0.00 MB
wpDbQueries 27 27 0 0.00 % 0 0
wpExtObjCache no no

<b>Homepage › Theme: twentytwentyone, Locale: de_DE</b>

Metric Before After Diff abs. Diff % STD MAD
timeToFirstByte 44.95 ms 46.80 ms 1.85 ms 3.95 % 2.46 ms 1.65 ms
largestContentfulPaint 96.95 ms 102.50 ms 5.55 ms 5.41 % 4.68 ms 2.10 ms
lcpMinusTtfb 52.15 ms 56.55 ms 4.40 ms 7.78 % 3.31 ms 1.15 ms
wpBeforeTemplate 14.54 ms 14.97 ms 0.43 ms 2.87 % 1.70 ms 0.82 ms
wpTemplate 27.59 ms 28.57 ms 0.99 ms 3.46 % 1.07 ms 0.66 ms
wpTotal 42.33 ms 43.51 ms 1.18 ms 2.71 % 2.32 ms 1.36 ms
wpMemoryUsage 3.76 MB 3.79 MB 0.03 MB 0.87 % 0.17 MB 0.17 MB
wpDbQueries 27 27 0 0.00 % 0 0
wpExtObjCache no no

The classic theme shows some regression in LCP, LCP - TTFB and wp-template per the GHA - https://github.com/WordPress/wordpress-develop/actions/runs/13400657032

#30 @flixos90
3 months ago

In 59881:

General: Allow speculative loading opt-out CSS classes to be applied on parent element, e.g. at the block level.

Follow-up to [59837].

Props flixos90, westonruter.
Fixes #63032.
See #62503.

This ticket was mentioned in Slack in #core by desrosj. View the logs.


2 months ago

#32 @flixos90
2 months ago

I shared the dev note draft on Slack the other day for review already, but sharing here for additional visibility: https://docs.google.com/document/d/1aby5hjvV7tODd7bPZWuiRtUsG1ZxeGChuzy0Ysd62zk/edit

#33 @flixos90
2 months ago

  • Keywords has-dev-note added; needs-dev-note removed
Note: See TracTickets for help on using tickets.