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

[POC] Performance Dashboard (Web Vitals) #1098

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

Conversation

swissspidy
Copy link
Member

@swissspidy swissspidy commented Mar 28, 2024

Summary

See #1324

Leverage Optimization Detective to collect Core Web Vitals field data inside WordPress. See what real users are experiencing on your site, without CrUX.

Optimization Detective is uniquely positioned to also collect web vitals RUM data. This data can then be presented in the WordPress dashboard for site owners to keep an eye on their site's performance.

Demo

The proof of concept looks as follows:

Dedicated dashboard page:

Screenshot 2024-03-28 at 17 28 25

Admin dashboard widget:

Screenshot 2024-04-10 at 10 16 17

Advantages

  • Works for smaller sites without CrUX field data
  • You don't have to wait for CrUX data to be available
  • Get data from other browsers
  • No external data source required
  • Tightly integrated into WordPress

Main difference to Optimization Detective today is that ideally CWV

Potential

In the future we could:

  • Provide WP-specific call-to-actions, e.g. to fix the offending LCP image in the block editor
  • Identify plugins causing LCP/CLS/etc. issues and provide call-to-actions
  • Identify plugins causing CLS issues
  • Expose (aggregated) CWV data publicly for analysis purposes
    • Opt-in or opt-out
    • Alternatively send to some telemetry server
  • Use Long Animation Frames API to identify offenders
  • Collect Server-Timing measurements per page
  • Add insights to admin bar
  • Add insights to block editor

Related

I found an existing Core Web Vitals Monitor WordPress plugin which also does this but is somehow not maintained nor popular. We might be able to learn something from it.

See also:

Relevant technical choices

(TODO)

@swissspidy swissspidy added [Type] Enhancement A suggestion for improvement of an existing feature [Focus] Measurement [Plugin] Optimization Detective Issues for the Optimization Detective plugin labels Mar 28, 2024
@adamsilverstein
Copy link
Member

@swissspidy I like the concept, but couldn't quite get this building and running locally to test.

Can you add instructions for building and testing?

To get the build even working, I had to rename the js files for .jsx to avoid a Unexpected token: operator (<) from Terser when running npm run build:plugins, maybe I am missing a step? I tried collecting some data but never saw the dashboard load.

@swissspidy
Copy link
Member Author

That sounds odd 🤔 But since it's in very early stages, things can be a bit bumpy :)

I'll add more detailed instructions once it's more robust and less in flux.

During development, what I did is:

  • Run npm run start:plugin:optimization-detective to build the JS files

  • Add a small plugin to disable some safeguards (hat tip Weston):

<?php
/**
 * Plugin Name: Optimization Detective Debugging
 * Version: 0.1.0
 */

add_filter( 'od_url_metric_storage_lock_ttl', '__return_zero' );
add_filter( 'od_url_metric_freshness_ttl', '__return_zero' );
add_filter( 'od_url_metrics_breakpoint_sample_size', function () { return 1; } );
add_filter( 'od_can_optimize_response', '__return_true' );

add_filter(
    'register_od_url_metrics_post_type_args',
    static function( $args ) {
    
        $args['supports'][] = 'content';
        $args['public'] = true;

        return $args;
    }
);
  • In a new session, visit a few pages, move around etc. so that visibilitychange is triggered and data is collected

@westonruter
Copy link
Member

I was thinking, in order to facilitate the historical data use case, perhaps it would make sense to fire an action whenever a URL metric is stored, like so:

--- a/plugins/optimization-detective/storage/rest-api.php
+++ b/plugins/optimization-detective/storage/rest-api.php
@@ -160,6 +160,16 @@ function od_handle_rest_request( WP_REST_Request $request ) {
 		return $result;
 	}
 
