So is Firefox doing a full rendering then scaling, or is it also doing a partial rendering but in another way? You're only telling one side of the story.
the8472•Aug 12, 2026
Firefox doesn't decode the image into a full-resolution buffer and then downscale either, instead it does a streaming decode and applies downscaling on the fly. They call it downscale-during-decode[0]. I guess it doesn't do partial decoding of the 8x8 blocks though.
Ah! It took a fair bit of digging to get there. Maybe I'll look into the firefox pipeline and make another post. In the mean time if anyone know the internals and how firefox does it, I'm eager to hear about it!
debazel•Aug 12, 2026
Chrome and Firefox uses two different scaling algorithms that is probably contributing a lot more to this difference. Chrome is more blurry in general while Firefox is sharper but has slightly more ringing artifacts. Personally I prefer the Firefox version.
gutechh•Aug 12, 2026
I do prefer the firefox look too! I'd be curious to hear your take on what could be the root cause of this. I'm far from a image rendering expert. But I remember when inspecting the edges and curves of the images in a DCT visualizer they were all in the AC coefficients which is what led me to the conclusion of the post.
ack_complete•Aug 12, 2026
I wonder if this is a gamma correction related. JPEG encodes directly in a non linear color encoding (full-range YCbCr), so the partial decoding may be effectively scaling without gamma correction.
debazel•Aug 12, 2026
I'm far from an image rendering expert myself, but I don't think there is a single root cause here. I don't doubt the partial decoding would affect the final result just as the scaling algorithm itself, so in the end it's going to be a combination of it all.
The reason I believe the scaling algorithm is contributing more in your particular example, is because it looks almost exactly like a classic B/W comparison between a sharp ringing heavy algorithm and a more blurry one.
It would be interesting to see how your example would look if you used colors instead, where the ringing artifacts become a lot more obvious. Like this one: https://twinlens.app/compare?share=8fb890a5820e
aidenn0•Aug 12, 2026
I've noticed that a lot of objective measures of image quality prefer blur to ringing, but many subjective measurements tilt the other way.
ryandamm•Aug 12, 2026
That's why you should prefer LPIPS to PSNR. LPIPS is a learned metric that uses subjective human input.
That said, it's limited due to the training set, iirc. So we still use PSNR regularly — it's an easily-understood metric with widely-understood limitations, which is in practice not too bad. Devil you know, etc.
smallnix•Aug 12, 2026
Would be nifty if they only did that partial scaling when there's little memory available.
gutechh•Aug 12, 2026
ahah, yeah surprising considering how Chrome is RAM hungry, 20mb isn't that much of a win. On another end when trying to reproduce the glitch, it was quite hard! basically invisible on photos and not all icons were affected. So it does work very well. It was kind of our fault to use a jpg for an icon ahah.
Thanks, I knew it was much more efficient, but seeing the numbers in the benchmarks make me appreciate this "trick" even more!
bluedino•Aug 12, 2026
Reminds me of digging into HTML Canvas scaling, especially when HiDPI Macs came out.
jonathanlydall•Aug 12, 2026
I'm pretty sure the same issue happens with PNGs, which being lossless are generally good for icons as they don't land up with compression artifacts like what happens in JPEGs (which the author points out are really for photographs), they also support alpha blending.
When Chrome introduced this "optimization" and it made it through to an Electron release which we were upgrading to, it really messed up the icons in a lot of places in our product such that we had to hold off the upgrade until we had SVGs to replace them.
SVGs also have the advantage of being able to respond to light/dark mode. We just needed to put each icon in its own shadow DOM to avoid styles clashing between the different SVGs if they happen to be named the same which was a bit of an annoyance for our graphic designer.
StilesCrisis•Aug 12, 2026
You were using bitmap icons that were more than 8x larger on each axis than necessary? Why?
aljgz•Aug 12, 2026
Guess: same icon used in very small size for lists/menus and much larger when you select the item. Also, if the same one is used for all resolutions, the actual size can vary widely between monitor sizes, DPIs, resolutions, scales. Good to have one that looks decent to people who see it large and/or care about quality
gutechh•Aug 12, 2026
Ah this is weird! My understanding is that png doesn't store the images like jpg at all, they use a palette of all the colors in the image. Then each pixel is a reference to this palette. So it's not IDCT scaling, but I imagine there are other tricks to save on space/cpu when decoding pngs.
binaryturtle•Aug 12, 2026
PNG supports both, palette based (for 8 bit and less), and just straight direct/true color (RGB or ARGB).
(still different from JPEG's method, of course)
polpo•Aug 12, 2026
I don't think it's possible to partially decode/render a PNG in a way similar to JPEG. The only exception I can think of is adam7 interlacing, which _does_ store the initial pass as 8x8 blocks, but I'm pretty sure PNGs with adam7 are rare in practice because they do result in larger files.
jancsika•Aug 12, 2026
> We just needed to put each icon in its own shadow DOM to avoid styles clashing between the different SVGs if they happen to be named the same which was a bit of an annoyance for our graphic designer.
What do you mean by "named the same" here?
LoganDark•Aug 12, 2026
Not sure why one would use JPEG for a little digital icon anyway. It is indeed only acceptable for photos. SVG is a good choice for icons, PNG or WebP for other digital content.
gutechh•Aug 12, 2026
Yes! for a bit of backstory, it was an internal icon on a prototype that we were polishing up. So I get why the person did it at the time, running after the svg would have been too much effort for something that might have been tossed in the end.
LoganDark•Aug 12, 2026
I mean it's surprising someone would ever save a digital icon as JPG in the first place rather than something like PNG.
Theodores•Aug 12, 2026
You can over ride lib-jpeg-turbo with the moz-jpeg 'update' if you want much nicer jpeg things going on.
Mozilla wringed out more from JPEG for Meta/Instagram about a decade or so ago, and their library would be noteworthy in this article, for comparison. The basic idea was that JPEG was devised when CPU cycles were expensive and displays were analogue, meaning that only a limited effort was made to optimise, resulting in things like banding, that OG CRTs handled well, unlike modern digital displays (on systems with 1000000 more CPU).
Regardless of what tools you are using, going from 'gigapixels' to a thumbnail is going to be a two or more step process, with a colourful item rendered a grey mush, when you really needed some of the colours in the original.
Few respect the pixel blocks of JPEG (8 x 8) and most graphic artists have no knowledge of the powers of two. Once upon a time it was necessary to align image dimensions with important binary numbers, particularly if working with texture maps for early 3D graphics.
The other thing going on in the article is that practically every web screen should be considered 'retina' resolution, with everything apart from the lamest office PC having a pixel resolution equivalent to 1.5x the amount of pixels shown 'nominally'. If the web stats say '1280 x 720' as a oft-used resolution, regardless of device, that will be a 1920 x 1080 screen at 1.5x, with Chrome and other browsers packing in 1920 rather than 1280 pixels across, if the image has the pixels in it for that.
9 Comments
[0] https://bugzilla.mozilla.org/show_bug.cgi?id=1045926
The reason I believe the scaling algorithm is contributing more in your particular example, is because it looks almost exactly like a classic B/W comparison between a sharp ringing heavy algorithm and a more blurry one.
For reference here is a quick comparison between Lanczos/Bilinear I threw together: https://twinlens.app/compare?share=40973d84a174
It would be interesting to see how your example would look if you used colors instead, where the ringing artifacts become a lot more obvious. Like this one: https://twinlens.app/compare?share=8fb890a5820e
That said, it's limited due to the training set, iirc. So we still use PSNR regularly — it's an easily-understood metric with widely-understood limitations, which is in practice not too bad. Devil you know, etc.
When Chrome introduced this "optimization" and it made it through to an Electron release which we were upgrading to, it really messed up the icons in a lot of places in our product such that we had to hold off the upgrade until we had SVGs to replace them.
SVGs also have the advantage of being able to respond to light/dark mode. We just needed to put each icon in its own shadow DOM to avoid styles clashing between the different SVGs if they happen to be named the same which was a bit of an annoyance for our graphic designer.
(still different from JPEG's method, of course)
What do you mean by "named the same" here?
Mozilla wringed out more from JPEG for Meta/Instagram about a decade or so ago, and their library would be noteworthy in this article, for comparison. The basic idea was that JPEG was devised when CPU cycles were expensive and displays were analogue, meaning that only a limited effort was made to optimise, resulting in things like banding, that OG CRTs handled well, unlike modern digital displays (on systems with 1000000 more CPU).
Regardless of what tools you are using, going from 'gigapixels' to a thumbnail is going to be a two or more step process, with a colourful item rendered a grey mush, when you really needed some of the colours in the original.
Few respect the pixel blocks of JPEG (8 x 8) and most graphic artists have no knowledge of the powers of two. Once upon a time it was necessary to align image dimensions with important binary numbers, particularly if working with texture maps for early 3D graphics.
The other thing going on in the article is that practically every web screen should be considered 'retina' resolution, with everything apart from the lamest office PC having a pixel resolution equivalent to 1.5x the amount of pixels shown 'nominally'. If the web stats say '1280 x 720' as a oft-used resolution, regardless of device, that will be a 1920 x 1080 screen at 1.5x, with Chrome and other browsers packing in 1920 rather than 1280 pixels across, if the image has the pixels in it for that.