Skip to content

Commit

Permalink
Flesh out inline phpdoc for od_init and od_register_tag_visitors actions
Browse files Browse the repository at this point in the history
  • Loading branch information
westonruter committed Jan 9, 2025
1 parent 6340f0c commit 2892386
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 0 deletions.
16 changes: 16 additions & 0 deletions plugins/optimization-detective/helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,22 @@ function od_initialize_extensions(): void {
/**
* Fires when extensions to Optimization Detective can be loaded and initialized.
*
* This action is useful for loading extension code that depends on Optimization Detective to be running. The version
* of the plugin is passed as the sole argument so that if the required version is not present, the callback can short circuit.
*
* Example:
*
* add_action( 'od_init', function ( string $version ) {
* if ( version_compare( $version, '1.0', '<' ) ) {
* add_action( 'admin_notices', 'my_plugin_warn_optimization_plugin_outdated' );
* return;
* }
*
* // Bootstrap the Optimization Detective extension.
* require_once __DIR__ . '/functions.php';
* // ...
* } );
*
* @since 0.7.0
*
* @param string $version Optimization Detective version.
Expand Down
71 changes: 71 additions & 0 deletions plugins/optimization-detective/optimization.php
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,77 @@ function od_optimize_template_output_buffer( string $buffer ): string {
/**
* Fires to register tag visitors before walking over the document to perform optimizations.
*
* Once a page has finished rendering and the output buffer is processed, the page contents are loaded into
* an HTML Tag Processor instance. It then iterates over each tag in the document, and at each open tag it will
* invoke all registered tag visitors. A tag visitor is simply a callable (such as a regular function, closure,
* or even a class with an `__invoke` method defined). The tag visitor callback is invoked by passing an instance
* of the `OD_Tag_Visitor_Context` object which includes the following read-only properties:
*
* - `$processor` (`OD_HTML_Tag_Processor`): The processor with the cursor at the current tag.
* - `$url_metric_group_collection` (`OD_URL_Metric_Group_Collection`): The URL Metrics which may include information about the current tag to inform what optimizations the callback performs.
* - `$link_collection` (`OD_Link_Collection`): Collection of links which will be added to the `HEAD` when the page is served. This allows you to add preload links and preconnect links as needed.
*
* Note that you are free to call `next_tag()` in the callback (such as to walk over any child elements) since the
* cursor will be reset to the tag after the callback finishes.
*
* A tag visitor callback returns a boolean value. When it returns `true`, then Optimization Detective will mark the
* tag as needing to be included among the elements stored in URL Metrics. The element data includes properties such
* as intersectionRatio, intersectionRect, and boundingClientRect as well as whether it is the LCP element. If the
* current tag is not relevant for the tag visitor or if the tag visitor callback does not need to query the provided
* `OD_URL_Metric_Group_Collection` instance to apply the desired optimizations, it can just return `false`. An
* element will be tracked in URL Metrics if _any_ tag visitor callback returns `true` when visiting the tag.
*
* Here's an example tag visitor that depends on URL Metrics data:
*
* $tag_visitor_registry->register(
* 'lcp-img-fetchpriority-high',
* static function ( OD_Tag_Visitor_Context $context ): bool {
* if ( $context->processor->get_tag() !== 'IMG' ) {
* return false; // Tag is not relevant for this tag visitor.
* }
*
* // Make sure fetchpriority=high is added to LCP IMG elements.
* $common_lcp_element = $context->url_metric_group_collection->get_common_lcp_element();
* if (
* null !== $common_lcp_element
* &&
* $common_lcp_element->get_xpath() === $context->processor->get_xpath()
* ) {
* $context->processor->set_attribute( 'fetchpriority', 'high' );
* }
*
* // Must return true so that the tag is included among the elements stored in URL Metrics.
* return true;
* }
* );
*
* Please note this implementation of setting `fetchpriority=high` on the LCP `IMG` element is simplified. Please
* see the Image Prioritizer extension for a more robust implementation.
*
* Here's an example tag visitor that does not depend on any URL Metrics data:
*
* $tag_visitor_registry->register(
* 'img-decoding-async',
* static function ( OD_Tag_Visitor_Context $context ): bool {
* if ( $context->processor->get_tag() !== 'IMG' ) {
* return false; // Tag is not relevant for this tag visitor.
* }
*
* // Set the decoding attribute if it is absent.
* if ( null === $context->processor->get_attribute( 'decoding' ) ) {
* $context->processor->set_attribute( 'decoding', 'async' );
* }
*
* // There's no need to query OD_URL_Metric_Group_Collection, so this element
* // doesn't need to be tracked in URL Metrics and the callback can return false.
* return false;
* }
* );
*
* Refer to [Image Prioritizer](https://github.com/WordPress/performance/tree/trunk/plugins/image-prioritizer) and
* [Embed Optimizer](https://github.com/WordPress/performance/tree/trunk/plugins/embed-optimizer) for additional
* examples of how tag visitors are used.
*
* @since 0.3.0
*
* @param OD_Tag_Visitor_Registry $tag_visitor_registry Tag visitor registry.
Expand Down

0 comments on commit 2892386

Please sign in to comment.