-
Notifications
You must be signed in to change notification settings - Fork 108
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
Optimize compression levels for WebP, test file sizes vs. JPEGs #7
Comments
I'm doing some exploration here to see if we can adapt https://github.com/cramforce/avif-webp-quality-setting to get the data we need. |
Good read on the topic: Having a second option for compression for @2x+ retinas might be useful. Did a test for a couple of ±1000px images at 75% quality webp yielded 30-35K, while a ±15% quality yielded 15-20K, which isn't a significant enough bump to warrant the complexity of the implementation. |
@mehigh Thank you! This is really interesting. Some updates: It's a very rough proof of concept at the moment. I’m currently trying to get it to work with GD as well. Ran into a problem where GD in the WordPress Docker Environment doesn’t seem to support WebP on the default PHP, at least on my installation, so digging into that. As far as I'm aware, this was added back when WebP support was added to WordPress. If you download that branch, and toss it in any sort of local server, you can view the results from the initial dataset by visiting I’m hoping running it on GD, along with expanding the image set, will help verify those results. On Imagick, initial results show the current default is close, anyway, but that different types of images change the optimal level, so a larger sample set of images would be helpful. |
I've been making good progress here, and about ready to move the branch changes into main on my fork: There's documentation there now, and it should be possible to use Here are a couple example reports generated by the script, both with DSSIM 3.1.2: As a next step, I'm:
After that, I think we still should test with some additional images, so picking appropriate ones would be a good idea. Any recommendations on sample sets and / or single additional high resolution images would be great. As a last note, right now this uses DSSIM, but it's pretty straight-forward to swap that out for any other image comparison tool. So if there's something better out there (a little looking found SSIMULACRA, for instance, although that looks to be a couple years old), we can run the script against that as well. |
I ported the changes in the branches into a clean branch so that I could make a PR, to bring back to main on my repo: I’m not sure if it’d be better for me just to cherry pick the commits at this point (and what repo it'll eventually live in), but that way it’s a bit more clear what’s going on, if anyone would like to take a look. I’m pretty excited about this particular revision. Ended up with these reports: The last tab (“Quality Settings for JPEG 83”) is the most helpful, I think. It has all of the sizes that WordPress creates by default, at WP’s default JPEG quality, with a suggested WebP closest quality, and percentage of file-size saved for each of the tested images. As mentioned in the last update, I think it still needs at least a line art example to be a bit more definitive, but I like where the report ended up. A note that it takes a long time (hours) to run this particular one, but it’s totally doable to re-run with the images we want / need. |
This is great, thanks for building out this research tool and running initial test sets for JPEG/WebP comparison. Looking at the two results pages for "Quality settings" JPEG 83, I can draw two clear conclusions:
Attaching some screenshots here of those results tabs from the sheets: When possible it would be great run this on a larger set of test images and in particular test some "outliers" that don't compress as efficiently with WebP. |
When I convert high-quality, pre-optimized JPEGs (Lightroom exports) at 2560px wide, the resultant WebP files are often around 30%-50% larger than the original JPEG files. (I convert using |
Hey @markhowellsmead - thanks for the note - how do you upload these images to WordPress and place them in posts? Do you use the "Full sized image" after uploading? How are you creating the WebP images? Can you provide a sample JPEG that you have optimized? |
I export the JPEG from Adobe Lightroom then run ImageMagick's I upload and use the file through the media manager in the usual way and I can use all of the available image sizes, which are all WebP files. Example image files: |
Hey, thanks for providing these examples @markhowellsmead however looking into your WebP example it looks like is actually a PNG image that explains the size of the image. I used your JPEG image and uploaded it to WordPress these were the results after uploading it to WordPress. Take into account that the JPEG images are using a lower quality to compress the image |
Nope, it's definitely a WebP file. Dropbox is either sending the wrong headers or automatically converting the WebP to a PNG. 🤦♂️ Please compare https://dev.permanenttourist.ch/20220328-DSCF1424.jpg and https://dev.permanenttourist.ch/20220328-DSCF1424.webp Update: these files are no longer online.
I'm using quality 82 on the command line to convert the full-sized image to a full-sized WebP file. |
Hey @markhowellsmead could you please upload the original image to this GitHub issue directly? you should be able to just drop it onto the comment box! I'd like to test uploading the original to WordPress to see how it compresses. |
Thank you! I was actually able to reproduce using the JPEG you linked in your last comment. This is the result of WordPress compressing that image locally: Note that the full size image is larger in WebP, but every other size is smaller This validates the need for #186 where we choose the smaller image for every size. Might be especially relevant for the full size image. |
@markhowellsmead thanks so much for providing this sample, this is very helpful. I'm curious if this is the original image from your camera or if you have reduced it already in size. if you reduced it, what compression quality level did you use? Do you get the same results if you use a much higher level (maybe try using 100 for this intermediate image)? I'm also curious to test what happens if you upload your image at a slightly larger size (eg 2500px) so WordPress creates the Also, one question about your workflow - after you upload your images, do you typically place the "Full" sized image in your layouts? what do you use for layouts where you might want a smaller image? |
I'm curious if this is the original image from your camera or if you have reduced it already in size. if you reduced it, what compression quality level did you use?
I exported it from Adobe Lightroom, with a target file size. The application automatically chooses the appropriate compression to achieve the requested file size.
Do you get the same results if you use a much higher level (maybe try using 100 for this intermediate image)? I'm also curious to test what happens if you upload your image at a slightly larger size (eg 2500px) so WordPress creates the -scaled version as the full sized image.
I’ll have to provide that information next week.
Also, one question about your workflow - after you upload your images, do you typically place the "Full" sized image in your layouts?
Rarely, but sometimes. e.g. in a cover block with full alignment.
what do you use for layouts where you might want a smaller image
Not sure I understand that question. Can you be more specific please?
|
Cloudflare does something interesting with its Polish implementation webp_bigger: Polish attempted to convert to WebP, but the image was optimized at the origin server or was created using a low quality setting. Because the WebP version does not exist, the status is set on the JPEG/PNG version of the response. A similar comparison can be done here... if the original file is optimised to be smaller than a webp, keep delivering the original. What do you think? |
A similar comparison can be done here... if the original file is optimised to be smaller than a webp, keep delivering the original.
It makes sense to me and would provide the site visitor with the quickest possible result. But PageSpeed Insights will probably still moan. Imagify’s solution (which delivers an appropriate file on requesting a JPG, according to browser support) would be especially luxurious.
|
I don't think the 'moaning' of a lab tool should be what would drive the evolution, but the user experience. That will be 'ever-green' regardless of how measuring tools change over time. |
This plugin already contains a logic to perform and deliver the smallest file available in case the JPEG one is smaller than the WebP version. |
I don't think we can do this type of request based response directly because WordPress doesn't handle image requests - those are handled by the we web server. A plugin might support some use cases (eg. Apache) but it would be hard/impossible for core to implement given the variety of stacks that run WordPress.
Yea that is the main goal of this work in the first place, so if you place a full size image on your site and the jpeg is smaller than the webp we should serve the jpeg for that size. Pretty sure that is what the plugin does currently, you can test by uploading your example and placing the full sized image. I'll also give this a test.
I'm asking here about your use of images at sizes other than "Full" size. If you use the large or medium size or any other custom size on your site, the generated WebP will still be smaller than the generated JPEG in my testing so far. Which images actually get served to your visitors will depend on many factors including their viewport size (with a srcset) . The Full size image would mainly be used when placed that way intentionally. |
Thanks for the feedback @erikyo. Exporting an optimised JPG will certainly add artefacts, which will then also be present in the resultant WebP file. (An aside: your screenshot isn't the export panel from Lightroom and bears no correlation to the settings or results of my export process.) The goal is to convert this JPG to WebP and that the WebP file should be smaller than the JPG.
I'd overlooked this; thanks. Converting the 755kb JPG without specifying a quality results in a 1.4mb WebP file at 92% quality. (So a secondary degradation when compared to the JPG.) Setting As we've already discussed here, if the site owner were to choose the “full” size when placing the image on the website, then the use of the WebP would cause a massive performance degradation. This is where the WordPress solution has to be intelligent enough to recognise that the JPG file is smaller and, therefore, automatically choose this image instead of the WebP. |
yes but afaik if I can save this file without any quality loss at 55% means the source was saved at that quality. Probably you have checked the flag "limit filesize to [ ]kb" and this has unpredictable results if you need to know the quality of the image.
I hope the goal is to convert the jpg into webp if is worth to do that. Sometimes (as in this case) the resulting webp will be always worst than the jpg (sadly). to get a good result you need a good source image, the best result are with lossless images as source.
This will save the image into a lossless format (4:4:4 like png, tiff etc) and that is the reason for that large filesize (isn't a web optimized format but useful to save source images for example)
I also think that would be nice, and also nice to check the image quality before encode an image into webp to avoid the generation of useless image if is possible, Imagemagick has getImageCompressionQuality() but I haven't found nothing similar in gd. Anyhow the quality is a calculation since isn't saved into image metadata so we can't rely 100% on that function. |
I'm going to take the test images and manually run them through processing with core imagick and gd manually with a couple of different quality settings to see how the resulting sizes compare to the automated runs. |
this is comparing the jpeg compressed image to the webp compressed image, right? In this case I would always expect some dssim difference when comparing them. I wonder we should try comparing a lossless resize of the original to both jpeg and webp compressed versions and look at the dssim vs the original. |
manual testing results: |
ciao @adamsilverstein, In addition, I want to point out that you are right and when we evaluate the SSIM it would be better to compare it with the lossless image (even though the webp is actually generated from the jpg). This way we can assess the generation loss that occurs, whereas otherwise we would not have a real measure of how much was lost in the "double" encoding process, because we need to sum the loss of the jpg encoding and the loss of the webp encoding. |
I took part in the contributors day at WCEU2022 on the core tables and was introduced to the work to move this webp work into core. I come from an ecommerce background with another product, and we have implemented webp for a number of our clients. I installed the performance plugin and tried out a few image uploads, hooking filter_webp_quality to set different quality levels. As pointed out here the default quality level regularly gives bigger webp images compared to the original jpeg. However, our experience is that some clients want to have a high quality level, and others are happier with a lower level. Therefore setting a generic quality level is restrictive, and even setting it via filter makes it difficult for the client to tweak. In addition, the client needs to be able to see their optimised images and compare them with the original, to get a better idea of what is being lost. We've implemented a preview tool that shows the images in the same location in a web page, using arrow keys to cycle through or switch between the original and a compressed image. It's easy to see any differences by switching back and forward. If you set a single fixed quality level with little size advantage, then the feature is basically useless. With our work, we can typically get webp that are more than good enough at under 20% of the original jpeg size. That's worth doing. We're just getting involved with Wordpress so we'll be contributing more. I offered to share our compression comparison tool with the table lead as switching in place is much better than trying to compare images side by side. |
Hi @JosKlever, interesting case... I want to add some additional info about your image for further considerations: identify 2022-05-06-13.00.54.jpg
2022-05-06-13.00.54.jpg JPEG 4032x2268 4032x2268+0+0 8-bit sRGB 3.25165MiB 0.000u 0:00.000
# returns the jpg image quality
identify -format '%Q' img.jpg
92% Just tested locally with stat -c "%n,%s" * | column -t -s,
2022-05-06-13.00.54-100x100.jpg 54315
2022-05-06-13.00.54-100x100.webp 54332
2022-05-06-13.00.54-1024x576.jpg 207498
2022-05-06-13.00.54-1024x576.webp 220734
2022-05-06-13.00.54-150x150.jpg 57611
2022-05-06-13.00.54-150x150.webp 58232
2022-05-06-13.00.54-1536x864.jpg 386996
2022-05-06-13.00.54-1536x864.webp 400934
2022-05-06-13.00.54-1920x1080.jpg 552865
2022-05-06-13.00.54-1920x1080.webp 563588
2022-05-06-13.00.54-2048x1152.jpg 612138
2022-05-06-13.00.54-2048x1152.webp 618000
2022-05-06-13.00.54-400x225.jpg 75579
2022-05-06-13.00.54-400x225.webp 78328
2022-05-06-13.00.54-400x400.jpg 95418
2022-05-06-13.00.54-400x400.webp 101728
2022-05-06-13.00.54-475x267.jpg 85589
2022-05-06-13.00.54-475x267.webp 89046
2022-05-06-13.00.54-600x338.jpg 105891
2022-05-06-13.00.54-600x338.webp 111742
2022-05-06-13.00.54-768x432.jpg 140452
2022-05-06-13.00.54-768x432.webp 150776
2022-05-06-13.00.54.jpg 3409603
2022-05-06-13.00.54-scaled.jpg 871571
2022-05-06-13.00.54-scaled.webp 842840 What we have to think about is that we are comparing an 82% jpg (WordPress has this standard for jpg resizes quality) with the webp resize, and both are generated from the original which is 92%. For this we should carefully evaluate the SSIM of the two results... the quality paramer is just a way of passing settings to the encoder but what we should always take as a reference is the image similarity! So we could do something like this: ("2022-05-06-13.00.54" was renamed to "original" for better understanding) $: convert -quality 87 original.jpg img.webp
$: convert -quality 82 original.jpg img.jpg
$: compare -metric SSIM -verbose original.jpg img.webp res.png
original.jpg JPEG 4032x2268 4032x2268+0+0 8-bit sRGB 3.25165MiB 0.120u 0:00.118
img.webp WEBP 4032x2268 4032x2268+0+0 8-bit sRGB 1.73574MiB 0.230u 0:00.241
Image: original.jpg
Channel distortion: SSIM
red: 0.97622
green: 0.978625
blue: 0.971797
all: 0.975547
$: compare -metric SSIM -verbose original.jpg img.jpg res.png
original.jpg JPEG 4032x2268 4032x2268+0+0 8-bit sRGB 3.25165MiB 0.110u 0:00.117
img.jpg JPEG 4032x2268 4032x2268+0+0 8-bit sRGB 1.80553MiB 0.100u 0:00.096
Image: original.jpg
Channel distortion: SSIM
red: 0.974551
green: 0.977116
blue: 0.969274
all: 0.973647 Seems the webp has a better quality (+0.02 SSIM) with a lower filesize (-0.06 mb) maybe due the different compression method other examples: |
@getsource I was able to track down some additional information about the dssim margin question and why it might need to have a small margin versus the jpeg:
Why have a margin? |
if it possible it would be cool to check also different jpg qualities (50% - 75% - 82% - 90%)... the result will be quite different especially when compared with the original lossless (i.e. the lossless from which the jpg was generated). It is true that jpg is the most uploaded format but what we are interested to is to not loss quality and this loss starts during the first conversion (outside WordPress) so if we decided to double encode images we need to take in account this sum of losses. |
The suggestion you made is how the script is currently intended to work. I agree that a DSSIM between the two compressed images would not be as helpful for this particular purpose. I am double-checking to make sure things are working as I understand / is intended as part of:
This is interesting, thank you! I'll do some followup tests here, since at a first glance it doesn't seem to match the generated results for those images / sizes. |
@adamsilverstein Sorry for the wait on this. I decided to check with uploading the same image (without using the script) to my trunk / docker install with the performance plugin + WebP enabled. The JPEG sizes are similar to the ones in the directory listings you pasted, but the WebP sizes are larger than the ones in the gists you linked, whether I set things to 82 or 90 WebP quality. I'm wondering if it might be due to a difference in configuration of our environments. Would you mind posting the configuration from your test site's Site Health? Here's the info from mine -- it says that the 82 Quality: https://gist.github.com/getsource/9c0fd74123c40c12357116011da98e68 |
My local environment is highly configurable and I regularly change which PHP version and image library I'm testing; unfortunately I didn't record my settings at the time of those tests so I'm not really sure what I had enabled, sorry about that How do the 82 quality images compare to the jpeg versions in your visual estimation, do you notice any difference in the quality? |
@getsource Based on everything so far, I would like to propose using the same default for WebP that we use for JPEG - namely |
Hi @adamsilverstein ! Sorry for the wait here. In the meantime, I thought it'd be helpful to provide my current thoughts. The mean / median in the testing were very close to 82. The image in the tests (a portrait) that required the highest value to match its equivalent 82 JPEG needed a WebP quality of 90. For this image, and similar ones, the quality of the resizes will be lower than it was previously. I like the idea of matching the intent behind WebP's design, but I think we should make sure that aligns with the quality users currently expect from JPEG resizes (Side-wondering: Do you know if that design was based off of resizing from lossless images rather than JPEGs?). I also don't know where 86 came from, but it seems remarkably close to the value required for JPEG resizes into WebP! All of that said, I'm going continue another visual test, like you asked previously, and I'll follow up again. |
Ah, another side-note -- I noticed some of the spreadsheets had "83" instead of "82" in their pivot tables for JPEG quality, so I updated a couple of the more recent ones, so that the data will be more useful for this conversation. |
I was having issues with this as well recently and would up editing core to be "sure" since it is a little hard to tell what level was used.
I'm not opposed to 84, my guess is this would provide slightly better quality images overall vs. jpeg and still remain smaller. at all sizes. I still prefer 82 because it simplifies the default quality logic and I believe result in very similar quality images (that are smaller). I do agree that a slightly higher number like 84 would probably better match the "quality profile" of jpeg at 82, but I'm saying the difference won't be perceivable, especially when comparing against the original image.
The tests compare structural similarity, and when an image is highly detailed WebP has to work harder to match JPEG. Other testing tools such as visually comparing with real users or PSNR (signal to noise ratio) tests might give you different results. I guess my question here is, if you used 82 for WebP on this image, would the difference between webp & jpeg be perceivable?
I believe it came from here: https://www.industrialempathy.com/posts/avif-webp-quality-settings/#quality-settings-for-a-range-of-jpeg-qualities in this chart Malte suggests a WebP quality of 82 to match a JPEG quality of 80 and I extrapolated from there.
perfect, thanks for your continued attention here! |
@getsource - I also experienced this and think it might be a bug - I found the comment where I encountered this issue (and fixed it) - WordPress/wordpress-develop#2393 (comment) that might be helpful |
Rarely, but sometimes. e.g. in a cover block with full alignment.
what do you use for layouts where you might want a smaller image
Not sure I understand that question. Can you be more specific please?
I'm asking here about your use of images at sizes other than "Full" size.
If you use the large or medium size or any other custom size on your site, the generated WebP will still be smaller than the generated JPEG in my testing so far.
That is the ideal situation and clients are taught to choose the appropriate size when adding content to the site. If the full-sized image is set then the performance will be worse, which is expected. If the new feature will choose between the two alternatives (WebP and JPG) for the selected size when the HTML is rendered, I agree that this will be the best solution for performance, if not for measurement tools. (Which should always take second place.)D
|
Thanks for all the lively discussion here! We already resolved this issue in the plugin by setting the quality to Closing this issue as resolved, using 82 here gives us a good way to test/validate making a similar change in core. |
Trac ticket: https://core.trac.wordpress.org/ticket/54356
The text was updated successfully, but these errors were encountered: