WordPress / performance

Performance plugin from the WordPress Performance Group, which is a collection of standalone performance modules.
https://wordpress.org/plugins/performance-lab/
GNU General Public License v2.0
350 stars 94 forks source link

Convert PNG to AVIF/WebP on upload #371

Closed mxbclang closed 1 week ago

mxbclang commented 2 years ago

As noted in this support topic, add the ability to automatically convert PNG images to WebP.

erikyo commented 2 years ago

I think it's definitely a good idea 💯 if jpgs are not always the ideal source for webp encoding, because the result vary depending on the source quality, pngs would give amazing results -- especially considering that a lossy webp weighs up to 20 times less than a png (png -> webp lossy). This would be a nice performance boost! Another advantage is that in this case there we have generation loss so, at the same SSIM, the images will weight about the 30% compared to a standard jpg.

there would be two options:

My vote goes for png->lossy because the images of websites aren't intended to be 1:1 with the original so we can take the advantage of the compression techniques like chroma subsampling that decimates the image filesize.

Another suggestion is to use the png as the source image and not to create the subsizes in png. I currently use exactly this way: I upload png images that I keep it only as source in order to create the copy and subsizes in webp. In this way I get much higher quality than a jpg, it takes up less space, and I only have one extra image (the source png).

EDIT: the bug of the webp missing transparency is related to versions before gd 2.1.1 (6 years ago, php 5.6)... I forgot to mention about, but i guess actually isn't a real issue since it's deprecated. here more info

maisondasilva commented 11 months ago

@felixarntz Any news about this, I loved the plugin, but most of my images are .png and that would be very good, I did an online conversion test and saw that the images would be half the size!

Thanks

nikolasholm commented 10 months ago

Any update on this yet?

ficod commented 5 months ago

Any plans on this feature? First post in this thread is dated Jun 13, 2022... Is there any progress made or it's just "planned for the future"?

predaytor commented 5 months ago

@ficod, yeah, I decided to convert them manually with Imagick:


<?php

namespace App\Media;

/**
 * Set image quality based on mime type.
 *
 * @param int    $quality    The image quality level.
 * @param string $mime_type  The mime type of the image.
 *
 * @return int The modified image quality level.
 */
function set_image_quality($quality, $mime_type)
{
    // Check if the mime type is 'image/webp'
    if ('image/webp' === $mime_type) {
        // Set a higher quality level for 'image/webp'
        return 86;
    }

    // Return the original quality level for other mime types
    return $quality;
}

// Add a filter to set image quality
add_filter('wp_editor_set_quality', __NAMESPACE__ . '\\set_image_quality', 10, 2);

///

/**
 * Scale down and optimize uploading image.
 *
 * @param array $file The uploading file information.
 * @return array The modified file information.
 */
function resize_preupload_image($file)
{
    $allowed_types = array('image/png', 'image/bmp', 'image/jpeg', 'image/jpg', 'image/webp');

    // Check mime type
    // Check if Imagick extension is available
    if (!in_array($file['type'], $allowed_types) || !class_exists('Imagick', false) || !class_exists('ImagickPixel', false)) {
        return $file;
    }

    // Check size limit
    $limit = 24000;
    $size = $file['size'] / 1024;

    if ($size > $limit) {
        $file['error'] = "Image files must be smaller than {$limit}kb";
        return $file;
    }

    // Get the temporary image path
    $filepath = $file['tmp_name'];

    // Get the file's dimensions
    list($image_width, $image_height) = @getimagesize($filepath);

    // Calculate the new dimensions for scaling
    $max_width = <YOUR_MAX_WIDTH_NUMBER>;
    $max_height = intval($image_height * ($max_width / $image_width));

    // Create a new Imagick object from the uploaded image
    $image = new \Imagick($filepath);

    // Get original image size
    $original_size = strlen($image->getImageBlob());

    // Check if image already has webp format (do not change quality)
    if ('image/webp' === $file['type']) {
        $image->setImageCompressionQuality(100);
    } else {
        // Set webp format (support transparency)
        $image->setImageFormat('webp');
        // Set image compression quality
        $image->setImageCompressionQuality(86);
    }

    // Scale down the image to the new dimensions
    $image->resizeImage(min($image_width, $max_width), min($image_height, $max_height), \Imagick::FILTER_CATROM, 1);

    // Get resized (webp converted) image size
    $resized_size = strlen($image->getImageBlob());

    // Check if the resized image has a larger file size than the original
    if ($resized_size >= $original_size) {
        // Original image has smaller or equal size, so keep it
        $image->clear();
        return $file;
    }

    // Save the resized image, overwrite the original file
    $image->writeImage($filepath);
    $file['size'] = $resized_size;
    $image->clear();

    // Return result
    return $file;
}
add_action('wp_handle_upload_prefilter', __NAMESPACE__ . '\\resize_preupload_image', 10, 1);
adamsilverstein commented 5 months ago

Now that we have landed AVIF support in core, the current "WebP Uploads" image plugin could be expanded to include support for AVIF. This would also be good opportunity to add some more flexibility around input formats we handle, or progressive encoding (also new in 6.5).

@ficod, yeah, I decided to convert them manually with Imagick:

@predaytor - Here is are some alternate approaches:

To filter the mime types that the WebP Uploads plugin transforms, use the webp_uploads_upload_image_mime_transforms filter:

add_filter( 'webp_uploads_upload_image_mime_transforms', function( $transforms ) {
    $transforms['image/png'] = array( 'image/png', 'image/webp' );
    return $transforms;
} );

To leverage the core filter directly:

add_filter( 'image_editor_output_format', function( $mappings ) {
    $mappings['image/png'] = 'image/webp';
    return $mappings;
} );
ficod commented 5 months ago

@adamsilverstein @predaytor Thank you all for your replies.

What I don't understand is why this plugin can't receive an official update to solve the issue. This issue is totally not taken care of, is it considered not important or the project is not being actively developed?

I ended up preferring another plugin: WebP Express

benoitfouc commented 5 months ago

AVIF do not support transparency like the PNG format.

AVIF is a good alternative for JPEG files And WebP is the best alternative for PNG files because WebP support transparency.

So, this plugin being to be useless since the AVIF is now supported by the core and since this plugin do not support convert PNG files to WebP.

We just need a new plugin to convert automaticly WEBP, JPEG and PNG files into AVIF

erikyo commented 5 months ago

Sorry but this is wrong! avif image format fully support alpha channel (the transparency)
https://avif.io/blog/faq/avif-transparency/

Addy Osmani has written a nice book on the argument, recommended https://www.smashingmagazine.com/2021/09/modern-image-formats-avif-webp/

benoitfouc commented 4 months ago

Now that the Modern Images Formats plugin will support AVIF format (output), thanks to @adamsilverstein on #1151. I think the next logical evolution is to support more input like the PNG format.

Adam make this one, for his plugin, what do you think about that setting page ?

image

Leave the choice for users to convert a JPEG input into AVIF, PNG input into WebP, and WebP input into AVIF (for example) that can be a great evolution for our Modern Images Formats plugin and it will be more consistent with the new plugin name 😉

westonruter commented 3 months ago

Two support topics have raised this the past couple days:

phanduynam commented 2 months ago

Please update the topic to add PNG to Avif image format conversion

bolach commented 2 months ago

This is the only reason why i don't use this plugin. No .png support :(

adamsilverstein commented 2 months ago

Let's try to land wider support for uploaded images, including PNGs.

The biggest question I have is about the best UI to provide.

For my plugin (pictured above) I went with giving users full control of the output format they want for each input format, but that me a bit over the top for this plugin? Maybe we can use a simplified approach where you choose an output format, then you choose from a checkbox list of input formats, choosing the ones you want to transform? Or maybe just automatically transform any uploaded images when we can reasonably do so?

westonruter commented 2 months ago

@adamsilverstein Yeah, I do think that would be over-the-top to provide such granularity. With considering decisions not options, should JPEG and PNG always be converted to AVIF? Or would there be scenarios where one should rather be converted to WebP? Like, as I understand, only lossless AVIF supports transparency. So would perhaps all JPEGs be converted to AVIF as well as all non-transparent PNGs, but then leave transparent PNGs to converted to WebP (lossless or lossy)?

For sites that want to have fine-tuned control, I'd think that we'd perhaps offer a filter instead of a UI for that.

adamsilverstein commented 2 months ago

