What a data URI actually buys you
Normally an image is a separate file: the browser requests the HTML, parses it,
finds an <img> tag, and fires off a second request to fetch the
picture. A data URI skips that second trip entirely by encoding the image's raw
bytes as text and putting them directly in the HTML, CSS or JSON — the browser
already has everything it needs the moment the first request finishes.
That trade is worth making for small, frequently repeated assets: a favicon-sized icon, a logo mark, a one-color placeholder, a tiny background texture. It stops being worth it as the image grows, for a reason that has nothing to do with encoding and everything to do with caching.
The size cost, and why it compounds
Base64 encodes every 3 bytes of the original file as 4 text characters. That is a fixed, unavoidable 33% size increase before any compression is considered — a 30KB icon becomes roughly 40KB of text. On its own that is a manageable cost for a small file.
The bigger issue is caching. A normal image file is fetched once and stored by the browser; every other page that uses it loads instantly from cache. A data URI is baked into the HTML or CSS itself, so it gets re-downloaded, re-parsed and re-decoded every single time that HTML or CSS loads — there is nothing separate for the browser to cache. Inline a 200KB image and you have not saved a request, you have made every page load 260KB heavier with no way to avoid it.
A rough rule that holds up in practice: inline it if the file is a few kilobytes and used once or twice. Link to it normally the moment it is either large or reused across many pages.
Four formats, four different jobs
| Format | Looks like | Use it when |
|---|---|---|
| Data URI | data:image/png;base64,iVBOR... | Anywhere a URL is expected |
| Raw Base64 | iVBOR... | Your own code builds the header itself |
| CSS background-image | background-image: url("data:..."); | Pasting straight into a stylesheet |
| HTML img tag | <img src="data:..."> | Pasting straight into a page |
The data URI is the complete, self-contained value and the one most tools expect
by default. Raw Base64 exists for the cases where a config file, an API payload or
your own code already knows the MIME type and just needs the encoded bytes without
the data:image/png;base64, prefix repeated everywhere.
No quality is lost
Base64 is a text encoding of the exact original bytes, not a re-compression step. Decoding it reproduces the identical file, bit for bit, so whatever quality the source image had going in is exactly what comes out the other end. The only change is representation — binary bytes become a string of 64 printable characters — not content.
Nothing is uploaded
The encoding happens entirely inside your browser via the standard FileReader API. The file is never sent to a server, which matters when the image is from an unreleased design, a private project, or anything else you would rather not route through a third party just to get a text string back.