JXL – JPEGXL and the web experience here.

Addressing the JXL or JPegXL format floating around the internet.

We’re going to do something we usually do not do for ANY of our blog articles. We’re going to purposefully STOP all optimization of our files in this entry and only use ONLY PNG files (Blog article only, navigation, footer, and backgrounds will still be processed. It may sound totally counter productive to do when making an article about a new format that the developers insist that you use. However, in order to graphically demonstrate my points about the “New kid on the image war block” we must go totally lossless with a codec we trust and has been proven for almost 20 years.

Now, for those users running nightly builds of Chrome or Firefox that want to test out JXL Good news! Every article EXCEPT this one is already encoded thanks to scripting mentioned on this blog article. So once you’ve enabled JXL in your browser (details described below) you can explore this site with it and see if it’s really all of the hype it’s meant to be!

Read on if you care about my rants and opinions of this format.

Faster, harder, stronger…… Right?

CanIUse JXL as of 09/23/2021

When we first heard of this new image format which is under consideration for release in browsers at the time of this posting under CanIUse. As a blogger who loves tech and the general art of speeding up how a website and its content is delivered to you the user.

Fuck yeah, sign me up. – S

I setup my scripts to do the batch conversion process of all of the images on s-config.com (Except this article, of course.)

Testing JpegXL/JXL for yourselves.

At the time of this blog article only nightly builds support JXL and it has to be enabled by the end-user.

Google Chrome.

At the time of this posting JXL is not available in the main chrome distributive file but in Google Chrome Canary, which is a nightly build of Google for people to test out new features like JXL in.

Once you have installed this version you can simple type into the address bar:

chrome://flags/#enable-jxl

Google Chrome Canary Enabling JXL

And you will be presented with a window like the one posted above. Simple click the drop-down box for JXL support and enable it. then, you could clear your browser cache and cookies and load up our site again and suddenly my NGINX server will start to server you JXL files.

Firefox Nightly

You can download the nightly beta from firefox and even select ‘custom’ so it does not overwrite your existing Firefox installation if it is your main browser. Remember to download the nightly edition and not the beta edition!

Type in the following into the address bar:

about:preferences#experimental

Firefox Nightly Enabling JXL

and from here a window like the one above will appear allowing you to check the box to enable JXL Media.

Microsoft Edge Canary.

Unlike Google Chrome you have to modify the shortcut for the “Canary” version of Edge! Download is here! Not the regular one. Then, you modify the shortcut of the executable with the following command.

--enable-features=JXL

Enable Shortcut JXL for Microsoft Edge Canary

Just like how it appears in the window above. Except once again, you will be doing this to “Canary” and not your regular Microsoft Edge as the regular edition will do nothing.

Disclaimer time.

We’re not software engineers or graphic arts experts. We’re users and readers just like 99 percent of you out there. The only thing we did a little different is we have our own server to deploy this. As such, take whatever information you find here as opinion. Any scripting or commands that mention you do at you own risk! Always check your code. Any modification you make to your software is your own responsibility as well and s-config.com will not be held liable for any damages.

Test 1: 15 color PNG with transparancy.

In just about every blog we’ve seen the story is unchanged. They claim massive Benefits over JPG pictures which are typically high color with millions of colors. Fair enough. But what about a low-fidelity PNG file? After all if JXL can work wonders with millions of colors it should have no problems with just a few in a locked pallet right?

Binturong-Logo 15 colors plus transparancy.

We’re attaching my 512×512 FavIcon logo that is normally saved in .SVG format. I took the vector and output to raster at 512px-512px 4-bit color. 15 colors + transparency just to make things interesting.
after optimizing with optiPNG, and passing it through my script. Here is the results.

-rw-r--r-- 1 user group 13830 Sep 22 01:14 Bintu-Logo-2.png.webp
-rw-r--r-- 1 user group 15344 Sep 22 01:12 Bintu-Logo.png
-rw-r--r-- 1 user group 20317 Sep 22 01:12 Bintu-Logo.png.avif
-rw-r--r-- 1 user group 80540 Sep 22 01:19 Bintu-Logo.png.jxl
-rw-r--r-- 1 user group 10643 Sep 24 19:28 Bintu-Logo.png-2.jxl
-rw-r--r-- 1 user group 31510 Sep 22 01:15 Bintu-Logo.png.webp
-rw-r--r-- 1 user group 21370 Sep 22 01:21 Bintu-Logo.svg

  • So, my original vector weighs in at around 21KB for Bintu-Logo.svg which isn’t bad and it was designed in InkScape 0.9.0.
  • My 4-bit PNG Bintu-Logo.png is coming in at 15KB! Using OptiPNG version 0.7.7.
  • My WebP Bintu-Logo.png.webp is coming in at 31KB! Double the size using the flags -q 85 -m 6 -pass 10 -o. Using CWebP version 1.2.0
  • AVIF Bintu-Logo.png.avif cannot beat PNG and comes in at 20KB using flags –min 0 –max 63 –minalpha 0 –maxalpha 63 -a end-usage=q -a cq-level=18 -a tune=ssim -s 0 -j 1 also using CWebP version 1.2.0
  • JXL Bintu-Logo-png.jxl comes in at a horrific 80KB! Flags passed are -q 85 -e 9 -p Using cjxl Version 0.7.0 95cb570
  • JXL Bintu-Logo-2.png.jxl – comes in at an excellent 10.6KB ! Flags passed are -d 0.0 -e 9 -p Using cjxl Version 0.7.0 95cb570
  • The only one that could possibly dethrone my 4-bit PNG was a different WebP at 14KB. And that’s only because of the -near_lossless 40 flag that does not work all of the time! Espechally on pictures! Even with smalled PNG files such as system icons that flag sometimes does not stand a chance.

Now, just like WebP. Different algorithms must be deployed in order to work with limited palette images and JXF. In this case actually setting the JXF lossless with the -d 0.0 flag destroyed AVIF while still making the image look great! This is awesome!

Also note that we discovered the -p flag was pushing up the size of some of our JXLs. We will be removing it from the files on our site and will see what happens.

Animated GIFs anyone?

Cherry MX Red Animation Test.

Cherry Red keyboard animation!

-rwxr--r-- 1 user group 111374 Sep 23 03:48 Cherry-MX-Red.gif
-rwxr--r-- 1 user group  97014 Sep 23 03:48 Cherry-MX-Red.gif.apng
-rw-r--r-- 1 user group  13371 Sep 23 03:48 Cherry-MX-Red.gif.avif
-rw-r--r-- 1 user group 450947 Sep 23 03:50 Cherry-MX-Red.gif.jxl
-rw-r--r-- 1 user group 100912 Sep 25 02:27 Cherry-MX-Red-d0-no-p.gif-.jxl
-rw-r--r-- 1 user group 106052 Sep 23 03:48 Cherry-MX-Red.gif.webp

Every codec has varying success rates based off of our optimization script EXCEPT for JXL! Which exploded the file to 4 times its original size using lossy -q 85 ! And 2x its size using lossless -d 0.0 . However! If you drop the -p progressive flag. it comes in at 6k lower then the original GIF! Which hey! At least it’s something!

We begin to question if perhaps we’re doing something wrong? Is there a command we’re supposed to set like what we discovered with WEBP where playing with the -near_lossless flag improves performance? Sadly, we found nothing in the cjxl encoding manual.

So, JXL cannot replace certain 8-bit PNG’s from 1995 nor can it replace GIFS from the 1980’s. There’s a few things going on here.

First, the way GIFs optimize themselves is via subtractive imaging. That it keeps what pixels have not changed, and moves what pixels have changed in order to maintain a low filesize. JXL doesn’t really work like that.

Second, AVIF is piggybacking onto the AV1 standard to produce high compression files off of an already established video codec. Which is why in my script we have to go through a lot of loopholes to make an AVIF animation such as convert GIF to Y2M with FFMPEG and THEN bring it into AVIF! So, from a user friendly standpoint AVIF kind of sucks to work with. But AVIF won this round in terms of animated image compression.

S, JXL is supposed to replace JPEGs! Compare it to the right codec!!!

Okay! bare in mind we cannot put complete allegiance to JXL as there’s times where regardless of algorithm PNG sometimes beats it (very rare! But it does happen!) Thanks to the newly discovered -d 0.0 flag it’s certainly a positive step!

JPG to JXL conversion.

Okay! We’ll compare our sample-set we’ll be using titles off of our website because in many cases they were saved as a jpg with a quality of 80. If you drill down to the pixel level on the original JPG you will of course find artifact distortion. Which is actually common for a website! But it’s a real-world scenario as web-admins like us will be doing the same to migrate away from old standards and onto the new.

-rw-r--r-- 1 user group 132142 Sep 23 04:06 YouTube-Monopoly-title.jpg
-rw-r--r-- 1 user group 39452 Sep 23 04:06 YouTube-Monopoly-title.jpg.avif
-rw-r--r-- 1 user group 36505 Sep 23 04:06 YouTube-Monopoly-title.jpg.jxl
-rw-r--r-- 1 user group 111140 Sep 25 18:51 YouTube-Monopoly-title-d0.jpg.jxl
-rw-r--r-- 1 user group 63560 Sep 25 18:51 YouTube-Monopoly-title-d1.jpg.jxl
-rw-r--r-- 1 user group 60542 Sep 23 04:06 YouTube-Monopoly-title.jpg.webp

Now because we’re playing with a legit 8-bit/channel jpg. JXL starts to shine, blasting away WEBP and even pushing past AVIF!

Side-by-side image comparison.

Image Comparison between AVIF, JXL, Original JPG, WebP

Each of the images were decoded BACK to PNG files using their native conversion program for making the file in the first place. dwebp, djxl, and decavif. Then, they were merged using a graphic program and saved as a lossless 24-bit PNG for you the reader to look at.

JPG

While the YouTube-Monopoly-title.jpg is not fantastic, as you could tell by looking at the YouTube Logo on the monopoly board as well as the demonetized logos. It’s perfect because this would be your typical image that JXL would be converting for website operators.

WEBP

With WEBP the differences are subtle but some edge dithering is present around the monopoly board. Overall it did a good job retaining the quality while giving us a 50 percent gain over JPG.

AVIF

It gets super-interesting! Because AVIF subtracts detail in order to achieve a better encode. It inadvertently cleaned up the JPG artifacts from the original file! Although the explosion dulled a little in the AVIF. It did result is a very small file size at 39KB.

JXL

In order to test this out more. I’ve re-ran this test several times passing out different flags.

Quality compression mode -85

You’ll see the JXL actually made it MUCH WORSE with the 85 quality level! Meaning that when it comes to ‘quality’ JXL is using a different scale then native JPG.

On the up-side! File size quality is crazy-low for a quality 85 encode and beats AVIF!

Distance / MaxError -d 0.0

This is the command to make a JXL mathematically lossless. Which is impressive in respects that doing this in PNG would result in a 450KB file. And yet, it STILL beats JPG -q80 by 21KB. So, if you’re a web-admin who wants to be ultra-conservative with converting your entire site to JXL. Using -d 0.0 is the way to go!

Distance / MaxError -d 1.0

This is what is described as ‘visually lossless’ or perhaps a quality 95 scale? Either way it goes it comes in at 63KB which is only 3KB higher then WebP in our test example. Which is very good! When we looked at it ultra-close (We are talking pixel by pixel here kids) the only thing that’s slightly noticeable is the JPG artifacts that were already there getting messed with a little more. Which is that’s the worst that happens then JXL lives up to its statement of ‘visually lossless’

Encoding time.

We don’t really care. We didn’t bother to measure it. Sure, cjxl is rather fast when it comes to encoding a file. Of course much faster then AVIF being the slowest in some cases taking almost a minute to encode. (Or 5-10 minutes for that animated GIF above.) But at the end of the day is that really important? I have a multi-core VPS that idles at 5-10 percent most of the day. With the way the Cron.daily file works is you have 24 hours to make the very best file. To me encode time is irrelevant as the end-result is everything. Is it small? Does it look good?

We did find out that if you add the command –num_reps=XX to cjxl that it’s supposed to give you a better file. So in our script we set it for 16 reps just to give our VPS something to do!:)

