Quizás haya oído hablar de los URI de datos. Es una forma realmente agradable de incluir un recurso que de otro modo habría sido una solicitud HTTP separada. El formato que usa en un URI de datos puede variar. Básicamente, solo dígale qué tipo de contenido es (p. Ej. image/png
), punto y coma, luego los datos de ese archivo.
Me gusta:
<img src="https://css-tricks.com/probably-dont-base64-svg/data: ...">
o:
.bg {
background: url("https://css-tricks.com/probably-dont-base64-svg/data: ...");
}
Para una imagen rasterizada como PNG, los datos de esa imagen deben estar en formato base64. No soy un gran experto aquí, pero hasta donde tengo entendido, base64 es seguro para usar en algo como HTML o CSS porque solo usa 64 caracteres que se sabe que son seguros en esos formatos.
A la izquierda, los datos de un PNG, que incluye caracteres que tienen el potencial de estropear HTML. A la derecha, esa misma imagen codificada en base64 con todos los caracteres seguros.
Probablemente una mejor respuesta de desbordamiento de pila de Dave Markle:
Nunca se sabe: algunos protocolos pueden interpretar sus datos binarios como caracteres de control (como un módem), o sus datos binarios podrían estropearse porque el protocolo subyacente podría pensar que ha ingresado una combinación de caracteres especial (como la forma en que FTP traduce los finales de línea ).
Entonces, para evitar esto, la gente codifica los datos binarios en caracteres. Base64 es uno de estos tipos de codificaciones.
Base64 parece un galimatías y, a menudo, asociamos el galimatías con la compresión en la web. Pero este galimatías no es compresión, en realidad es un poco más grande que el original porque, para citar a Jon Skeet en el mismo hilo de Stack Overflow:
Se necesitan 4 caracteres por cada 3 bytes de datos, más potencialmente un poco de relleno al final.
Sin embargo, no estoy seguro de cómo influye gzip. Pero a lo que me refiero aquí es a cómo influye SVG en esto.
También puede usar URI de datos para SVG.
<img src="data:image/svg+xml; ... ">
.bg {
background: url('data:image/svg+xml; ... ');
}
Para SVG, no es necesario convertir los datos en base64. Nuevamente, no soy un experto aquí, pero creo que la sintaxis SVG simplemente no tiene caracteres locos. Es XML como HTML, por lo que es seguro de usar en HTML.
Puede dejar la codificación en UTF-8 y soltar la <svg>
sintaxis allí mismo! Como esto:
<img src="data:image/svg+xml;utf8,<svg ... > ... </svg>">
.bg {
background: url('data:image/svg+xml;utf8,<svg ...> ... </svg>');
}
Entonces, debido a que podemos hacer eso, y sabemos que base64 a menudo aumenta el tamaño, ¿podríamos hacerlo bien? Sí. Como beneficio adicional, el <svg>
la sintaxis dejada solo hace gzip mejor, porque es mucho más repetitivo que base64. Supongamos que desea dos versiones de un icono, una roja y otra amarilla. Puede usar la misma sintaxis SVG duplicada, simplemente cambie el color de relleno. Gzip se lo comerá en el desayuno. Gracias a Todd Parker por ese consejo, y ese es también el enfoque de Grunticon, que registra el SVG de URI en UTF-8 en CSS.
Una prueba
Para probar esto, descargué tres íconos SVG de IcoMoon.
cog.svg – 1.026 bytes
play.svg – 399 bytes
replay.svg – 495 bytes
Los ejecuté a través de SVGO solo para que estén muy bien optimizados y listos para usar como un URI de datos (se eliminan los espacios en blanco, aunque supongo que no es estrictamente necesario).
cog.svg – 685 bytes
play.svg – 118 bytes
replay.svg – 212 bytes
Luego los ejecuté a través de un convertidor base64.
cog.svg – 916 bytes – 133% del tamaño original
play.svg – 160 bytes – 136% del tamaño original
replay.svg – 283 bytes – 134% del tamaño original
Entonces eso tiene sentido, ¿verdad? Si son 4 caracteres por cada 3 bytes, eso es un 133% más grande, con la variación proveniente de longitudes desiguales y, por lo tanto, del relleno.
De todos modos, tal vez todo esto sea super obvio. Pero me parece que si va a usar un URI de datos para SVG, no hay razón para usarlo en base64.
Felicitaciones a Matt Flaschen por su correo electrónico de hace unos meses que destacó este problema para mí.
ACTUALIZACIÓN: en IE
En los comentarios se habla mucho de que IE 10/11 / Edge no admite esto. Lo hace, es meticuloso. Aquí hay un caso de prueba reducido que funciona en esas versiones de IE. Tenga en cuenta que el segundo ejemplo, que está codificado en URL, funciona. El truco consiste en no especificar un tipo de codificación en absoluto.
ACTUALIZACIÓN: “Optimizado codificado en URL”
Taylor Hunt investigó un poco más y descubrió que se puede lograr un poco más de optimización al no codificar cosas como espacios y comillas simples. Ejemplo:
data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox='0 0 512 512'%3E%3Cpath d='M224%20387.814V512L32 320l192-192v126.912C447.375 260.152 437.794 103.016 380.93 0 521.287 151.707 491.48 394.785 224 387.814z'/%3E%3C/svg%3E