Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add: Auto Sizes for Lazy-loaded Images #904

Merged
merged 42 commits into from
Feb 19, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
9a14b1f
Add: Auto Sizes for Lazy-loaded Images
joemcgill Dec 14, 2023
a5e4afa
Update module constant name
joemcgill Dec 19, 2023
a7dffc5
Add CODEOWNERS entry
joemcgill Dec 19, 2023
97980c1
Add initial unit tests
joemcgill Dec 19, 2023
cab72e1
Merge pull request #913 from WordPress/update/auto-sizes-module
joemcgill Dec 20, 2023
8e6ef6f
Update hook function names
joemcgill Jan 5, 2024
db4a5da
Add plugin readme.txt
joemcgill Jan 5, 2024
1a88b89
Fix Plugin header name.
joemcgill Jan 5, 2024
7e3c544
Update plugin description
joemcgill Jan 5, 2024
6870baf
Consistently use hyphenated 'auto-sizes'
joemcgill Jan 8, 2024
d0a19e5
Merge pull request #922 from WordPress/update/auto-sizes-plugin
joemcgill Jan 8, 2024
98af1d7
Merge branch 'trunk' into feature/auto-sizes
joemcgill Jan 10, 2024
6b3d16d
Fix PHPCS whitespace issue
joemcgill Jan 10, 2024
bd625e8
Merge pull request #931 from WordPress/update/auto-sizes-phpcs
joemcgill Jan 10, 2024
35e5fbf
Auto-sizes: Disallow direct file access
joemcgill Jan 17, 2024
3cb88e5
Merge pull request #945 from WordPress/fix/auto-sizes-direct-load
joemcgill Jan 17, 2024
161a738
Move plugin to plugins folder
mukeshpanchal27 Feb 6, 2024
1ff1004
Merge branch 'trunk' into fix/unit-test
mukeshpanchal27 Feb 6, 2024
5f174b7
Fix unit tests
mukeshpanchal27 Feb 6, 2024
2fab10a
Merge pull request #970 from WordPress/trunk
swissspidy Feb 6, 2024
a5f78b4
Merge branch 'feature/auto-sizes' into fix/unit-test
mukeshpanchal27 Feb 6, 2024
8f3c458
Merge pull request #971 from WordPress/fix/unit-test
mukeshpanchal27 Feb 6, 2024
d10052f
Merge branch 'feature/auto-sizes' into move/auto-sizes
mukeshpanchal27 Feb 6, 2024
23bcfc2
Unit test coverage setup
mukeshpanchal27 Feb 6, 2024
edba918
Add new line at end
mukeshpanchal27 Feb 6, 2024
45a8b57
Add new line at end
mukeshpanchal27 Feb 6, 2024
2daf975
Merge branch 'feature/modules-to-plugins' into move/auto-sizes
mukeshpanchal27 Feb 6, 2024
88040f2
Use single unit test file for plugins
mukeshpanchal27 Feb 7, 2024
14c4776
Adjust spacing
mukeshpanchal27 Feb 7, 2024
87f3a04
Added support for plugin/plugin.php
mukeshpanchal27 Feb 7, 2024
852775d
Remove test plugin
mukeshpanchal27 Feb 9, 2024
bc2884f
Adjust bootstrap file code
mukeshpanchal27 Feb 9, 2024
4b0974e
Add plugin into plugins.json
mukeshpanchal27 Feb 12, 2024
8cfded4
Address review feedback
mukeshpanchal27 Feb 13, 2024
2a687c7
Add plugin directory assets for Auto Sizes
westonruter Feb 14, 2024
6901573
Squoosh images from Figma
westonruter Feb 14, 2024
6fa9128
Compress icon.svg with SVGOMG
westonruter Feb 14, 2024
f0d74fb
Merge pull request #986 from WordPress/add/auto-sizes-plugin-assets
swissspidy Feb 15, 2024
7f3b13b
Address review feedback
mukeshpanchal27 Feb 15, 2024
9addb11
Merge pull request #972 from WordPress/move/auto-sizes
mukeshpanchal27 Feb 19, 2024
2d0deca
Move auto-sizes plugin assets to plugins folder
mukeshpanchal27 Feb 19, 2024
5aeb1c4
Merge pull request #999 from WordPress/move/auto-sizes-plugin-assets
mukeshpanchal27 Feb 19, 2024
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
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,8 @@
/modules/images/dominant-color-images @pbearne @spacedmonkey
/tests/modules/images/dominant-color-images @pbearne @spacedmonkey
/tests/testdata/modules/images/dominant-color-images @pbearne @spacedmonkey

# Module: Auto-sizes for Lazy-Loaded Images
/modules/images/auto-sizes @joemcgill
/tests/modules/images/auto-sizes @joemcgill
/tests/testdata/modules/images/auto-sizes @joemcgill
71 changes: 71 additions & 0 deletions modules/images/auto-sizes/hooks.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php
/**
* Hook callbacks used for Auto Sizes for Lazy-loaded Images.
*
* @package performance-lab
* @since n.e.x.t
*/

if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}

/**
* Adds auto to the sizes attribute to the image, if applicable.
*
* @since n.e.x.t
*
* @param array $attr Attributes for the image markup.
* @return array The filtered attributes for the image markup.
*/
function performance_lab_auto_sizes_attr( $attr ) {
joemcgill marked this conversation as resolved.
Show resolved Hide resolved
// Bail early if the image is not lazy-loaded.
if ( ! isset( $attr['loading'] ) || 'lazy' !== $attr['loading'] ) {
return $attr;
}

// Bail early if the image is not responsive.
if ( ! isset( $attr['sizes'] ) ) {
return $attr;
}

// Don't add 'auto' to the sizes attribute if it already exists.
if ( false !== strpos( $attr['sizes'], 'auto,' ) ) {
return $attr;
}

$attr['sizes'] = 'auto, ' . $attr['sizes'];

return $attr;
}
add_filter( 'wp_get_attachment_image_attributes', 'performance_lab_auto_sizes_attr' );

/**
* Adds auto to the sizes attribute to the image, if applicable.
*
* @since n.e.x.t
*
* @param string $html The HTML image tag markup being filtered.
* @return string The filtered HTML image tag markup.
*/
function performance_lab_auto_sizes_img_tag( $html ) {
// Bail early if the image is not lazy-loaded.
if ( false === strpos( $html, 'loading="lazy"' ) ) {
return $html;
}

// Bail early if the image is not responsive.
if ( false === strpos( $html, 'sizes="' ) ) {
return $html;
}

// Don't double process content images.
if ( false !== strpos( $html, 'sizes="auto,' ) ) {
return $html;
}

$html = str_replace( 'sizes="', 'sizes="auto, ', $html );

return $html;
}
add_filter( 'wp_content_img_tag', 'performance_lab_auto_sizes_img_tag' );
18 changes: 18 additions & 0 deletions modules/images/auto-sizes/load.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php
/**
joemcgill marked this conversation as resolved.
Show resolved Hide resolved
* Module Name: Auto Sizes for Lazy-loaded Images.
* Description: Implements auto sizes for lazy loaded images.
joemcgill marked this conversation as resolved.
Show resolved Hide resolved
* Experimental: Yes
*
* @package performance-lab
* @since n.e.x.t
*/

// Define the constant.
if ( defined( 'IMAGE_AUTO_SIZES_VERSION' ) ) {
return;
}

define( 'IMAGE_AUTO_SIZES_VERSION', 'Performance Lab ' . PERFLAB_VERSION );

require_once __DIR__ . '/hooks.php';
90 changes: 90 additions & 0 deletions tests/modules/images/auto-sizes/auto-sizes-test.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<?php
/**
* Tests for the Auto Sizes for Lazy-loaded Images module.
*
* @package performance-lab
* @group auto-sizes
*/

class AutoSizesTests extends WP_UnitTestCase {

/**
* Attachment ID.
*
Copy link
Member

@westonruter westonruter Jan 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I realize you can't (shouldn't?) apply this suggestion here, but this will fix the linting error I believe.

Suggested change
*
*

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep! Handled in #931, which also requires some extra hoops to add the correct labels, etc.

Interestingly our npm run lint-php script does not catch this, while composer run lint does. I'm going to investigate why that is at a later date. I'm not sure what changed upstream that caused the error to show up here in the first place but it's good that it did.

* @var int
*/
public static $image_id;

/**
* Setup shared fixtures.
*/
public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ) {
self::$image_id = $factory->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg' );
}

/**
* Helper function to create image markup from a given attachment ID.
*
* @param int $attachment_id Attachment ID.
* @return string Image markup.
*/
public function get_image_tag( $attachment_id ) {
return get_image_tag( $attachment_id, '', '', '', 'large' );
}

/**
* Test generated markup for an image with lazy loading gets auto sizes.
*
* @covers ::performance_lab_auto_sizes_attr
*/
public function test_image_with_lazy_loading_has_auto_sizes() {
$this->assertStringContainsString(
'sizes="auto, ',
wp_get_attachment_image( self::$image_id, 'large', null, array( 'loading' => 'lazy' ) )
);
}

/**
* Test generated markup for an image without lazy loading does not get auto sizes.
*
* @covers ::performance_lab_auto_sizes_attr
*/
public function test_image_without_lazy_loading_does_not_have_auto_sizes() {
$this->assertStringContainsString(
'sizes="(max-width: 1024px) 100vw, 1024px"',
wp_get_attachment_image( self::$image_id, 'large', null, array( 'loading' => '' ) )
);
}

/**
* Test content filtered markup with lazy loading gets auto sizes.
*
* @covers ::performance_lab_auto_sizes_img_tag
*/
public function test_content_image_with_lazy_loading_has_auto_sizes() {
// Force lazy loading attribute.
add_filter( 'wp_img_tag_add_loading_attr', '__return_true' );

$image_tag = $this->get_image_tag( self::$image_id );

$this->assertStringContainsString(
'sizes="auto, (max-width: 1024px) 100vw, 1024px"',
wp_filter_content_tags( $this->get_image_tag( self::$image_id ) )
);
}

/**
* Test content filtered markup without lazy loading does not get auto sizes.
*
* @covers ::performance_lab_auto_sizes_img_tag
*/
public function test_content_image_without_lazy_loading_does_not_have_auto_sizes() {
// Disable lazy loading attribute.
add_filter( 'wp_img_tag_add_loading_attr', '__return_false' );

$this->assertStringContainsString(
'sizes="(max-width: 1024px) 100vw, 1024px"',
wp_filter_content_tags( $this->get_image_tag( self::$image_id ) )
);
}
}