+	/**
+	 * Fires when a new URL metric has been stored.
+	 *
+	 * @since n.e.x.t
+	 *
+	 * @param OD_URL_Metric   $url_metric Stored URL metric.
+	 * @param WP_REST_Request $request    REST request to store the URL metric.
+	 */
+	do_action( 'od_url_metric_stored', $url_metric, $request );
+
 	return new WP_REST_Response(
 		array(
 			'success' => true,

This could extract data from the URL metric or the storage request to then store in another location, like a custom table which is better suited for aggregating CWV metrics. This presumes that the CWV dashboard is eventually built in a dependent plugin and not in Optimization Detective itself.

@joemcgill
Copy link
Member

I just became aware of this demo and am really intrigued by the potential usefulness here. My initial thought was to agree with @felixarntz, that this probably shouldn't be a feature of the Optimization Detective plugin, but perhaps a feature in another plugin that makes use of the Optimization Detective API.

Personally, I think this is the perfect kind of feature for Performance Lab, now that it's been repositioned from a collection of modules, to a central place to inform site owners of performance optimizations that they can make and surface performance features they can install via our standalone plugins.

@swissspidy
Copy link
Member Author

I started this before we did all the refactoring with plugin dependencies etc. So yeah this can now easily be its own plugin. I plan to pick it up again at some point 👍

@joemcgill
Copy link
Member

So yeah this can now easily be its own plugin

I was suggesting that it become a feature of the Performance Lab plugin, rather than a separate plugin. One of the unfortunate side-effects of needing to unbundle the Performance Lab modules into standalone plugins (#656) is that it limits the usefulness of what is included in the main PL plugin. In initial discussions about this change, one of the ideas was to have PL be responsible for helping site owners understand the performance characteristics of their own site through the use of tools like the Server Timing headers and Site Health Checks, as well as be a central place to surface suggestions about performance features that they could install to improve their site. I think a performance dashboard like this fits directly into that vision and improve the usefulness of the main PL plugin.

@swissspidy
Copy link
Member Author

swissspidy commented Jun 28, 2024

I see. It requires Optimization Detective though as a dependency, that might make things confusing.

@swissspidy swissspidy changed the title [POC] Optimization Detective: Performance Dashboard (Web Vitals) [POC]Performance Dashboard (Web Vitals) Jul 1, 2024
@swissspidy swissspidy changed the title [POC]Performance Dashboard (Web Vitals) [POC] Performance Dashboard (Web Vitals) Jul 1, 2024
@swissspidy swissspidy added the no milestone PRs that do not have a defined milestone for release label Jul 9, 2024
@felixarntz
Copy link
Member

+1 to @joemcgill's suggestion of making this part of Performance Lab. Our self-imposed guidance when we made the split was that only features that actually perform optimizations should be their own plugins, while features around metrics, monitoring, and recommendations should be part of the Performance Lab plugin.

The Optimization Detective dependency concern by @swissspidy makes this maybe tricky, but I think we can find a solution for it (without actually making Optimization Detective a dependency for Performance Lab, which we definitely shouldn't do).

How about this:

  • The dashboard only surfaces Server-Timing based data out of the box.
  • If Optimization Detective is active, the dashboard also surfaces all the additional metrics that having Optimization Detective unlocks.
  • If Optimization Detective is not active, we display a prompt that recommends the user to install and activate that. We can definitely include some reasons why, since of course the metrics it would unlock are much more powerful than Server-Timing metrics.

@swissspidy
Copy link
Member Author

Interesting suggestion. Moving it to the proposal issue for visibility.

westonruter added a commit that referenced this pull request Aug 18, 2024
This is an iteration on top of #1098

Co-authored-by: swissspidy <[email protected]>
Comment on lines +470 to +482
// Report all available metrics whenever the page is backgrounded or unloaded.
addEventListener( 'visibilitychange', () => {
if ( document.visibilityState === 'hidden' ) {
sendData();
}
} );

// NOTE: Safari does not reliably fire the `visibilitychange` event when the
// page is being unloaded. If Safari support is needed, you should also flush
// the queue in the `pagehide` event.
addEventListener( 'pagehide', () => {
sendData();
} );
Copy link
Member

Choose a reason for hiding this comment

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

I've largely adopted this in #1373 now so that instead of sending the gathered URL metric as soon as the page has loaded and is idle, it instead sends it via navigator.sendBeacon() when the page is left. It just sends it once per page. The intention is that client-side extensions can hook in to finalize the URL metric object before it are sent, as can be seen in that PR currently for using a ResizeObserver to update the ultimate height of embeds rather than just the initial height.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
no milestone PRs that do not have a defined milestone for release [Plugin] Optimization Detective Issues for the Optimization Detective plugin [Type] Enhancement A suggestion for improvement of an existing feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants