What does the decoding attribute on an HTML <img> control, and how does decoding="async" differ from loading="lazy"?
answer
- fetch and decode are different steps
- bytes on the wire vs pixels on screen
- sync, async, auto
- a hint the browser may ignore
- matters most for swapped-in large images
basics
~20 sdecoding hints at how the browser turns downloaded image bytes into displayable pixels: async allows that work to happen off the critical path, sync asks for it before the image is presented, and auto leaves the choice to the browser. It never affects when the file is fetched.
solid answer
~50 s`decoding` on `<img>` takes `sync`, `async`, or `auto`, and it is a hint about the *decode* step — turning compressed bytes into a bitmap — not about the download. `decoding="async"` tells the browser it is acceptable to decode without holding up presentation of the surrounding content, so the rest of the page can paint and the image appears when its bitmap is ready. `sync` asks the browser to have the image ready so it presents together with the content around it, which avoids a visible one-frame pop at the cost of possibly delaying that paint. `auto`, the default, means no preference. The contrast with `loading` is the clean way to remember it: `loading` decides **when the bytes are requested**, `decoding` only influences **when the already-fetched pixels are shown**. It is a hint in the honest sense — browsers may ignore it.
go deeper
Know that decoding is about turning downloaded image data into pixels, that its values are sync, async and auto, and that it is unrelated to when the file is downloaded.
Explain fetch and decode as separate steps and place each attribute against the question it answers — loading for when bytes are requested, decoding for when the decoded image is presented — and note that both are hints.
Show judgment about when the hint is worth setting at all: large images swapped in during an interaction, versus ordinary content images where auto is the correct answer and blanket application is noise.
Be ready to argue about where such micro-hints belong at all — whether a shared image component should expose a decoding knob, or default it and spend the team's attention on the levers that move real time.
## Two separate steps Getting an image on screen involves at least two distinct pieces of work: 1. **Fetch** — request the file over the network and receive its bytes. 2. **Decode** — expand those compressed bytes into a raster bitmap the compositor can draw. Decoding is real CPU work, and for a large photograph on a modest device it is not negligible. HTML gives you a separate hint for each step: `loading` governs the fetch, `decoding` governs how the decode is scheduled relative to presenting content. Confusing the two is the single most common error on this topic. `decoding="async"` does not delay, background, or defer the download. The file is fetched exactly as it would have been. ## The three values ```html <img src="photo.jpg" width="1200" height="800" decoding="async" alt="…"> ``` - **`async`** — it is acceptable to decode the image without blocking presentation of other content. The surrounding page can paint first, and the image appears once its bitmap is ready. - **`sync`** — the browser should aim to have the image decoded so it is presented atomically with the content around it. You are asking to avoid a frame where the layout is drawn and this image is not. - **`auto`** — the default. No author preference; the browser decides. All three are hints. The specification lets the browser do what it judges best, and different engines make different calls. Nothing about your page should *break* if the hint is ignored — that is the test for whether you are using it correctly. ## Where it visibly matters The effect is most noticeable with large images that are inserted or revealed rather than present from the start — a full-bleed photograph swapped in for a lightbox, or the next slide of a carousel. With a synchronous decode, the browser may hold the frame until the bitmap is ready, which can show up as a brief stall in an otherwise smooth interaction. With `async`, the update proceeds and the image lands a frame or two later. The flip side is the pop: an image that is decoded asynchronously can appear a beat after the box it lives in. For a page of ordinary content images that is invisible. For a deliberately choreographed transition it can look like a glitch, which is the case where `sync` earns its keep. For the common case — images in the initial HTML of a normal page — `auto` is a perfectly good answer, and reaching for `async` on every image is cargo cult rather than tuning. Say that plainly in an interview; it is a better answer than reciting a blanket rule. ## How it composes with the other attributes The three image-scheduling attributes are orthogonal, and being able to place each one is the point of the question: | Attribute | Question it answers | | --- | --- | | `loading` | Should the file be requested now, or only when it nears the viewport? | | `fetchpriority` | Among the fetches that will happen, how urgent is this one? | | `decoding` | Once the bytes are here, may the decode happen off the critical path? | And `width`/`height` answer a fourth question — how much space to reserve — which is independent of all three. A hero image, for instance, might carry high fetch priority and no `loading` attribute at all; whether it also carries a `decoding` hint is a much smaller decision, and often the right answer is to leave it off. ## Common misconceptions - **"`decoding="async"` loads the image in the background."** No — that is `loading="lazy"`, and even then "background" is the wrong word. - **"It makes images faster."** It moves decode work relative to presentation. It does not shrink the file, speed the network, or reduce decode cost. - **"It is a guarantee."** It is a hint; browsers may decode however they like. - **"`sync` is safer, so use it everywhere."** Blanket `sync` on a page of large images invites exactly the stalls you were trying to avoid. The interview-grade summary is one sentence: `loading` is about bytes over the wire, `decoding` is about pixels on the screen, and only one of them affects whether the request happens at all.
- If decoding="async" does not change the download, what would you expect to observe when you add it?Nothing in the network waterfall — the request timing is identical. The observable difference, if any, is in frame timing: with a large image being swapped in, an asynchronous decode lets the frame proceed and the image lands slightly later, instead of the update waiting on the decode. On ordinary content images the difference is usually imperceptible.
- When would decoding="sync" be the better choice?When a visible pop is worse than a slightly later frame — a deliberately choreographed transition or a lightbox where the image appearing a beat after its container looks broken. You are trading a possible delay for atomic presentation. Applied to a whole page of large images it backfires, because every decode then has a chance to stall a frame.
- Which of these attributes would you reach for first on a hero image, and why?Neither `decoding` nor anything about decode. The first moves are: make sure it is not lazy-loaded, give it intrinsic `width` and `height`, and consider `fetchpriority="high"`. Those change when the bytes arrive and whether the layout shifts. A decode hint is a much smaller lever, and `auto` is usually fine.
saying these in an interview costs you the question
- Says decoding="async" downloads the image in the background
- Uses decoding and loading interchangeably
- Claims the attribute guarantees a particular decode behaviour
- Applies decoding="async" to every image as a blanket optimisation
- Expects decoding to change anything in the network waterfall