Para cualquier cosa más grande que un ícono, no. Incrustar una imagen como data URI en Base64 te ahorra una solicitud de red y te cuesta 33% más bytes, el cache propio, el lazy loading y la negociación de formato. Por debajo de un kilobyte más o menos ese intercambio está bien: un ícono de viñeta, un patrón de fondo, un spinner. Por encima de unos pocos kilobytes, la solicitud que evitaste salía mucho más barata que todo lo que entregaste a cambio.
¿Cuánto más grande hace Base64 una imagen?
Un tercio más grande, redondeando. Base64 gasta cuatro caracteres por cada tres bytes, así que el aumento es un 33% fijo, más el prefijo data:image/png;base64, y hasta dos caracteres = de padding. Un PNG de 12 KB se convierte en unos 16 KB de texto. Eso es aritmética, no una debilidad de algún encoder, y ninguna herramienta va a bajar de ahí. Qué es Base64 en realidad tiene la versión a nivel de bits si la quieres.
La compresión en tránsito devuelve una parte. Gzip y Brotli encuentran algo de redundancia en una string de Base64, así que el tamaño transferido no llega al 133% completo. Pero tampoco vuelve nunca al original, y en un PNG, un JPEG o un WebP los bytes originales ya venían comprimidos, lo que significa que de entrada no quedaba mucho para exprimir. Presupuesta el sobrecosto en lugar de suponer que la codificación de transferencia lo borra.
¿Qué pierdes al incrustar una imagen?
Una imagen con URL propia se descarga una vez y se reutiliza en todas partes. Dale un nombre de archivo con hash y un header de cache largo y un visitante que vuelve no la descarga nunca más, en ninguna página.
La misma imagen incrustada en una hoja de estilos pasa a ser parte de esa hoja de estilos. Cambia un color que no tiene nada que ver, publica un hash nuevo, y cada visitante vuelve a descargar la imagen junto con ella. Si en cambio la incrustas en el HTML, baja en cada visita a la página, porque el HTML normalmente no se cachea en absoluto.
El resto se va con eso:
- Nada de lazy loading.
loading="lazy"no hace nada por bytes que ya están en el documento. Una imagen incrustada que queda fuera de la primera pantalla se paga entera, de inmediato. - Nada de negociación de formato. Un elemento
<picture>sirve AVIF o WebP a los navegadores que los admiten y algo más viejo al resto. Un data URI es una única codificación fija para todo el mundo. - Nada de tamaños responsive.
srcsetes una lista separada por comas y un data URI contiene una coma, así que los dos no se mezclan. El teléfono descarga lo que necesitaba la computadora de escritorio. - Bloquea el primer pintado. Un data URI dentro del CSS se parsea antes de que se renderice nada. Una foto de 200 KB incrustada en una hoja de estilos retrasa el primer pixel en cada página que carga esa hoja de estilos.
- Te arruina los diffs. Una línea de veinte mil caracteres cambia cada vez que cambia la imagen, y nadie revisa esa línea.
¿Incrustar todavía ahorra tiempo con HTTP/2?
Mucho menos que antes. El argumento clásico era la cantidad de solicitudes: con HTTP/1.1 un navegador mantenía alrededor de seis conexiones abiertas por host y todo lo demás hacía fila, y por eso los sprite sheets y los data URI eran el consejo estándar. HTTP/2, estandarizado en 2015 y compatible con todos los navegadores actuales, multiplexa muchas solicitudes sobre una sola conexión. Un archivo chico de más no es gratis —sigue teniendo sus propios headers y su propio trabajo en el servidor— pero ya no bloquea nada más.
Lo que sobrevive es la latencia en la primerísima carga. Una solicitud sigue necesitando un viaje de ida y vuelta, y en una conexión móvil lenta eso es medible. Por eso el único uso honesto que le queda a incrustar son assets diminutos que hacen falta en el primer pintado: no fotografías, no imágenes de portada, nada que llamarías contenido.
¿Cuándo sigue siendo correcto incrustar?
- Assets de menos de uno o dos kilobytes que aparecen en la mayoría de las páginas: un chevron, la marca de un checkbox, un fondo que se repite, un spinner de carga.
- Un archivo que tiene que funcionar sin hosting detrás. Un reporte HTML de un solo archivo que mandas adjunto por correo, un bookmarklet, un demo autocontenido que alguien va a abrir desde su escritorio. No hay servidor del cual traer una imagen, así que la imagen tiene que estar en el archivo.
- Una página offline. Lo que sea que muestre tu service worker cuando no hay red no puede depender de un fetch.
- Cualquier lugar donde no se permita binario. JSON no tiene un tipo binario, así que una imagen que viaja dentro del payload de una API o de un archivo de configuración tiene que ir en Base64. El costo es que el archivo se convierte en una única línea enorme e ilegible.
Fíjate qué no está en esa lista: fotografías, logos de más de un par de kilobytes, cualquier cosa que aparezca en una sola página y cualquier cosa que suba un usuario.
¿Qué tamaño ya es demasiado grande para incrustar?
Codifica el archivo y fíjate qué tan larga queda la string. Esa es toda la decisión. Soltar la imagen en el conversor a data URI de este sitio pone lado a lado los bytes originales, los bytes codificados y el sobrecosto: la cifra codificada cuenta la string completa, prefijo incluido, así que queda un poco por encima del 33% en lugar de justo ahí. Te avisa sin rodeos cuando la string pasa los 100 KB, pero toma eso como el punto en el que incrustar es indefendible, no el punto en el que deja de ser sensato. La tabla es el criterio que la herramienta no aplica por ti. No se sube nada, algo que aquí importa más que de costumbre: un data URI es una copia completa del archivo en texto plano.
| Largo codificado | Qué hacer |
|---|---|
| Menos de 1 KB | Incrústala. La solicitud cuesta más que los bytes. |
| 1–4 KB | Incrústala solo si hace falta para el primer pintado y se usa en la mayoría de las páginas. |
| 4–10 KB | Por lo general déjala como archivo. Que decida un umbral del build y no tú. |
| Más de 10 KB | Déjala como archivo. Estás cambiando el cache por un solo viaje de ida y vuelta. |
Si el número te sorprende, el problema es la imagen y no la codificación. Un ícono de 90 KB no es un ícono. Redimensionarla y comprimirla antes de codificar nada muchas veces responde la pregunta sola, y de dónde sale realmente el peso de una imagen explica por qué las dimensiones importan más que el control deslizante de calidad.
¿Conviene codificar un SVG en Base64?
No, y es el único caso donde la respuesta no tiene nada que ver con umbrales de tamaño.
Un SVG ya es texto. Codificarlo en Base64 le suma un tercio de tamaño sin ningún beneficio y convierte algo legible en ruido. Aplicar percent-encoding solo a los caracteres que romperían un url() de CSS —#, <, >, las comillas— lo deja más corto, lo deja legible dentro de la hoja de estilos y comprime muchísimo mejor, porque gzip encuentra repetición en XML y casi ninguna en Base64. El conversor enlazado arriba cambia solo a percent-encoding cuando le das un SVG, y te avisa que eso fue lo que hizo.
Para un ícono dentro del HTML, mejor todavía: pega el elemento <svg> en sí en lugar de cualquier tipo de URI. Así currentColor funciona, el CSS puede darles estilo a los paths y no hay ningún sobrecosto de codificación.
¿Qué se rompe cuando usas un data URI?
- El correo. Gmail y varios otros clientes se niegan a renderizar una imagen desde un data URI, así que quien lo recibe ve un recuadro roto. Si el destino es una bandeja de entrada, hospeda la imagen y usa una URL normal.
- Content Security Policy. Una política de
img-src 'self'bloquea los data URI de plano. A la directiva hay que agregarledata:explícitamente, y muchos equipos de seguridad no lo van a aprobar, porque amplía lo que puede renderizar una inyección de script. - La búsqueda de imágenes. Una imagen incrustada no tiene URL, así que no hay nada que un crawler pueda descargar ni indexar. Si quieres que la imagen en sí se pueda encontrar, tiene que ser un archivo.
¿Debería decidirlo tu bundler en lugar de ti?
Pegar data URI a mano en el código fuente es la forma en que un repositorio termina con archivos imposibles de revisar e imágenes que nadie encuentra para actualizar. Deja la imagen como un archivo normal y que el bundler la incruste por debajo de un umbral de tamaño: Vite incrusta por defecto los assets de menos de 4.096 bytes, y los asset modules de webpack funcionan igual con un corte similar de unos pocos kilobytes. Los dos te dejan cambiar el número o forzar cualquiera de los dos comportamientos archivo por archivo.
Te queda código fuente legible, sigues teniendo la optimización de los archivos pequeños y hay un solo número que cambiar cuando el ícono se convierte en una fotografía. Una string pegada a mano no te da nada de eso. Además es la versión que se queda años en el repositorio, porque nadie puede saber qué es ni de dónde salió.
Si estás evaluando un archivo concreto y no el caso general, el conversor de imagen a Base64 te da el número que lo resuelve: tamaño original, tamaño codificado y el sobrecosto, sin que el archivo salga nunca de tu navegador.
Y cuando un data URI termina dentro de una configuración JSON o de la respuesta de una API, colapsa el payload en una sola línea que nadie puede leer ni revisar. Formatear JSON minificado es la manera de volver a convertirlo en algo que una persona pueda comprobar.
Preguntas frecuentes
¿Conviene usar imágenes en Base64?
Solo para imágenes de menos de uno o dos kilobytes aproximadamente que aparecen en la mayoría de las páginas, como íconos pequeños y patrones de fondo. Por encima de eso, incrustar cuesta más que la solicitud que ahorra, porque los bytes ya no se pueden cachear por separado, cargar con lazy loading ni servir en un formato moderno. Cualquier cosa fotográfica y visible para el usuario debería seguir siendo un archivo normal.
¿Las imágenes en Base64 cargan más rápido?
Evitan una solicitud de red, algo que importaba con HTTP/1.1 y que importa mucho menos con la multiplexación de HTTP/2. En contra, suman un 33% al tamaño, bloquean el primer pintado cuando están dentro del CSS y se vuelven a descargar cada vez que cambia el archivo que las contiene. Para assets pequeños es una ganancia; para los grandes es una pérdida clara.
¿Cuánto más grande es una imagen en Base64 que la original?
Alrededor de un 33% más grande, más un prefijo corto y hasta dos caracteres de padding. Base64 codifica cada tres bytes como cuatro caracteres, así que una imagen de 12 KB se convierte en unos 16 KB de texto. Gzip o Brotli recuperan parte de la diferencia en tránsito, pero nunca toda.
¿Puedo usar una imagen en Base64 en un correo?
Por lo general no. Gmail y varios otros clientes de correo bloquean los data URI dentro de las etiquetas de imagen, así que quien lo recibe ve una imagen rota en su lugar. Hospeda el archivo y enlázalo con una URL normal, aunque eso signifique que la imagen puede quedar bloqueada hasta que quien lee cargue el contenido remoto.
¿Base64 es malo para el SEO?
Una imagen incrustada no tiene URL, así que un crawler no puede descargarla ni indexarla y no va a aparecer en la búsqueda de imágenes. Además le suma peso al HTML o al CSS que tiene que llegar antes de que la página se renderice, lo que afecta las métricas de carga. Para un ícono decorativo de 500 bytes ninguno de los dos puntos importa; para la foto de un producto, los dos.
¿Conviene codificar un SVG en Base64?
No. Un SVG ya es texto, así que Base64 lo hace un tercio más grande, ilegible y más difícil de comprimir. En su lugar, aplica percent-encoding a los pocos caracteres que rompen un url() de CSS, o pega el elemento SVG directamente en tu HTML para que el CSS le pueda seguir dando estilo.
Última actualización 19 de septiembre de 2026