FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Discard WebP image if it is larger than corresponding JPEG image by mukeshpanchal27 · Pull Request #418 · WordPress/performance · GitHub

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension .php  (6) All 1 file type selected
Viewed files
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Unified
Split
Hide whitespace
Diff view
Unified
Split
Hide whitespace
32 changes: 32 additions & 0 deletions modules/images/webp-uploads/helper.php
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -240,3 +240,35 @@ function webp_uploads_get_attachment_sources( $attachment_id, $size = 'thumbnail
// Return an empty array if no sources found.
return array();
}

/**
* Check whether the additional image is larger than the original image.
*
* @since n.e.x.t
*
* @param array $original An array with the metadata of the attachment.
* @param array $additional An array containing the filename and file size for additional mime.
* @return bool True if the additional image is larger than the original image, otherwise false.
*/
function webp_uploads_should_discard_additional_image_file( array $original, array $additional ) {
$original_image_filesize = isset( $original['filesize'] ) ? (int) $original['filesize'] : 0;
$additional_image_filesize = isset( $additional['filesize'] ) ? (int) $additional['filesize'] : 0;
if ( $original_image_filesize > 0 && $additional_image_filesize > 0 ) {
/**
* Filter whether WebP images that are larger than the matching JPEG should be discarded.
*
* By default the performance lab plugin will use the mime type with the smaller filesize
* rather than defaulting to `webp`.
*
* @since n.e.x.t
*
* @param bool $preferred_filesize Prioritize file size over mime type. Default true.
*/
$webp_discard_larger_images = apply_filters( 'webp_uploads_discard_larger_generated_images', true );

if ( $webp_discard_larger_images && $additional_image_filesize >= $original_image_filesize ) {
return true;
}
}
return false;
}
172 changes: 77 additions & 95 deletions modules/images/webp-uploads/load.php
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,11 @@ function webp_uploads_create_sources_property( array $metadata, $attachment_id )
continue;
}

if ( webp_uploads_should_discard_additional_image_file( $metadata, $image ) ) {
wp_delete_file_from_directory( $destination, $original_directory );
continue;
}

$metadata['sources'][ $targeted_mime ] = $image;
wp_update_attachment_metadata( $attachment_id, $metadata );
}
Expand Down Expand Up @@ -156,6 +161,12 @@ function webp_uploads_create_sources_property( array $metadata, $attachment_id )
continue;
}

if ( webp_uploads_should_discard_additional_image_file( $properties, $source ) ) {
$destination = path_join( $original_directory, $source['file'] );
wp_delete_file_from_directory( $destination, $original_directory );
Comment thread
mukeshpanchal27 marked this conversation as resolved.
continue;
}

$properties['sources'][ $mime ] = $source;
$metadata['sizes'][ $size_name ] = $properties;
wp_update_attachment_metadata( $attachment_id, $metadata );
Expand Down Expand Up @@ -481,6 +492,7 @@ function webp_uploads_update_image_references( $content ) {
* for the specified image sizes, the *.webp references are stored inside of each size.
*
* @since 1.0.0
* @since n.e.x.t Remove `webp_uploads_prefer_smaller_image_file` filter
*
* @param string $original_image An <img> tag where the urls would be updated.
* @param string $context The context where this is function is being used.
Expand All @@ -490,24 +502,11 @@ function webp_uploads_update_image_references( $content ) {
function webp_uploads_img_tag_update_mime_type( $original_image, $context, $attachment_id ) {
$image = $original_image;
$metadata = wp_get_attachment_metadata( $attachment_id );

if ( empty( $metadata['file'] ) ) {
return $image;
}

/**
* Filters whether the smaller image should be used regardless of which MIME type is preferred overall.
*
* This is disabled by default only because it is not part of the current WordPress core feature proposal.
*
* By enabling this, the plugin will compare the image file sizes and prefer the smaller file regardless of MIME
* type.
*
* @since 1.0.0
*
* @param bool $prefer_smaller_image_file Whether to prefer the smaller image file.
*/
$prefer_smaller_image_file = apply_filters( 'webp_uploads_prefer_smaller_image_file', false );

/**
* Filters mime types that should be used to update all images in the content. The order of
* mime types matters. The first mime type in the list will be used if it is supported by an image.
Expand All @@ -523,58 +522,73 @@ function webp_uploads_img_tag_update_mime_type( $original_image, $context, $atta
// Get the original mime type for comparison.
$original_mime = get_post_mime_type( $attachment_id );

$target_mime = null;
foreach ( $target_mimes as $mime ) {
if ( isset( $metadata['sources'][ $mime ] ) ) {
$target_mime = $mime;
break;
foreach ( $target_mimes as $target_mime ) {

if ( $target_mime === $original_mime ) {
continue;
}
}

if ( null === $target_mime ) {
return $image;
}
if ( ! isset( $metadata['sources'][ $target_mime ]['file'] ) ) {
continue;
}

// Replace the full size image if present.
if ( isset( $metadata['sources'][ $target_mime ]['file'] ) ) {
// Initially set the target mime as the replacement source.
$replacement_source = $metadata['sources'][ $target_mime ]['file'];
/**
* Filter to replace additional image source file, by locating the original
* mime types of the file and return correct file path in the end.
*
* Altering the $image tag through this filter effectively short-circuits the default replacement logic using the preferred MIME type.
*
* @since 1.1.0
*
* @param string $image An <img> tag where the urls would be updated.
* @param int $attachment_id The ID of the attachment being modified.
* @param string $size The size name that would be used to create this image, out of the registered subsizes.
* @param string $target_mime The target mime in which the image should be created.
* @param string $context The context where this is function is being used.
*/
$filtered_image = (string) apply_filters( 'webp_uploads_pre_replace_additional_image_source', $image, $attachment_id, 'full', $target_mime, $context );

// Check for the smaller image file.
if (
$prefer_smaller_image_file &&
! empty( $metadata['sources'][ $target_mime ]['filesize'] ) &&
! empty( $metadata['sources'][ $original_mime ]['filesize'] ) &&
$metadata['sources'][ $original_mime ]['filesize'] < $metadata['sources'][ $target_mime ]['filesize']
) {
// Set the original source file as the replacement if smaller.
$replacement_source = $metadata['sources'][ $original_mime ]['file'];
// If filtered image is same as the image, run our own replacement logic, otherwise rely on the filtered image.
if ( $filtered_image === $image ) {
$basename = wp_basename( $metadata['file'] );
$image = str_replace(
$basename,
$metadata['sources'][ $target_mime ]['file'],
$image
);
} else {
$image = $filtered_image;
}
}

// Replace sub sizes for the image if present.
foreach ( $metadata['sizes'] as $size => $size_data ) {
if ( empty( $size_data['file'] ) ) {
continue;
}

$basename = wp_basename( $metadata['file'] );
if ( $basename !== $replacement_source ) {
foreach ( $target_mimes as $target_mime ) {

/**
* Filter to replace additional image source file, by locating the original
* mime types of the file and return correct file path in the end.
*
* Altering the $image tag through this filter effectively short-circuits the default replacement logic using the preferred MIME type.
*
* @since 1.1.0
*
* @param string $image An <img> tag where the urls would be updated.
* @param int $attachment_id The ID of the attachment being modified.
* @param string $size The size name that would be used to create this image, out of the registered subsizes.
* @param string $target_mime The target mime in which the image should be created.
* @param string $context The context where this is function is being used.
*/
$filtered_image = (string) apply_filters( 'webp_uploads_pre_replace_additional_image_source', $image, $attachment_id, 'full', $target_mime, $context );
if ( $target_mime === $original_mime ) {
continue;
}

if ( ! isset( $size_data['sources'][ $target_mime ]['file'] ) ) {
continue;
}

if ( $size_data['file'] === $size_data['sources'][ $target_mime ]['file'] ) {
continue;
}

/** This filter is documented in modules/images/webp-uploads/load.php */
$filtered_image = (string) apply_filters( 'webp_uploads_pre_replace_additional_image_source', $image, $attachment_id, $size, $target_mime, $context );

// If filtered image is same as the image, run our own replacement logic, otherwise rely on the filtered image.
if ( $filtered_image === $image ) {
$image = str_replace(
$basename,
$metadata['sources'][ $target_mime ]['file'],
$size_data['file'],
$size_data['sources'][ $target_mime ]['file'],
$image
);
} else {
Expand All @@ -583,53 +597,21 @@ function webp_uploads_img_tag_update_mime_type( $original_image, $context, $atta
}
}

// Replace sub sizes for the image if present.
foreach ( $metadata['sizes'] as $size => $size_data ) {
if ( empty( $size_data['file'] ) ) {
continue;
}

if ( empty( $size_data['sources'][ $target_mime ]['file'] ) ) {
continue;
}
foreach ( $target_mimes as $target_mime ) {

if ( $size_data['file'] === $size_data['sources'][ $target_mime ]['file'] ) {
if ( $target_mime === $original_mime ) {
continue;
}

// Do not update image URL if the target image is larger than the original.
if (
$prefer_smaller_image_file &&
! empty( $size_data['sources'][ $target_mime ]['filesize'] ) &&
! empty( $size_data['sources'][ $original_mime ]['filesize'] ) &&
$size_data['sources'][ $original_mime ]['filesize'] < $size_data['sources'][ $target_mime ]['filesize']
! has_action( 'wp_footer', 'webp_uploads_wepb_fallback' ) &&
$image !== $original_image &&
'the_content' === $context &&
'image/jpeg' === $original_mime &&
'image/webp' === $target_mime
) {
continue;
add_action( 'wp_footer', 'webp_uploads_wepb_fallback' );
}

/** This filter is documented in modules/images/webp-uploads/load.php */
$filtered_image = (string) apply_filters( 'webp_uploads_pre_replace_additional_image_source', $image, $attachment_id, $size, $target_mime, $context );

// If filtered image is same as the image, run our own replacement logic, otherwise rely on the filtered image.
if ( $filtered_image === $image ) {
$image = str_replace(
$size_data['file'],
$size_data['sources'][ $target_mime ]['file'],
$image
);
} else {
$image = $filtered_image;
}
}

if (
! has_action( 'wp_footer', 'webp_uploads_wepb_fallback' ) &&
$image !== $original_image &&
'the_content' === $context &&
'image/jpeg' === $original_mime &&
'image/webp' === $target_mime
) {
add_action( 'wp_footer', 'webp_uploads_wepb_fallback' );
}

return $image;
Expand Down
44 changes: 44 additions & 0 deletions tests/modules/images/webp-uploads/helper-tests.php
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -410,4 +410,48 @@ function () {
$this->assertIsArray( $transforms );
$this->assertSame( array( 'image/jpeg' => array( 'image/jpeg', 'image/webp' ) ), $transforms );
}

/**
* @dataProvider data_provider_image_filesize
*
* @test
*/
public function it_should_discard_additional_image_if_larger_than_the_original_image( $original_filesize, $additional_filesize, $expected_status ) {
add_filter( 'webp_uploads_discard_larger_generated_images', '__return_true' );

$output = webp_uploads_should_discard_additional_image_file( $original_filesize, $additional_filesize );
$this->assertSame( $output, $expected_status );
}

public function data_provider_image_filesize() {
return array(
array(
array( 'filesize' => 120101 ),
array( 'filesize' => 100101 ),
false,
),
array(
array( 'filesize' => 100101 ),
array( 'filesize' => 120101 ),
true,
),
array(
array( 'filesize' => 10101 ),
array( 'filesize' => 10101 ),
true,
),
);
}

/**
* @dataProvider data_provider_image_filesize
*
* @test
*/
public function it_should_never_discard_additional_image_if_filter_is_false( $original_filesize, $additional_filesize ) {
add_filter( 'webp_uploads_discard_larger_generated_images', '__return_false' );

$output = webp_uploads_should_discard_additional_image_file( $original_filesize, $additional_filesize );
$this->assertFalse( $output );
}
}
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@

class WebP_Uploads_Image_Edit_Tests extends ImagesTestCase {

public function set_up() {
parent::set_up();

add_filter( 'webp_uploads_discard_larger_generated_images', '__return_false' );
}

/**
* Backup the sources structure alongside the full size
*
Expand Down
Loading

Back | FazBrowse Home | New Git URL