Skip to content

Conversation

@ShyamGadde
Copy link
Contributor

@ShyamGadde ShyamGadde commented Nov 26, 2024

Summary

Fixes #1424

Relevant technical choices

@ShyamGadde ShyamGadde marked this pull request as ready for review November 27, 2024 14:22
@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: ShyamGadde <[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.

@ShyamGadde
Copy link
Contributor Author

Code in question:

/**
* Gets a sample URL metric.
*
* @phpstan-param array{
* url?: string,
* viewport_width?: int,
* viewport_height?: int,
* element?: ElementDataSubset,
* elements?: array<ElementDataSubset>
* } $params Params.
*
* @return OD_URL_Metric URL metric.
*/
public function get_sample_url_metric( array $params ): OD_URL_Metric {
$params = array_merge(
array(
'url' => home_url( '/' ),
'viewport_width' => 480,
'elements' => array(),
),
$params
);
if ( array_key_exists( 'element', $params ) ) {
$params['elements'][] = $params['element'];
}
return new OD_URL_Metric(
array(
'url' => home_url( '/' ),
'viewport' => array(
'width' => $params['viewport_width'],
'height' => $params['viewport_height'] ?? ceil( $params['viewport_width'] / 2 ),
),
'timestamp' => microtime( true ),
'elements' => array_map(
function ( array $element ): array {
return array_merge(
array(
'isLCP' => false,
'isLCPCandidate' => $element['isLCP'] ?? false,
'intersectionRatio' => 1,
'intersectionRect' => $this->get_sample_dom_rect(),
'boundingClientRect' => $this->get_sample_dom_rect(),
),
$element
);
},
$params['elements']
),
)
);
}

@westonruter, while working on this PR, I came across this code and had a quick question. On line 93, shouldn’t it use $params['url'] instead of home_url( '/' )? It seems like if a URL is passed in the $params argument, it doesn’t get used. Is this intentional?

Just thought I’d flag it while I noticed it—thanks!

@westonruter
Copy link
Member

You're right! That seems to be an oversight in the tests.

@westonruter westonruter added [Type] Enhancement A suggestion for improvement of an existing feature [Plugin] Optimization Detective Issues for the Optimization Detective plugin labels Nov 27, 2024
'required' => true,
'pattern' => '^[0-9a-f]{32}$',
),
'eTag' => array(
Copy link
Member

Choose a reason for hiding this comment

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

See other comment about calling this rather current_etag.

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 371e998.


const url = new URL( restApiEndpoint );
url.searchParams.set( 'slug', urlMetricSlug );
url.searchParams.set( 'eTag', currentETag );
Copy link
Member

Choose a reason for hiding this comment

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

It's a bit confusing that this is here rather than (also?) added as urlMetric.eTag (or urlMetric.etag). In the end they will need to be identical of course, so it does make sense. Just an observation. Maybe this should be called current_etag to better disambiguate?

Copy link
Contributor Author

@ShyamGadde ShyamGadde Nov 28, 2024

Choose a reason for hiding this comment

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

Renamed the arg in 371e998.

'required' => true,
'readonly' => true, // Omit from REST API.
),
'eTag' => array(
Copy link
Member

Choose a reason for hiding this comment

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

I wonder if we should make this just 'etag'. In HTTP it is "ETag", and a lower case "eTag" feels like it would maybe be something else, like an "electronic tag" or something.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Makes sense. Done in 08f8f8a.

* @todo This should also include an ETag as a parameter. See <https://github.com/WordPress/performance/issues/1466>.
*
* @param string $slug Slug (hash of normalized query vars).
* @param string $etag ETag.
Copy link
Member

Choose a reason for hiding this comment

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

Consider $current_etag instead.

*
* @param string $hmac HMAC.
* @param string $slug Slug (hash of normalized query vars).
* @param string $etag ETag.
Copy link
Member

Choose a reason for hiding this comment

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

Ditto on $current_etag.

// Now supply the readonly args which were omitted from the REST API params due to being `readonly`.
'timestamp' => microtime( true ),
'uuid' => wp_generate_uuid4(),
'eTag' => $request->get_param( 'eTag' ),
Copy link
Member

Choose a reason for hiding this comment

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

This is good. It makes sense that the ETag wouldn't be provided with the URL Metric object in the JSON body since it's not something that the client collects from the document. In this way it is similar to the uuid and url, although in theory the url and etag could be provided with in the urlMetric object even though they will just be ignored.

do_action( 'od_register_tag_visitors', $tag_visitor_registry );

$visitors = iterator_to_array( $tag_visitor_registry );
$current_etag = implode( ',', array_keys( $visitors ) );
Copy link
Member

Choose a reason for hiding this comment

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

An important point here: similar to the slug, i think the etag actually should be hashed:

Suggested change
$current_etag = implode( ',', array_keys( $visitors ) );
$current_etag = md5( implode( ',', array_keys( $visitors ) ) );

The key reason here is that when expanding the scope here to address the parent issue #1466, there will be much more data to include in the ETag. So I suggest that there be a new function created, like od_compute_current_etag() which takes $tag_visitor_registry as an argument. For now it could look like:

function od_compute_current_etag( OD_Tag_Visitor_Registry $tag_visitor_registry ) {
    $data = array(
        'tag_visitors' => array_keys( iterator_to_array( $tag_visitor_registry ) ),
    );
    return md5( serialize( $data ) );
}

Then later when working on #1466 the $data can be expanded to include things like the IDs and post_modified times for the posts in the loop, what the current queried object is, and so on.

Copy link
Contributor Author

@ShyamGadde ShyamGadde Nov 28, 2024

Choose a reason for hiding this comment

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

Done in 8fe38f7.

@westonruter
Copy link
Member

The test cases for Embed Optimizer and Image Prioritizer are not fixed yet, as I'm uncertain if the approach used in Optimization Detective's test cases is the best path forward.

Suggestions or feedback on the Optimization Detective test cases would be appreciated before proceeding.

@ShyamGadde I believe I've worked out a solution for the testing problem by introducing a filter for allowing extensions to customize the parameters that go into constructing an ETag. For #1466 this will be useful in case sites want to fine-tune what internal state of a page goes into constructing an ETag.

@westonruter
Copy link
Member

Signing off for the day.

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.

Whew! This was more involved than I expected. Great work!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Activation of plugin that registers a new tag visitor should automatically make URL Metrics stale

2 participants