Skip to content

Unclear purpose for tag visitors returning true or false in Optimization Detective #1342

@westonruter

Description

@westonruter

When registering a tag visitor in Optimization Detective, the callable must return a boolean. When the boolean returns true, then this is an indication that the tag was indeed "visited" or rather that the visitor is relevant to the current tag. For example:

add_action( 'od_register_tag_visitors', static function ( OD_Tag_Visitor_Registry $registry ) {
	$registry->register( 'async_images', static function ( OD_Tag_Visitor_Context $context ) {
		if ( $context->processor->get_tag() !== 'IMG' ) {
			return false;
		}
		if ( $context->processor->get_attribute( 'decoding' ) !== 'async' ) {
			$context->processor->set_attribute( 'decoding', 'async' );
		}
		return true;
	} );
} );

Clearly this visitor should return false if the current tag is not an IMG. But should it still also return false if it already has a decoding=async attribute?

In reality, when a visitor returns true this is a signal for whether or not the tag should be captured to be stored in the URL Metrics:

foreach ( $visitors as $visitor ) {
$did_visit = $visitor( $tag_visitor_context ) || $did_visit;
// Since the visitor may have traversed HTML tags, we need to make sure we go back to this tag so that
// in the next iteration any relevant tag visitors may apply, in addition to properly setting the data-od-xpath
// on this tag below.
$processor->seek( $current_tag_bookmark );
}
$processor->release_bookmark( $current_tag_bookmark );
if ( $did_visit && $needs_detection ) {
$processor->set_meta_attribute( 'xpath', $processor->get_xpath() );
}

So when a visitor returns true then this means that $did_visit will be true and if the URL Metrics for current URL are not complete (if $needs_detection is false), then the effect is that it will add the data-od-xpath attribute to the tag. What does this do? It means that when detect.js runs, it will include the element among all of the elements for which it captures metrics, including via IntersectionObserver and web-vitals.js:

const breadcrumbedElements = doc.body.querySelectorAll( '[data-od-xpath]' );

for ( const element of breadcrumbedElementsMap.keys() ) {
intersectionObserver.observe( element );
}

However, in the case above for a tag visitor that just makes sure that all img tags have decoding=async, there is no need for this tag to ever be captured in the URL metrics because the URL metrics do not impact how the applied optimization in any way. This is in contrast with what Image Prioritizer does with applying lazy-loading and fetchpriority=high, where it depends on the URL Metrics to know what optimization to perform. Embed Optimizer also depends on URL Metrics to know whether an embed should be lazy-loaded or instead should have preconnect links added. Conversely, the auto-sizes integration in #1322 doesn't depend on the URL Metrics and so at present its tag visitor could always return false.

In short, I think the explanation of what the boolean means being returned from a tag visitor. It's not whether the tag was visited, but rather whether or not the tag needs to be tracked in the URL Metrics.

It could also be possible to automatically detect whether or not a tag visitor depends on URL metrics by detecting whether or not it accessed the $context->url_metrics_group_collection. If so, then this would be a signal that indeed the tag should be tracked in the URL metrics, and the return value of the tag visitor could be eliminated entirely. However, this could be a bit too sophisticated.

Metadata

Metadata

Assignees

Labels

[Plugin] Embed OptimizerIssues for the Embed Optimizer plugin (formerly Auto Sizes)[Plugin] Enhanced Responsive ImagesIssues for the Enhanced Responsive Images plugin (formerly Auto Sizes)[Plugin] Image PrioritizerIssues for the Image Prioritizer plugin (dependent on Optimization Detective)[Plugin] Optimization DetectiveIssues for the Optimization Detective plugin[Type] EnhancementA suggestion for improvement of an existing feature

Type

No type

Projects

Status

Done 😃

Relationships

None yet

Development

No branches or pull requests

Issue actions