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] Optimization Detective: Performance Dashboard (Web Vitals) #1098

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

Conversation

swissspidy
Copy link
Member

@swissspidy swissspidy commented Mar 28, 2024

Summary

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 Issues related to the Measurement focus area [Plugin] Optimization Detective Issues for the Optimization Detective plugin labels Mar 28, 2024
swissspidy and others added 2 commits March 28, 2024 23:49
Co-authored-by: Weston Ruter <westonruter@google.com>
@@ -148,6 +155,34 @@ public static function get_json_schema(): array {
'additionalProperties' => false,
),
),
'webVitals' => array(
Copy link
Member

Choose a reason for hiding this comment

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

@westonruter and I chatted about this yesterday. Assuming that, at least for now, we won't bake this functionality directly into Optimization Detective, it would be valuable to allow expanding the schema with additional properties, which would effectively allow to send arbitrary key value pairs based on the schema definition.

That way, a dashboard and underlying functionality like this could be implemented in a standalone plugin and still function by registering the additional supported data with the Optimization Detective API.

Copy link
Member

Choose a reason for hiding this comment

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

That being said, I think it does make sense to bake this in. If anything, there could be a way to opt-out of it. Since we're already using onLCP but just not capturing the LCP metric, it makes sense that we do. And if we do that, might as well capture INP and CLS as well.

This doesn't preclude there also being a way to extend the schema with arbitrary key/value pairs for other plugins to send custom metrics.

Copy link
Member

Choose a reason for hiding this comment

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

I'd argue this shouldn't be built-in just like no other feature should be built-in, as the Optimization Detective plugin is just for the API.

It doesn't make sense to store those values if no feature is using them, so I think a separate plugin with a Web Vitals dashboard that relies on Optimization Detective to collect the data makes more sense.

Copy link
Member Author

Choose a reason for hiding this comment

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

Either approach has pros and cons, let‘s not focus on tha too much while this is still a POC. The main thing here is that the POC highlights missing pieces and extension points in the API, which is already a great outcome.

It doesn't make sense to store those values if no feature is using them, so I think a separate plugin with a Web Vitals dashboard that relies on Optimization Detective to collect the data makes more sense.

With what I said above, that means OD would need a clear API for other plugins to collect additional metrics in JS and process that data on the server. Something to think about as this POC progresses.

@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.

@swissspidy
Copy link
Member Author

Interesting idea. Depending on what storage method we settle on, this could be a useful way to do that.

Aside: For custom tables it's worth noting that some environments don't like them. They would definitely be a valid option for stats like this though. Just wanted to flag it :)

This presumes that the CWV dashboard is eventually built in a dependent plugin and not in Optimization Detective itself.

Related discussion: #1098 (comment)

We'd need to define the boundaries for data collection and storage, extension points for other plugins, etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Focus] Measurement Issues related to the Measurement focus area [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.

None yet

4 participants