Download softwareDownload these files.

I have provided a link to our images we used in this article file so that you may download it and compare yourself just in case you think we’re pulling the file-size numbers out of our ass. You can also check my data too! The file was compressed with 7-zip to save space and also includes the following files:

JPegXL JXL Logo.Final thoughts.

We are also well aware thanks to jpeg.info that it’s resolution can go up to 1-billion which no other codec can do! But what’s that going to do for me the web-administrator really? Do we really have the technology to edit a 1-billion by 1-billion pixel picture? Is there such a beast online as a 1-billion by 1-billion picture to test the limits of both browser and codec?  We would find it difficult to really trust JXL in lossy with that level of data and would ultimately choose the lossless flags and deal with bigger file-sizes. Even with a larger file size it at least won’t be as stupid large as 90’s encoding technology such as JPEG.

We will even admit that we did not test out HDR 10-bit/channel functionality or if it can really go up to 32-bit/channel color. We feel there’s photography blogs which will probably dive into that aspect immediately for lossy and lossless encoding of such files. After all, we feel all the new generation codecs are attacking the photography world for dominance which is why they’ll most certainly do better then codecs from the mid-90’s.

If you go to their site they talk about making artwork off of the JXL library which produces very large and colorful abstract art pieces for only several bytes of data. And as impressive as that may be the practical use for website presentation is a little lacking. Perhaps using the JXL art generator for hyper-efficient user-icons? Or placeholder images for blogging? Just some ideas we guess! They’re at least cool to look at so go check them out!

