demo · v151

Adaptive Image Decoding

High-quality codecs like AVIF and JPEG-XL deliver smaller files but cost CPU on every decode. On a low-tier device, decoding a feed of 30 AVIFs can blow the main thread frame budget. Pick the right format from the CPU tier — and ship a graceful WebP fallback.

Limited availability. navigator.cpuPerformance is a Chrome 151 CPU tier attribute. Use the tier buttons below to simulate any tier; this page reads the real numeric value when available and pre-fills the matching tier.

simulate cpu tier

Read:

decode budget for a 30-image feed

AVIF (best)
probe pending
JPEG-XL
probe pending
WebP
probe pending
JPEG (legacy)
probe pending

The first number is the tier model for a 30-image feed. The measured column wraps performance.now() around img.decode() for codecs the browser can generate locally, then compares that per-image timing against the same 500 ms feed budget.

verdict

code

// Pick image format from CPU tier.
const tier = typeof navigator.cpuPerformance === "number"
  ? navigator.cpuPerformance
  : 2;
const pickFormat = (t) => {
  if (t >= 3) return ["avif", "jxl", "webp", "jpeg"];   // try richest first
  if (t === 2) return ["webp", "jpeg"];                  // skip heavy decode
  return ["jpeg"];                                       // budget device
};

// Emit a <picture> with only the formats this device can afford.
function html(src, alt) {
  const formats = pickFormat(tier);
  return `<picture>` +
    formats.slice(0, -1).map(f =>
      `<source srcset="${src}.${f}" type="image/${f}">`).join("") +
    `<img src="${src}.${formats.at(-1)}" alt="${alt}" decoding="async">` +
    `</picture>`;
}

see also

implementation reference

Need the exact API surface, compatibility boundaries, errors, lifecycle, and source links? Read the matching gendn reference ↗