Skip to content

Commit

Permalink
Introduce get_element_max_intersection_ratios method to cache O(n^3) …
Browse files Browse the repository at this point in the history
…operation
  • Loading branch information
westonruter committed May 31, 2024
1 parent 8a9f725 commit 35850bd
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 18 deletions.
21 changes: 4 additions & 17 deletions plugins/image-prioritizer/class-ip-img-tag-visitor.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,28 +73,15 @@ public function __invoke( OD_HTML_Tag_Walker $walker ): bool {
}

// TODO: Also if the element isLCPCandidate it should never by lazy-loaded.
$is_visible = false;
$is_found = false;
foreach ( $this->url_metrics_group_collection as $group ) {
foreach ( $group as $url_metric ) {
foreach ( $url_metric->get_elements() as $element ) {
if ( $xpath === $element['xpath'] ) {
$is_found = true;
if ( $element['intersectionRatio'] > 0 ) {
$is_visible = true;
break 3; // TODO: O(n^3) my!
}
}
}
}
}
$element_max_intersection_ratios = $this->url_metrics_group_collection->get_element_max_intersection_ratios();

// If the element was not found, we don't know if it was visible for not, so don't do anything.
if ( ! $is_found ) {
if ( ! array_key_exists( $xpath, $element_max_intersection_ratios ) ) {
$walker->set_attribute( 'data-od-unknown-tag', true );
} else {
// Otherwise, make sure visible elements omit the loading attribute, and hidden elements include loading=lazy.
$loading = (string) $walker->get_attribute( 'loading' );
$is_visible = $element_max_intersection_ratios[ $xpath ] > 0.0;
$loading = (string) $walker->get_attribute( 'loading' );
if ( $is_visible && 'lazy' === $loading ) {
$walker->set_attribute( 'data-od-removed-loading', $loading );
$walker->remove_attribute( 'loading' );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ final class OD_URL_Metrics_Group_Collection implements Countable, IteratorAggreg
* is_every_group_populated?: bool,
* is_every_group_complete?: bool,
* get_groups_by_lcp_element?: array<string, OD_URL_Metrics_Group[]>,
* get_common_lcp_element?: ElementData|null
* get_common_lcp_element?: ElementData|null,
* get_element_max_intersection_ratios?: array<string, float>
* }
*/
private $result_cache = array();
Expand Down Expand Up @@ -370,6 +371,41 @@ public function get_common_lcp_element(): ?array {
return $result;
}

/**
* Gets the max intersection ratios of elements across all groups and their captured URL metrics.
*
* @return array<string, float> Keys are XPaths and values are the intersection ratios.
*/
public function get_element_max_intersection_ratios(): array {
if ( array_key_exists( __FUNCTION__, $this->result_cache ) ) {
return $this->result_cache[ __FUNCTION__ ];
}

$result = ( function () {
$element_max_intersection_ratios = array();

/*
* O(n^3) my! Yes. This is why the result is cached. This being said, the number of groups should be 4 (one
* more than the default number of breakpoints) and the number of URL metrics for each group should be 3
* (the default sample size). Therefore, given the number (n) of visited elements on the page this will only
* end up running n*4*3 times.
*/
foreach ( $this->groups as $group ) {
foreach ( $group as $url_metric ) {
foreach ( $url_metric->get_elements() as $element ) {
$element_max_intersection_ratios[ $element['xpath'] ] = array_key_exists( $element['xpath'], $element_max_intersection_ratios )
? max( $element_max_intersection_ratios[ $element['xpath'] ], $element['intersectionRatio'] )
: $element['intersectionRatio'];
}
}
}
return $element_max_intersection_ratios;
} )();

$this->result_cache[ __FUNCTION__ ] = $result;
return $result;
}

/**
* Gets URL metrics from all groups flattened into one list.
*
Expand Down

0 comments on commit 35850bd

Please sign in to comment.