S-Config Homepage with JXL on Google Canary.

Finally, unlike just about every blog we’ve read. We’re not here to give you some fluff piece about JpegXL and walk away. We are using it! Right now! Run a VPS and got Nginx? you can use it too by setting up a CRON.Daily job like we did in this article! Once you get Google Canary rocking. go to the home page and smash that “F12” button. Clear out Cache and Cookies and reload that bad boy and watch the JXL’s come at you. The next question is, will we keep JXL as the first file to try during decoding out blog files?

The answer is:

Yes….. For now! – S

It will only affect nightly releases and we feel it’s important for users to test new standards out. JXL still feels like it needs to work out some of the defects happening when mapping high quality lossy files. It’s a coin toss if JXL remains my script or AVIF, then WebP and finally the 1990’s standards.

Special thanks.

We’d like to thank commenters BlueSwordM and Fabulous Monkey for setting us straight on limited palette JXL files with the quickness by using lossless encode. Never really put ‘lossless’ together with ‘great for limited colors’ but hey. The more you know! Please understand that this is a developing technology. As such we may not have all of the information to carry out the decision right away. In fact at the time of publishing this article new information has arrived which will allow us to test again.

Until next time, may server protect you!

+++END OF LINE!

5 thoughts on “JXL – JPEGXL and the web experience here.

  1. Hello S-Config. I hope you are doing well today.

    I just have some feedback regarding the article methodology itself:

    1. For the 1st 15 color PNG with transparency, it would be better to use the lossless mode of JXL, as it performs much better in this kind of image than the normal lossy varDCT mode.
    In fact, for any type of image with simple colors, shapes and graphics, it is better to always use CJXL in lossless mode as it performs better in the types of images we use PNG for anyway(lossless is activated by using -d 0.0)

    2. The animation itself presents an interesting scenario in itself: AVIF will of course perform better since it can use its video coding tools to work its magic, as expected, and WebP lossless/APNG lossless have special modes which have good animation efficiency(lossy WebP isn’t very good for these types of animations, and lossless is usually better). JXL lossy performing poorly is also expected, with lossless performing well, but not much better than the GIF one due to its subtractive nature(JXL can do some sort of inter-coding, but its toolset hasn’t been activated yet).

    3. One of the defining features of JXL is that lossless transcoding of JPEGs can be done, which means for any JPEG source, using that mode is an excellent idea to get more efficiency from storing JPEGs and as such, is the main mode I’d use for already well compressed JPEG encoded images(lossless transcoding of JPEGs is activated by default).

    Reply
    • Hey, thanks for the feedback on this.

      for issue number 1. It sounds like I need to run comparisons with PNGs similar to how I treat PNG<->WEBP conversion then. Cool! It looks like Bintu-Logo.png compresses down to 10.6kb like what Fabulous Monkey was doing with that -j 0.0 flag! Thank you very much! I’ll re-run the script tonight throughout my site to perform size comparisons between my old cjxl and new with lossless. Thanks so much on this! I’ll be sure to revise this article!

      For scenario number 2. I’d like to try to run a comparison on the same level as what i do with AVIF . If the cjxl command supported y2m video like what I’m doing in the script (realistically I’m doing doing that because AVIFENC cannot support GIF encoding out the gate.) I would be happy to pass it through that to give it the same advantage that AVIF is getting.

      Now for issue number 3. You are right, quality remains perfect with lossless jxl. but the size of the file is 111kb. Which granted! It’s smaller then the original JPG! But it did get a lot bigger then the 36kb lossy -q 85 one.

      Anyhow, thank you for checking out my blog! I will re-run my compression for my site tonight!

      Reply
    • I was not able to open the 7z.. having some problems with it. But looking at the descriptions I’m guessing you’re running cjxl lossless then?

      Reply
    • Hello Fabulous Monkey,

      It looks like another commenter filled me in on using the -d 0.0 lossless for indexed palette PNG files. Which is perfect! It produced the same size you were getting. I’ll re-run the script tonight by doing a size comparison between -d 85 and -d 0.0 in an attempt to get the best of both worlds.

      Reply

Leave a Comment to the Void