Skip to content

Commit acedf14

Browse files
committed
Merge branch 'trunk' of https://github.com/WordPress/performance into update/od-docs
* 'trunk' of https://github.com/WordPress/performance: Bump yoast/phpunit-polyfills from 3.1.1 to 4.0.0 Bump phpstan/php-8-stubs from 0.4.9 to 0.4.10 Add ETag explainer to od_url_metric_freshness_ttl hook docs Fix format for multisite active plugins Include active plugins in URL Metric ETag data Add missing getters for OD_URL_Metric_Group_Collection props Increase default freshness TTL from 1 day to 1 week
2 parents 732e472 + 1f8265d commit acedf14

File tree

8 files changed

+129
-27
lines changed

8 files changed

+129
-27
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
"szepeviktor/phpstan-wordpress": "^1.3",
3131
"wp-coding-standards/wpcs": "^3.1",
3232
"wp-phpunit/wp-phpunit": "^6.5",
33-
"yoast/phpunit-polyfills": "^3.1",
33+
"yoast/phpunit-polyfills": "^4.0",
3434
"phpstan/php-8-stubs": "^0.4.0",
3535
"phpstan/phpstan-strict-rules": "^1.6"
3636
},

composer.lock

Lines changed: 15 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

plugins/optimization-detective/class-od-url-metric-group-collection.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,39 @@ public function get_current_etag(): string {
192192
return $this->current_etag;
193193
}
194194

195+
/**
196+
* Gets the breakpoints in max widths.
197+
*
198+
* @since n.e.x.t
199+
*
200+
* @return positive-int[] Breakpoints in max widths.
201+
*/
202+
public function get_breakpoints(): array {
203+
return $this->breakpoints;
204+
}
205+
206+
/**
207+
* Gets the sample size for URL Metrics for a given breakpoint.
208+
*
209+
* @since n.e.x.t
210+
*
211+
* @return int<1, max> Sample size for URL Metrics for a given breakpoint.
212+
*/
213+
public function get_sample_size(): int {
214+
return $this->sample_size;
215+
}
216+
217+
/**
218+
* Gets the freshness age (TTL) for a given URL Metric..
219+
*
220+
* @since n.e.x.t
221+
*
222+
* @return int<0, max> Freshness age (TTL) for a given URL Metric.
223+
*/
224+
public function get_freshness_ttl(): int {
225+
return $this->freshness_ttl;
226+
}
227+
195228
/**
196229
* Gets the first URL Metric group.
197230
*

plugins/optimization-detective/docs/hooks.md

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -124,16 +124,18 @@ add_filter( 'od_metrics_storage_lock_ttl', function ( int $ttl ): int {
124124
} );
125125
```
126126

127-
### Filter: `od_url_metric_freshness_ttl` (default: 1 day in seconds)
127+
### Filter: `od_url_metric_freshness_ttl` (default: 1 week in seconds)
128128

129-
Filters the freshness age (TTL) for a given URL Metric. The freshness TTL must be at least zero, in which it considers URL Metrics to always be stale. In practice, the value should be at least an hour. If your site content does not change frequently, you may want to increase the TTL to a week:
129+
Filters the freshness age (TTL) for a given URL Metric. The freshness TTL must be at least zero, in which it considers URL Metrics to always be stale. In practice, the value should be at least an hour. If your site content does not change frequently, you may want to increase the TTL even longer, say to a month:
130130

131131
```php
132132
add_filter( 'od_url_metric_freshness_ttl', static function (): int {
133-
return WEEK_IN_SECONDS;
133+
return MONTH_IN_SECONDS;
134134
} );
135135
```
136136

137+
Note that even if you have large freshness TTL a URL Metric can still become stale sooner; if the page state changes then this results in a change to the ETag associated with a URL Metric. This will allow new URL Metrics to be collected before the freshness TTL has transpired. See the `od_current_url_metrics_etag_data` filter to customize the ETag data.
138+
137139
During development, this can be useful to set to zero so that you don't have to wait for new URL Metrics to be requested when engineering a new optimization:
138140

139141
```php
@@ -233,10 +235,17 @@ add_filter(
233235

234236
See also [example usage](https://github.com/WordPress/performance/blob/6bb8405c5c446e3b66c2bfa3ae03ba61b188bca2/plugins/embed-optimizer/hooks.php#L128-L144) in Embed Optimizer. Note in particular the structure of the plugin’s [detect.js](https://github.com/WordPress/performance/blob/trunk/plugins/embed-optimizer/detect.js) script module, how it exports `initialize` and `finalize` functions which Optimization Detective then calls when the page loads and when the page unloads, at which time the URL Metric is constructed and sent to the server for storage. Refer also to the [TypeScript type definitions](https://github.com/WordPress/performance/blob/trunk/plugins/optimization-detective/types.ts).
235237

236-
### Filter: `od_current_url_metrics_etag_data` (default: array with `tag_visitors` key)
238+
### Filter: `od_current_url_metrics_etag_data` (default: `array<string, mixed>`)
237239

238240
Filters the data that goes into computing the current ETag for URL Metrics.
239241

240-
The ETag is a unique identifier that changes whenever the underlying data used to generate it changes. By default, the ETag calculation includes the names of registered tag visitors. This ensures that when a new Optimization Detective-dependent plugin is activated (like [Image Prioritizer](https://wordpress.org/plugins/image-prioritizer/) or [Embed Optimizer](https://wordpress.org/plugins/embed-optimizer/)), any existing URL Metrics are immediately considered stale. This happens because the newly registered tag visitors alter the ETag calculation, making it different from the stored ones.
242+
The ETag is a unique identifier that changes whenever the underlying data used to generate it changes. By default, the ETag calculation includes:
243+
244+
1. The active theme and current version (for both parent and child themes).
245+
2. The queried object ID, post type, and modified date.
246+
3. The list of registered tag visitors.
247+
4. The IDs and modified times of posts in The Loop.
248+
5. The current theme template used to render the page.
249+
6. The list of active plugins.
241250

242-
When the ETag for URL Metrics in a complete viewport group no longer matches the current environment's ETag, new URL Metrics will then begin to be collected until there are no more stored URL Metrics with the old ETag. These new URL Metrics will include data relevant to the newly activated plugins and their tag visitors.
251+
A change in ETag means that any previously-collected URL Metrics will be immediately considered stale. When the ETag for URL Metrics in a complete viewport group no longer matches the current environment's ETag, new URL Metrics will then begin to be collected until there are no more stored URL Metrics with the old ETag.

plugins/optimization-detective/storage/data.php

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ function od_get_url_metric_freshness_ttl(): int {
3131
*
3232
* @since 0.1.0
3333
*
34-
* @param int $ttl Expiration TTL in seconds. Defaults to 1 day.
34+
* @param int $ttl Expiration TTL in seconds. Defaults to 1 week.
3535
*/
36-
$freshness_ttl = (int) apply_filters( 'od_url_metric_freshness_ttl', DAY_IN_SECONDS );
36+
$freshness_ttl = (int) apply_filters( 'od_url_metric_freshness_ttl', WEEK_IN_SECONDS );
3737

