Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
07730df
first commit for fetchprionty
pbearne Sep 12, 2022
9b8f5ce
Merge remote-tracking branch 'upstream/trunk' into experiment/fetchpr…
pbearne Sep 12, 2022
412ae47
added basic tests
pbearne Sep 12, 2022
5793388
Update modules/images/fetchpriority/load.php
pbearne Sep 13, 2022
4dcb016
Update modules/images/fetchpriority/load.php
pbearne Sep 13, 2022
ca092d6
Update modules/images/fetchpriority/load.php
pbearne Sep 13, 2022
8939080
code review feedback
pbearne Sep 13, 2022
280f11d
Add CODEOWNERS update for fetchpriority module.
Sep 13, 2022
5480988
Use lowercase file name for test class file.
Sep 13, 2022
ddc78b8
Fix CODEOWNERS indentation.
Sep 13, 2022
1cdf6a4
Update modules/images/fetchpriority/load.php
pbearne Sep 13, 2022
0946219
Update modules/images/fetchpriority/load.php
pbearne Sep 13, 2022
15665fb
Update modules/images/fetchpriority/load.php
pbearne Sep 13, 2022
a573ecc
Update modules/images/fetchpriority/load.php
pbearne Sep 13, 2022
6702525
Update modules/images/fetchpriority/load.php
pbearne Sep 13, 2022
2fbc825
Update modules/images/fetchpriority/load.php
pbearne Sep 13, 2022
7caf166
Update modules/images/fetchpriority/load.php
pbearne Sep 13, 2022
e6826eb
code review feedback
pbearne Sep 13, 2022
6dd14bb
added test for wp_filter_content_tags() function
pbearne Sep 14, 2022
958987e
Update tests/modules/images/fetchpriority/fetchpriority-tests.php
pbearne Sep 22, 2022
28122a2
Update tests/modules/images/fetchpriority/fetchpriority-tests.php
pbearne Sep 22, 2022
55b3b92
added test for wp_filter_content_tags() function
pbearne Sep 28, 2022
1201df6
Merge remote-tracking branch 'origin/experiment/fetchpriority' into e…
pbearne Sep 28, 2022
fb18628
Merge branch 'trunk' into experiment/fetchpriority
pbearne Sep 28, 2022
ec41481
Merge branch 'trunk' into experiment/fetchpriority
adamsilverstein Oct 28, 2022
bf515a2
Improve tests with multiple attachments, in_the_loop true
adamsilverstein Oct 28, 2022
4a4c237
Mock is_main_query
adamsilverstein Oct 28, 2022
8f42c02
Update modules/images/fetchpriority/load.php
adamsilverstein Nov 14, 2022
aa9f635
Update modules/images/fetchpriority/load.php
adamsilverstein Nov 14, 2022
0e3061c
test_fetchpriority… expect exactly one
adamsilverstein Nov 14, 2022
0494e6d
Fetchpriority relies on lazy loading logic
adamsilverstein Nov 14, 2022
ae0eb60
Add test_fetchpriority_img_tag_with_lazyload_disabled
adamsilverstein Nov 14, 2022
a7392d2
Combine tests
adamsilverstein Nov 14, 2022
0a4fe58
Correct assertion typo
adamsilverstein Nov 14, 2022
a709c91
Merge branch 'trunk' into experiment/fetchpriority
Nov 22, 2022
66d2a0d
SImplify fetchpriority module description.
felixarntz Nov 22, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@
/tests/modules/images/dominant-color @pbearne @spacedmonkey
/tests/testdata/modules/images/dominant-color @pbearne @spacedmonkey

# Module: Fetchpriority
/modules/images/fetchpriority @pbearne @adamsilverstein
/tests/modules/images/fetchpriority @pbearne @adamsilverstein
/tests/testdata/modules/images/fetchpriority @pbearne @adamsilverstein

# Module: Full Page Cache Health Check
/modules/object-cache/audit-full-page-cache @manuelRod @westonruter
/tests/modules/object-cache/audit-full-page-cache @manuelRod @westonruter
54 changes: 54 additions & 0 deletions modules/images/fetchpriority/load.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php
/**
* Module Name: Fetchpriority
* Description: Adds a fetchpriority hint for the primary content image on the page to load faster.
* Experimental: Yes
*
* @since n.e.x.t
* @package performance-lab
*/