For sites that want to have fine-tuned control, I'd think that we'd perhaps offer a filter instead of a UI for that.

that makes sense, possibly a filter against whatever we decide are the defaults. existing core filters the plugin itself uses could already be used to fine tune the final behavior.

only lossless AVIF supports transparency. So would perhaps all JPEGs be converted to AVIF as well as all non-transparent PNGs, but then leave transparent PNGs to converted to WebP (lossless or lossy)?

interesting point, for transparent images, WebP lossy is probably the best choice. I like the general direction of mapping to what we think is the best available output type for the input type. I will work on a PR with that approach and we can discuss further.

erikyo commented 2 months ago

Like, as I understand, only lossless AVIF supports transparency

Afaik (but I can be wrong) lossy avifs also support the alpha channel (the transparency). you can give a try with squoosh and converting a transparent image to avif (for me has worked)

As to which is "preferred" I prepared this which converts random images and measures their PSNR / SSIM ( spoiler: in the end avif always wins) https://gist.github.com/erikyo/d6ef961adc95a5c74e376a0216b29f69

the only doubts about whether to use avif or not is the time it takes to convert images which is hundreds of times longer than converting a jpeg, this in some cases (e.g. image regeneration by woocommerce) leads to unexpected results

phanduynam commented 2 months ago

I was wondering if you could address this request when it launches with WordPress 6.6? This request has been raised and pending for 2 years and still has not been resolved.

westonruter commented 2 months ago

@erikyo

Afaik (but I can be wrong) lossy avifs also support the alpha channel (the transparency). you can give a try with squoosh and converting a transparent image to avif (for me has worked)

Interesting. I was just going off of what I found in search. For example via shortpixel.com:

AVIF supports transparency for lossless images but doesn’t support transparency for lossy images. On the other hand, WebP is the only image format that supports RGB channel transparency for lossy images.

I guess that's just wrong.

the only doubts about whether to use avif or not is the time it takes to convert images which is hundreds of times longer than converting a jpeg, this in some cases (e.g. image regeneration by woocommerce) leads to unexpected results

That's a great point. I've seen approaches where the WebP is generated first since it is fast, with the AVIF generation then sent to a background process since it can take a long time.

adamsilverstein commented 2 months ago

the only doubts about whether to use avif or not is the time it takes to convert images which is hundreds of times longer than converting a jpeg, this in some cases (e.g. image regeneration by woocommerce) leads to unexpected results

Encoding speed has improved dramatically over time for AVIF so this will depend to some degree on what version of the encoder you are using.

erikyo commented 2 months ago

While libaom has indeed improved over time, encoding an image in AVIF format remains extremely complex, especially in server environments. GPU acceleration is not available, and in many cases, even multicore processing is not feasible.

I attempted to give AVIF a fair chance by modifying the Colab script to record the time used for each step. Here are the results:

Time taken to save 85% quality webp: 0.43184375762939453 seconds
Time taken to save 85% quality jpg: 0.046629905700683594 seconds
Time taken to save 85% quality jxl: 1.72273588180542 seconds
Time taken to save 85% quality avif: 40.48055696487427 seconds

As you can see from these numbers, avif takes significantly longer than other formats, making the avif format unsuitable for large batches of images.

using my server's CPU, I get better results (linearly) of x0.1.

I can be wrong, of course, that's why I would like others in this chat to do the same experiment. please let me know