3838
if ( $freshness_ttl < 0 ) {
3939
_doing_it_wrong(
@@ -201,6 +201,17 @@ function od_get_current_url_metrics_etag( OD_Tag_Visitor_Registry $tag_visitor_r
201201
$queried_object_data['type'] = $queried_object->name;
202202
}
203203

204+
$active_plugins = (array) get_option( 'active_plugins', array() );
205+
if ( is_multisite() ) {
206+
$active_plugins = array_unique(
207+
array_merge(
208+
$active_plugins,
209+
array_keys( (array) get_site_option( 'active_sitewide_plugins', array() ) )
210+
)
211+
);
212+
}
213+
sort( $active_plugins );
214+
204215
$data = array(
205216
'xpath_version' => 2, // Bump whenever a major change to the XPath format occurs so that new URL Metrics are proactively gathered.
206217
'tag_visitors' => array_keys( iterator_to_array( $tag_visitor_registry ) ),
@@ -232,6 +243,7 @@ static function ( $post ): ?array {
232243
'version' => wp_get_theme()->get( 'Version' ),
233244
),
234245
),
246+
'active_plugins' => $active_plugins,
235247
'current_template' => $current_template instanceof WP_Block_Template ? get_object_vars( $current_template ) : $current_template,
236248
);
237249

plugins/optimization-detective/tests/storage/test-data.php

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public function tear_down(): void {
3333
* @covers ::od_get_url_metric_freshness_ttl
3434
*/
3535
public function test_od_get_url_metric_freshness_ttl(): void {
36-
$this->assertSame( DAY_IN_SECONDS, od_get_url_metric_freshness_ttl() );
36+
$this->assertSame( WEEK_IN_SECONDS, od_get_url_metric_freshness_ttl() );
3737

3838
add_filter(
3939
'od_url_metric_freshness_ttl',
@@ -486,6 +486,27 @@ static function ( $link, $author_id ) {
486486
};
487487
},
488488
),
489+
490+
'plugin_activated' => array(
491+
'set_up' => function (): Closure {
492+
$this->go_to( '/' );
493+
494+
return function ( array $etag_data, Closure $get_etag ): void {
495+
$etag = $get_etag();
496+
update_option(
497+
'active_plugins',
498+
array_merge(
499+
get_option( 'active_plugins' ),
500+
array(
501+
'image-prioritizer/load.php',
502+
)
503+
)
504+
);
505+
$etag_after = $get_etag();
506+
$this->assertNotEquals( $etag, $etag_after );
507+
};
508+
},
509+
),
489510
);
490511
}
491512