/**
* Filters an image tag in content to add the fetchpriority attribute if it is not lazy-loaded.
*
* @since n.e.x.t
*
* @param string $filtered_image The image tag to filter.
* @param string $context The context of the image.
* @return string The filtered image tag.
*/
function fetchpriority_img_tag_add_attr( $filtered_image, $context ) {
Comment thread
adamsilverstein marked this conversation as resolved.

if ( 'the_content' !== $context && 'the_post_thumbnail' !== $context ) {
return $filtered_image;
}

// Fetchpriority relies on lazy loading logic.
if ( ! wp_lazy_loading_enabled( 'img', $context ) ) {
return $filtered_image;
}

if ( ! empty( $filtered_image ) && strpos( $filtered_image, 'loading="lazy"' ) === false && strpos( $filtered_image, 'fetchpriority=' ) === false ) {
Comment thread
adamsilverstein marked this conversation as resolved.
$filtered_image = str_replace( '<img ', '<img fetchpriority="high" ', $filtered_image );
Comment thread
felixarntz marked this conversation as resolved.
Comment thread
adamsilverstein marked this conversation as resolved.
remove_filter( 'wp_content_img_tag', 'fetchpriority_img_tag_add_attr' );
Comment thread
adamsilverstein marked this conversation as resolved.
remove_filter( 'post_thumbnail_html', 'fetchpriority_filter_post_thumbnail_html' );
}

return $filtered_image;
}
add_filter( 'wp_content_img_tag', 'fetchpriority_img_tag_add_attr', 10, 2 );

/**
* Filters the post thumbnail HTML to conditionally add the fetchpriority attribute.
*
* @since n.e.x.t
*
* @param string $html The post thumbnail HTML to filter.
* @return string The filtered post thumbnail HTML.
*/
function fetchpriority_filter_post_thumbnail_html( $html ) {
$html = fetchpriority_img_tag_add_attr( $html, 'the_post_thumbnail' );

return $html;
}
add_filter( 'post_thumbnail_html', 'fetchpriority_filter_post_thumbnail_html' );
Comment thread
adamsilverstein marked this conversation as resolved.
82 changes: 82 additions & 0 deletions tests/modules/images/fetchpriority/fetchpriority-tests.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<?php
/**
* Tests the adding of fetchpriority to img tags in the content.
*
* @covers ::fetchpriority_img_tag_add_attr
*/
class Fetchpriority_Test extends WP_UnitTestCase {
protected static $post;
protected static $attachment_id;
protected static $attachment_id_2;

protected $current_size_filter_data = null;
protected $current_size_filter_result = null;

public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ) {
self::$post = $factory->post->create_and_get();
$file = DIR_TESTDATA . '/images/canola.jpg';
self::$attachment_id = $factory->attachment->create_upload_object(
$file,
self::$post->ID,
array(
'post_mime_type' => 'image/jpeg',
)
);
self::$attachment_id_2 = $factory->attachment->create_upload_object(
$file,
self::$post->ID,
array(
'post_mime_type' => 'image/jpeg',
)
);
}

public static function tear_down_after_class() {
wp_delete_attachment( self::$attachment_id, true );
wp_delete_attachment( self::$attachment_id_2, true );
parent::tear_down_after_class();
}

public function test_fetchpriority_img_tag_add_attr_based_on_context_and_loading_lazy() {
$img = get_image_tag( self::$attachment_id, '', '', '', 'large' );
Comment thread
pbearne marked this conversation as resolved.

$this->assertStringContainsString( 'fetchpriority="high"', fetchpriority_img_tag_add_attr( $img, 'the_content' ) );
$this->assertStringNotContainsString( 'fetchpriority="high"', fetchpriority_img_tag_add_attr( $img, 'not_content' ) );

$img = str_replace( '<img ', '<img loading="lazy" ', $img );
$this->assertStringNotContainsString( 'fetchpriority="high"', fetchpriority_img_tag_add_attr( $img, 'the_content' ) );
}

public function test_fetchpriority_img_tag_add_in_wp_filter_content_tags() {
global $wp_query;
global $wp_the_query;
$img = get_image_tag( self::$attachment_id, '', '', '', 'large' );
$img_2 = get_image_tag( self::$attachment_id_2, '', '', '', 'large' );

$img = '<!-- wp:image {"id":' . self::$attachment_id . ',"sizeSlug":"large","linkDestination":"none"} -->
<figure class="wp-block-image size-large">' . $img . '</figure>
<!-- /wp:image -->
<!-- wp:paragraph -->
<p>This is an example page.</p>
<!-- /wp:paragraph -->
<!-- wp:image {"id":' . self::$attachment_id_2 . ',"sizeSlug":"large","linkDestination":"none"} -->
<figure class="wp-block-image size-large">' . $img_2 . '</figure>
<!-- /wp:image -->
';
// Ensure image filtering occurs 'in_the_loop', is_main_query.
$wp_the_query = $wp_query;
$wp_query->in_the_loop = true;
$content = wp_filter_content_tags( $img, 'the_content' );
$this->assertStringContainsString( 'fetchpriority="high"', $content );
$this->assertStringContainsString( 'loading="lazy"', $content );
$this->assertTrue( strpos( $content, 'fetchpriority="high"' ) < strpos( $content, 'loading="lazy"' ) );

$this->assertEquals( 1, substr_count( $content, 'fetchpriority' ) );

// Disable lazy loading and verify fetchpriority isn't added.
add_filter( 'wp_lazy_loading_enabled', '__return_false' );
$content = wp_filter_content_tags( $img, 'the_content' );
$this->assertStringNotContainsString( 'fetchpriority="high"', $content );

}
}