EDIT: I conducted further tests and also [implemented image resizing](https://gist.github.com/erikyo/d6ef961adc95a5c74e376a0216b29f69 then clic "open in colab"). Here are the results:

Time taken to save 85% quality webp at size 300x300: 0.01772332191467285 seconds
Time taken to save 85% quality jpg at size 300x300: 0.0024929046630859375 seconds
Time taken to save 85% quality jxl at size 300x300: 0.06117439270019531 seconds
Time taken to save 85% quality avif at size 300x300: 2.21492600440979 seconds

Time taken to save 85% quality webp at size 1024x1024: 0.27861666679382324 seconds
Time taken to save 85% quality jpg at size 1024x1024: 0.03254413604736328 seconds
Time taken to save 85% quality jxl at size 1024x1024: 0.9864084720611572 seconds
Time taken to save 85% quality avif at size 1024x1024: 14.245483875274658 seconds

Time taken to save 85% quality webp at size 4k: 1.7801191806793213 seconds
Time taken to save 85% quality jpg at size 4k: 0.23264503479003906 seconds
Time taken to save 85% quality jxl at size 4k: 6.623462438583374 seconds
Time taken to save 85% quality avif at size 4k: 183.6950123310089 seconds

I must say that while small images can achieve a decent processing time, when we going to upload a large image, the result is definitely disastrous :(

While it is true that on a fast server, a single image can be converted in a fraction of the time (about 1/10), it is also important to consider that we often need to generate multiple resizes for each image. This becomes significantly more time-consuming when multiplied by the number of images in the gallery, especially in scenarios like WooCommerce where all images are (sometimes) regenerated.

youri-- commented 2 months ago

@erikyo wow, that's indeed a problematic duration difference. I've not used avif yet myself, and looking at those processing times, I'll probably stick with webp for some time longer.

If you happen to still have those files handy, I would be interested in seeing what the end resulting file sizes were, of those first 4 you mentioned.

adamsilverstein commented 1 month ago

Wow @erikyo - those times are surprisingly large. Thanks for sharing the colab, that is great! I'd like to run similar timing tests in WordPress to see how the PHP libraries compare when processing images. They use the same underlying libraries, so probably not going to be much different though.

adamsilverstein commented 1 month ago

cc: @y-guyon for any feedback on the processing time, maybe there is something about the config that could be optimized

erikyo commented 1 month ago

@adamsilverstein, it would be great if you could test AVIF vs. WebP encoding and decoding with WordPress. As you’ve seen, my tests use ImageMagick (like WordPress), but it’s always better to have real-world tests!

The standard CPU offered by Colab isn’t very fast. On my server, it’s about 10 times faster (so what takes 20 seconds for a single encoded image on Colab only takes 2 seconds on my server), but the difference between formats is still huge. For that reason, after trying to convert all the images in my media library, I found it unreasonable 😔.

jzern commented 1 month ago

@erikyo, with ImageMagick you can try setting 'heic:speed' to 6 or 7 for AVIF. libheif looks like it defaults libaom to speed 0, the slowest setting.

adamsilverstein commented 1 month ago

after trying to convert all the images in my media library, I found it unreasonable

@erikyo I'm curious if you saw particular slowness with lossless images (since thats the focus of this ticket) or all AVIF images?

@erikyo, with ImageMagick you can try setting 'heic:speed' to 6 or 7 for AVIF. libheif looks like it defaults libaom to speed 0, the slowest setting.

@jzern interesting! We should probably fix that in WordPress as well when using Imagick. Also: I wonder why the default is so slow, wouldn't a higher default for Imagick heic:speed make sense?

y-guyon commented 1 month ago

cc: @y-guyon for any feedback on the processing time, maybe there is something about the config that could be optimized

I think so. This comparison uses libavif+aom instead of libheif+aom but I expect AVIF to be around 5 times slower to encode than WebP at default speeds for 2K images in a lossy setting.

Afaik (but I can be wrong) lossy avifs also support the alpha channel (the transparency)

Yes, AVIF supports translucency. The alpha channel can be compressed with or without loss, no matter if the color channels are compressed with or without loss.

I would recommend using lossy AVIF (even for transparency) or keeping the original file format. There are very few use cases requiring lossless conversion in a WordPress context in my opinion.

For non-photo content (screen capture, UI elements etc.), other formats such as WebP may give smaller file sizes than AVIF.

adamsilverstein commented 1 month ago

@erikyo, with ImageMagick you can try setting 'heic:speed' to 6 or 7 for AVIF. libheif looks like it defaults libaom to speed 0, the slowest setting.

Imagick says it uses 5 as the default value - although I didn't see that default in the code.

I created a simple PR to change the default for WordPress Imagick AVIF handling to 7 - https://github.com/WordPress/wordpress-develop/pull/7068

adamsilverstein commented 1 month ago

@adamsilverstein, it would be great if you could test AVIF vs. WebP encoding and decoding with WordPress. As you’ve seen, my tests use ImageMagick (like WordPress), but it’s always better to have real-world tests!

@erikyo -

I created this mini plugin to test processing time by mime type using WordPress - https://gist.github.com/adamsilverstein/b4e91c9ab1e6f546ec98e3dcc53afb7d

Times were too fast in my local to me meaningful to measure. I need to test it in a slower environment to measure actual performance, or modify to run the process repeatedly.

erikyo commented 1 month ago

@jzern Below the tests using different speeds and quality settings for the AVIF format. It seems you are right about that, the "heic:speed" option greatly reduces time without interfering with quality too much.

avif / testing quality + heic:speed (updated with some line charts at the end of the file)

@adamsilverstein thanks again, here are the results:

2k image jpg 2000x2400 ```json { "profiling_data": [ { "format": "image\/jpeg", "size": { "width": 300, "height": 300 }, "filesize": 78452, "time": 0.027272939682006836 }, { "format": "image\/jpeg", "size": { "width": 600, "height": 600 }, "filesize": 78452, "time": 0.0017361640930175781 }, { "format": "image\/jpeg", "size": { "width": 1200, "height": 1200 }, "filesize": 78452, "time": 0.0017290115356445312 }, { "format": "image\/jpeg", "size": { "width": 2400, "height": 2400 }, "filesize": 78452, "time": 0.001683950424194336 }, { "format": "image\/webp", "size": { "width": 300, "height": 300 }, "filesize": 79732, "time": 0.03746390342712402 }, { "format": "image\/webp", "size": { "width": 600, "height": 600 }, "filesize": 79732, "time": 0.012015819549560547 }, { "format": "image\/webp", "size": { "width": 1200, "height": 1200 }, "filesize": 79732, "time": 0.01200103759765625 }, { "format": "image\/webp", "size": { "width": 2400, "height": 2400 }, "filesize": 79732, "time": 0.011939048767089844 }, { "format": "image\/avif", "size": { "width": 300, "height": 300 }, "filesize": 12328, "time": 0.21320605278015137 }, { "format": "image\/avif", "size": { "width": 600, "height": 600 }, "filesize": 12328, "time": 0.1872880458831787 }, { "format": "image\/avif", "size": { "width": 1200, "height": 1200 }, "filesize": 12328, "time": 0.18783307075500488 }, { "format": "image\/avif", "size": { "width": 2400, "height": 2400 }, "filesize": 12328, "time": 0.19110894203186035 } ], "total_time": { "image\/jpeg": { "start": 1721671552.943534, "end": 1721671552.975962, "total": 0.03242802619934082 }, "image\/webp": { "start": 1721671553.005592, "end": 1721671553.079016, "total": 0.07342386245727539 }, "image\/avif": { "start": 1721671553.108473, "end": 1721671553.887918, "total": 0.7794449329376221 } } } ``` ``` -------------------------------------- format, size, time image/jpeg, 300x300, 0.027272939682007 image/jpeg, 600x600, 0.0017361640930176 image/jpeg, 1200x1200, 0.0017290115356445 image/jpeg, 2400x2400, 0.0016839504241943 image/webp, 300x300, 0.037463903427124 image/webp, 600x600, 0.012015819549561 image/webp, 1200x1200, 0.012001037597656 image/webp, 2400x2400, 0.01193904876709 image/avif, 300x300, 0.21320605278015 image/avif, 600x600, 0.18728804588318 image/avif, 1200x1200, 0.187833070755 image/avif, 2400x2400, 0.19110894203186 ```
png image 3600x2700 ```json { "profiling_data": [ { "format": "image\/jpeg", "size": { "width": 300, "height": 300 }, "filesize": 15270, "time": 0.030642032623291016 }, { "format": "image\/jpeg", "size": { "width": 600, "height": 600 }, "filesize": 15270, "time": 0.0013499259948730469 }, { "format": "image\/jpeg", "size": { "width": 1200, "height": 1200 }, "filesize": 15270, "time": 0.0013699531555175781 }, { "format": "image\/jpeg", "size": { "width": 2400, "height": 2400 }, "filesize": 15270, "time": 0.0014090538024902344 }, { "format": "image\/webp", "size": { "width": 300, "height": 300 }, "filesize": 13284, "time": 0.033232927322387695 }, { "format": "image\/webp", "size": { "width": 600, "height": 600 }, "filesize": 13284, "time": 0.010429859161376953 }, { "format": "image\/webp", "size": { "width": 1200, "height": 1200 }, "filesize": 13284, "time": 0.010452032089233398 }, { "format": "image\/webp", "size": { "width": 2400, "height": 2400 }, "filesize": 13284, "time": 0.010426044464111328 }, { "format": "image\/avif", "size": { "width": 300, "height": 300 }, "filesize": 5811, "time": 0.16109609603881836 }, { "format": "image\/avif", "size": { "width": 600, "height": 600 }, "filesize": 5811, "time": 0.1379549503326416 }, { "format": "image\/avif", "size": { "width": 1200, "height": 1200 }, "filesize": 5811, "time": 0.13739490509033203 }, { "format": "image\/avif", "size": { "width": 2400, "height": 2400 }, "filesize": 5811, "time": 0.13708209991455078 } ], "total_time": { "image\/jpeg": { "start": 1721672632.182837, "end": 1721672632.217613, "total": 0.03477597236633301 }, "image\/webp": { "start": 1721672632.550024, "end": 1721672632.614569, "total": 0.0645449161529541 }, "image\/avif": { "start": 1721672632.946851, "end": 1721672633.520387, "total": 0.5735359191894531 } } } ``` ``` -------------------------------------- format, size, time image/jpeg, 300x300, 0.027272939682007 image/jpeg, 600x600, 0.0017361640930176 image/jpeg, 1200x1200, 0.0017290115356445 image/jpeg, 2400x2400, 0.0016839504241943 image/webp, 300x300, 0.037463903427124 image/webp, 600x600, 0.012015819549561 image/webp, 1200x1200, 0.012001037597656 image/webp, 2400x2400, 0.01193904876709 image/avif, 300x300, 0.21320605278015 image/avif, 600x600, 0.18728804588318 image/avif, 1200x1200, 0.187833070755 image/avif, 2400x2400, 0.19110894203186 ```
very large png image 4300x2850 ```json { "profiling_data": [ { "format": "image\/jpeg", "size": { "width": 300, "height": 300 }, "filesize": 10764, "time": 0.023726940155029297 }, { "format": "image\/jpeg", "size": { "width": 600, "height": 600 }, "filesize": 10764, "time": 0.001238107681274414 }, { "format": "image\/jpeg", "size": { "width": 1200, "height": 1200 }, "filesize": 10764, "time": 0.0012209415435791016 }, { "format": "image\/jpeg", "size": { "width": 2400, "height": 2400 }, "filesize": 10764, "time": 0.0011870861053466797 }, { "format": "image\/webp", "size": { "width": 300, "height": 300 }, "filesize": 8844, "time": 0.03127789497375488 }, { "format": "image\/webp", "size": { "width": 600, "height": 600 }, "filesize": 8844, "time": 0.008497953414916992 }, { "format": "image\/webp", "size": { "width": 1200, "height": 1200 }, "filesize": 8844, "time": 0.008488893508911133 }, { "format": "image\/webp", "size": { "width": 2400, "height": 2400 }, "filesize": 8844, "time": 0.008411169052124023 }, { "format": "image\/avif", "size": { "width": 300, "height": 300 }, "filesize": 3431, "time": 0.1293962001800537 }, { "format": "image\/avif", "size": { "width": 600, "height": 600 }, "filesize": 3431, "time": 0.1075899600982666 }, { "format": "image\/avif", "size": { "width": 1200, "height": 1200 }, "filesize": 3431, "time": 0.10776495933532715 }, { "format": "image\/avif", "size": { "width": 2400, "height": 2400 }, "filesize": 3431, "time": 0.10826396942138672 } ], "total_time": { "image\/jpeg": { "start": 1721673332.803404, "end": 1721673332.830782, "total": 0.027377843856811523 }, "image\/webp": { "start": 1721673333.215625, "end": 1721673333.272304, "total": 0.05667901039123535 }, "image\/avif": { "start": 1721673333.657167, "end": 1721673334.11019, "total": 0.45302295684814453 } } } ``` ``` image/jpeg, 300x300, 0.023726940155029 image/jpeg, 600x600, 0.0012381076812744 image/jpeg, 1200x1200, 0.0012209415435791 image/jpeg, 2400x2400, 0.0011870861053467 image/webp, 300x300, 0.031277894973755 image/webp, 600x600, 0.008497953414917 image/webp, 1200x1200, 0.0084888935089111 image/webp, 2400x2400, 0.008411169052124 image/avif, 300x300, 0.12939620018005 image/avif, 600x600, 0.10758996009827 image/avif, 1200x1200, 0.10776495933533 image/avif, 2400x2400, 0.10826396942139

image

a small consideration about this. the 300x300 images takes more time to be processed, probably due to the time required time to resize the image with the sinc-lanczos filter. this pattern is repeated for all of these formats as well

My server specs: Server architecture | Linux 5.15.0-116-generic x86_64 cpu Intel(R) Core(TM) i5-7500T CPU @ 2.70GHz, 4 cores memory 7.63 GiB total Web server | nginx/1.18.0 PHP version | 7.4.33 (Supports 64bit values) PHP SAPI | fpm-fcgi PHP max input variables | 1000 PHP time limit | 120 PHP memory limit | 512M Max input time | 120 Upload max filesize | 128M PHP post max size | 128M cURL version | 7.81.0 OpenSSL/3.0.2 Is SUHOSIN installed? | No Is the Imagick library available? | Yes Are pretty permalinks supported? | Yes Current time | 2024-07-22T18:43:30+00:00 Current UTC time | Monday, 22-Jul-24 18:43:30 UTC Current Server time | 2024-07-22T19:43:28+01:00 ImageMagick version number | 1691 ImageMagick version string | ImageMagick 6.9.11-60 Q16 x86_64 2021-01-25 https://imagemagick.org Imagick version | 3.7.0 File uploads | Enabled Maximum size of post data allowed | 128M Maximum size of an uploaded file | 128M Maximum effective file size | 128 MB Maximum number of files allowed | 20 Imagick Resource Limits | area: 122 MBdisk: 1073741824file: 768map: 512 MBmemory: 256 MBthread: 1time: 9.2233720368548E+18 ImageMagick-supported file formats | 3FR, 3G2, 3GP, AAI, AI, APNG, ART, ARW, AVI, AVIF, AVS, BGR, BGRA, BGRO, BIE, BMP, BMP2, BMP3, BRF, CAL, CALS, CANVAS, CAPTION, CIN, CIP, CLIP, CMYK, CMYKA, CR2, CR3, CRW, CUR, CUT, DATA, DCM, DCR, DCX, DDS, DFONT, DNG, DPX, DXT1, DXT5, EPDF, EPI, EPS, EPS2, EPS3, EPSF, EPSI, EPT, EPT2, EPT3, ERF, FAX, FILE, FITS, FRACTAL, FTP, FTS, G3, G4, GIF, GIF87, GRADIENT, GRAY, GRAYA, GROUP4, H, HALD, HDR, HEIC, HISTOGRAM, HRZ, HTM, HTML, HTTP, HTTPS, ICB, ICO, ICON, IIQ, INFO, INLINE, IPL, ISOBRL, ISOBRL6, J2C, J2K, JBG, JBIG, JNG, JNX, JP2, JPC, JPE, JPEG, JPG, JPM, JPS, JPT, JSON, K25, KDC, LABEL, M2V, M4V, MAC, MAGICK, MAP, MASK, MAT, MATTE, MEF, MIFF, MKV, MNG, MONO, MOV, MP4, MPC, MPG, MRW, MSL, MTV, MVG, NEF, NRW, NULL, ORF, OTB, OTF, PAL, PALM, PAM, PATTERN, PBM, PCD, PCDS, PCL, PCT, PCX, PDB, PDF, PDFA, PEF, PES, PFA, PFB, PFM, PGM, PGX, PICON, PICT, PIX, PJPEG, PLASMA, PNG, PNG00, PNG24, PNG32, PNG48, PNG64, PNG8, PNM, POCKETMOD, PPM, PREVIEW, PS, PS2, PS3, PSB, PSD, PTIF, PWP, RADIAL-GRADIENT, RAF, RAS, RAW, RGB, RGBA, RGBO, RGF, RLA, RLE, RMF, RW2, SCR, SCT, SFW, SGI, SHTML, SIX, SIXEL, SPARSE-COLOR, SR2, SRF, STEGANO, SUN, TEXT, TGA, THUMBNAIL, TIFF, TIFF64, TILE, TIM, TTC, TTF, TXT, UBRL, UBRL6, UIL, UYVY, VDA, VICAR, VID, VIDEO, VIFF, VIPS, VST, WBMP, WEBM, WEBP, WMV, WPG, X, X3F, XBM, XC, XCF, XPM, XPS, XV, XWD, YCbCr, YCbCrA, YUV GD version | 2.3.3 GD supported file formats | GIF, JPEG, PNG, WebP, BMP, XPM Ghostscript version | 9.55.0

@y-guyon Thanks so much for providing such interesting information! will try asap also with the avif codec. I have chosen the heic one since that Colab script is from 2 years ago, and at that time the heic codec was much more widespread and (if I remember correctly) was also faster

I would, however, like to point out that the command from the command line is used and instead WordPress uses Imagick, which is not performing in the same way. The biggest limitation in this case would be the number of cores used to convert the image than with imagemagick it should only use 1 core for each file converted

adamsilverstein commented 1 month ago

@erikyo thanks for sharing those results. Clearly the AVIF generation is taking much longer than the other formats - still the slowest time was well under a second, so for average use in WordPress this might be OK. I'll try to repeat the experiment on a lower end server as well as expanding the code to run a large number of repetitions.

@jzern Bellow the tests using different speeds and quality settings for the AVIF format. It seems you are right about that, the "heic:speed" option greatly reduces time without interfering with quality too much.

Seems likely we should change the default for WordPress (from 5) to 7

jzern commented 1 month ago

@jzern Bellow the tests using different speeds and quality settings for the AVIF format. It seems you are right about that, the "heic:speed" option greatly reduces time without interfering with quality too much.

Thanks for testing it out. The results look reasonable.

Seems likely we should change the default for WordPress (from 5) to 7

libavif's default is 6; either that or 7 should be a good default.

erikyo commented 1 month ago

To verify, I modified the script so that it now uses only the full-size image and tests the quality vs ‘heif:speed’ vs time

test 2

It is even clearer that there is no quality loss with speed = 7. However, since the default speed for ImageMagick is 6, changing it to 7 is unlikely to affect the encoding performance significantly.

adamsilverstein commented 1 month ago

It is even clearer that there is no quality loss with speed = 7. However, since the default speed for ImageMagick is 6, changing it to 7 is unlikely to affect the encoding performance significantly.

Somewhere I saw a default of 5 mentioned for Imagick (although I didn't find the code), perhaps it is readable so I will try to check it. Still if quality isn't adversely affected, probably worth raising given the very slow encoding speed.

jzern commented 1 month ago

Somewhere I saw a default of 5 mentioned for Imagick (although I didn't find the code), perhaps it is readable so I will try to check it. Still if quality isn't adversely affected, probably worth raising given the very slow encoding speed.

https://imagemagick.org/script/defines.php

heic:speed=value    set the HEIC speed parameter. Integer value from 0-9. Default is 5.

It would be good to verify this though.

adamsilverstein commented 1 month ago

It would be good to verify this though.

I couldn't find the default anywhere in the codebase, but I did see a 22% speed improvement when explicitly setting the speed variable to 7 (comments on the PR). I can re-test with 5 to verify this is the same speed as not setting a speed - this will confirm the default.

In the meantime, I plan to resume work here on the PNG -> AVIF/WebP conversion support.

adamsilverstein commented 1 month ago

I created a PR that adds PNG upload to AVIF (or WebP) output - https://github.com/WordPress/performance/pull/1421

chrillep commented 6 days ago

@mukeshpanchal27 friday release? 🤠

swissspidy commented 6 days ago

The next Performance Lab release is planned for the week after WordCamp US. See https://make.wordpress.org/core/2024/09/03/performance-chat-summary-03-september-2024/

westonruter commented 6 days ago

@chrillep You can still use a pre-release version of the plugin though. I just created a build via npm run build-plugins:zip: webp-uploads.zip

Your early testing and feedback would be much appreciated!

benoitfouc commented 22 hours ago

@chrillep You can still use a pre-release version of the plugin though. I just created a build via npm run build-plugins:zip: webp-uploads.zip

Your early testing and feedback would be much appreciated!

Thank you very much, i make some tests with your file and all is working good for me :) 🚀