@@ -498,6 +519,21 @@ static function ( $link, $author_id ) {
498519
* @covers ::od_get_current_theme_template
499520
*/
500521
public function test_od_get_current_url_metrics_etag( Closure $set_up ): void {
522+
update_option(
523+
'active_plugins',
524+
array(
525+
'optimization-detective/load.php',
526+
)
527+
);
528+
if ( is_multisite() ) {
529+
update_site_option(
530+
'active_sitewide_plugins',
531+
array(
532+
'performance-lab/load.php' => time(),
533+
)
534+
);
535+
}
536+
501537
$captured_etag_data = null;
502538
add_filter(
503539
'od_current_url_metrics_etag_data',
@@ -533,11 +569,17 @@ static function ( array $data ) use ( &$captured_etag_data ) {
533569
$etag = $get_etag();
534570
$this->assertMatchesRegularExpression( '/^[a-z0-9]{32}\z/', $etag );
535571
$this->assertIsArray( $captured_etag_data );
536-
$expected_keys = array( 'xpath_version', 'tag_visitors', 'queried_object', 'queried_posts', 'active_theme', 'current_template' );
572+
$expected_keys = array( 'xpath_version', 'tag_visitors', 'queried_object', 'queried_posts', 'active_theme', 'current_template', 'active_plugins' );
537573
foreach ( $expected_keys as $expected_key ) {
538574
$this->assertArrayHasKey( $expected_key, $captured_etag_data );
539575
}
540576
$this->assertSame( $initial_active_theme, $captured_etag_data['active_theme'] );
577+
$this->assertContains( 'optimization-detective/load.php', $captured_etag_data['active_plugins'] );
578+
if ( is_multisite() ) {
579+
$this->assertContains( 'performance-lab/load.php', $captured_etag_data['active_plugins'] );
580+
} else {
581+
$this->assertNotContains( 'performance-lab/load.php', $captured_etag_data['active_plugins'] );
582+
}
541583
$this->assertContains( 'foo', $captured_etag_data['tag_visitors'] );
542584
$this->assertContains( 'bar', $captured_etag_data['tag_visitors'] );
543585
$this->assertContains( 'baz', $captured_etag_data['tag_visitors'] );

plugins/optimization-detective/tests/test-class-od-url-metrics-group-collection.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@ public function data_provider_test_construction(): array {
111111
/**
112112
* @covers ::__construct
113113
* @covers ::get_current_etag
114+
* @covers ::get_breakpoints
115+
* @covers ::get_sample_size
116+
* @covers ::get_freshness_ttl
114117
* @covers ::create_groups
115118
* @covers ::count
116119
*
@@ -130,6 +133,9 @@ public function test_construction( array $url_metrics, string $current_etag, arr
130133
$group_collection = new OD_URL_Metric_Group_Collection( $url_metrics, $current_etag, $breakpoints, $sample_size, $freshness_ttl );
131134
$this->assertCount( count( $breakpoints ) + 1, $group_collection );
132135
$this->assertSame( $current_etag, $group_collection->get_current_etag() );
136+
$this->assertSame( $sample_size, $group_collection->get_sample_size() );
137+
$this->assertSame( $breakpoints, $group_collection->get_breakpoints() );
138+
$this->assertSame( $freshness_ttl, $group_collection->get_freshness_ttl() );
133139
}
134140

135141
/**

plugins/optimization-detective/tests/test-detection.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ public function data_provider_od_get_detection_script(): array {
9090
'storageLockTTL' => MINUTE_IN_SECONDS,
9191
'extensionModuleUrls' => array(),
9292
'cachePurgePostId' => null,
93-
'freshnessTTL' => DAY_IN_SECONDS,
93+
'freshnessTTL' => WEEK_IN_SECONDS,
9494
),
9595
'expected_standard_build' => true,
9696
),

0 commit comments

Comments
 (0)