HN Debrief

Why tiny JPEGs look different in Chrome

  • Web
  • Graphics
  • Browsers
  • Performance
  • Developer Tools

The post digs into a small but very visible rendering quirk: a JPEG shrunk to icon size looked different in Chrome than in Firefox. The author tied it to Chrome using partial JPEG decode for aggressive downscaling, which can effectively throw away higher-frequency detail early and change the final look. People filled in the missing browser internals. Firefox is not doing a naive full decode and then scaling either. It uses downscale-during-decode, while Chrome's JPEG path leans on the 8x8 DCT structure more directly for speed. That made the comments land on a broader point than the original bug hunt. Browser image pipelines are full of performance shortcuts, and those shortcuts show up most on tiny UI assets, line art, repeated patterns, and high-contrast edges, not on normal photos where the optimization is usually invisible. The practical consensus was blunt: JPEG is the wrong format for icons, browsers also differ in their resampling choices, and even lossless formats can still look bad if you hand the browser a huge bitmap and ask it to crush it down. SVG came up as the cleanest fix for icons because it survives DPI and zoom changes better, though inline SVG can create its own DOM style and ID collision problems if you do not isolate it.

If image quality matters in UI, stop relying on browser defaults to rescue oversized assets. Ship vector icons where possible, provide raster images near their display size, and test cross-browser rendering at real zoom and DPI settings before rollout.

Discussion mood

Interested and mostly positive. People liked the reverse engineering, but the dominant reaction was that the browser behavior is understandable and the real mistake was using JPEG or oversized bitmaps for tiny UI graphics in the first place.

Key insights

  1. 01

    Firefox also downsizes during decode

    Firefox is not taking the expensive 'decode full image then shrink it' path. It already has a downscale-during-decode pipeline, and Mozilla is also adding lower-scale JPEG decompression work, so the difference here is not 'optimized Chrome' versus 'unoptimized Firefox'. It is two different optimization strategies with different quality tradeoffs.

    Do not assume one browser is doing the obvious reference implementation. If rendering differences matter to your product, test the actual browser pipelines you ship against rather than reasoning from first principles.

      Attribution:
    • the8472 #1
    • muizelaar #1
  2. 02

    Resampling choice may matter more

    The visible gap may be driven at least as much by the scaler as by partial JPEG decode. People pointed out that Chrome looks blurrier and Firefox sharper with more ringing, which matches familiar tradeoffs between faster and sharper filters. The side discussion on PSNR, LPIPS, and FLIP reinforced the same point. 'Better' image quality depends on the artifact people notice first, and engineering metrics do not settle that for UI assets.

    When you compare browser output, separate decode-path effects from scaling-filter effects. If a pixel-perfect result matters, precompute thumbnails with your own chosen filter instead of accepting whatever the browser or GPU picks.

      Attribution:
    • debazel #1
    • aidenn0 #1
    • ryandamm #1
    • m-schuetz #1
    • Theodores #1
  3. 03

    Partial IDCT can expose broken JPEG edges

    Downscaling during JPEG decode can surface encoder sloppiness that full-size decode hides. Some JPEGs leave garbage or zeros in the unused rows or columns of the final MCU, and full decode simply crops that away. Partial IDCT scaling blends those bad edge samples back into visible pixels, which explains why only some files show ugly artifacts.

    If a browser bug seems file-specific, inspect the source JPEG before blaming the renderer. Re-encoding or cropping a few edge pixels can fix production assets without waiting on a browser change.

      Attribution:
    • adzm #1
  4. 04

    SVG fixes scaling but adds isolation work

    Switching icons to SVG solved the quality problem for one product across dark mode, zoom levels, and mixed DPI displays. The catch was operational, not visual. Inline SVGs exported from tools like Adobe Illustrator reused class names and element IDs, which caused icons to style each other unless each one lived in its own Shadow DOM or had its identifiers rewritten.

    Moving to SVG is not just an asset-format change. Budget time for a sanitizing or namespacing step in your icon pipeline, especially if designers export raw SVGs into a large app.

  5. 05

    Browser scaling is not a stable contract

    People stressed that browser downscaling is a performance feature, not a quality guarantee. The algorithm can differ by browser and even by GPU path, and CSS knobs like `image-rendering` only help in some cases because filters that look good on photos often smear line art. That makes browser resizing acceptable for ordinary web content, but unreliable for UI elements where tiny differences are obvious.

    Treat browser image scaling as approximate. For logos, icons, and other sharp assets, ship the right size or use vector art instead of hoping CSS and the browser rasterizer will converge on the same answer everywhere.

      Attribution:
    • kccqzy #1
    • gwittel #1
    • bawolff #1 #2

Against the grain

  1. 01

    PNG is a separate issue

    The claims that Chrome was doing the same trick to PNGs did not hold up. PNG does not support the same kind of partial block decode as JPEG, aside from rare Adam7 interlacing cases, so similar-looking quality problems with PNG are more likely ordinary scaling-filter differences than a decode shortcut.

    Do not generalize a JPEG-specific explanation to every image format. When debugging browser rendering, separate decode behavior from resize behavior before you pick a fix.

      Attribution:
    • polpo #1
    • bawolff #1
    • binaryturtle #1
  2. 02

    ICO may still be useful

    For tiny fixed-size assets around favicon scale, ICO was suggested as an ugly but practical container because it can bundle multiple raster sizes. That sidesteps some browser downscaling problems by letting the browser pick a closer native size instead of crushing one oversized bitmap.

    If you are stuck with raster-only assets at a few known tiny sizes, a multi-resolution container can still be a valid workaround. It is clunky, but better than shipping one giant source and trusting resampling.

      Attribution:
    • altairprime #1

In plain english

Adam7
An interlacing method for PNG that stores image data in multiple passes so a rough preview can appear before full decoding.
DCT
Discrete Cosine Transform, the JPEG compression technique that represents image data as low- and high-frequency coefficients in 8x8 blocks.
DPI
Dots per inch, commonly used as a shorthand for display pixel density.
favicon
The small icon a browser shows for a website in tabs, bookmarks, and other UI surfaces.
FLIP
A perceptual image-difference metric used to compare rendered images in a way meant to align with what people notice visually.
ICO
A Windows icon file format that can store multiple icon sizes and color depths in one file.
IDCT
Inverse Discrete Cosine Transform, a mathematical step used when decoding JPEG image blocks back into pixel values.
image-rendering
A CSS property that lets developers hint how the browser should scale images, such as smoothing or preserving hard pixel edges.
JPEG
A lossy compressed image format designed mainly for photographs, where some detail is discarded to reduce file size.
LPIPS
Learned Perceptual Image Patch Similarity, a machine-learned metric intended to better match human judgments of image similarity.
MCU
Minimum Coded Unit, the basic block group a JPEG encoder and decoder process, often involving 8x8 pixel blocks.
PNG
Portable Network Graphics, a lossless raster image format commonly used for graphics, icons, and images that need transparency.
PSNR
Peak Signal-to-Noise Ratio, a numeric measure of how different a processed image is from a reference image.
Shadow DOM
A browser feature that gives a component its own isolated DOM subtree so its styles and IDs do not clash with the rest of the page.
SVG
Scalable Vector Graphics, an XML-based image format that describes shapes mathematically so they can scale cleanly without pixelation.

Reference links

Browser implementation references

Image quality and rendering examples

Format support and specs

  • Wikipedia: Favicon
    Referenced to explain the messy modern favicon size landscape and inconsistent browser selection behavior.
  • Can I use: AVIF
    Referenced to argue AVIF support is now broad enough to consider over JPEG.

Background references