Skip to content
Kembali ke Blog
Tutorial

Gambar ke Base64 dan Data URI: Kapan Menyematkan Gambar (2026)

Perlu mengubah gambar menjadi Base64? Kapan data URI membantu, biaya ukuran 33%, penyematan CSS/HTML, dan kapan file gambar biasa lebih unggul.

11 menit membaca

Saat Anda mengubah gambar menjadi Base64, hasilnya adalah sebuah data URI: string seperti data:image/png;base64,iVBORw0KGgo… yang bisa Anda tempel langsung ke atribut src HTML atau ke url() di CSS. Browser mendekodenya seketika dan menampilkan gambar tanpa unduhan terpisah. Tidak ada file yang perlu di-host, tidak ada request tambahan.

Jadi, perlukah Anda melakukannya? Aturannya singkat. Sematkan (inline) gambar sebagai Base64 ketika gambar itu kecil (di bawah sekitar 2 KB), jarang berubah, dan Anda ingin memangkas satu request HTTP, misalnya ikon dan logo mungil. Untuk selain itu, seperti gambar besar, apa pun yang dipakai ulang di banyak halaman, atau apa pun yang ingin Anda biarkan di-cache oleh browser, pertahankan sebagai file gambar biasa. Yang penting diingat: Base64 membuat sebuah file menjadi sekitar 33% lebih besar, dan begitu teks itu tertanam di dalam HTML atau CSS Anda, ia tidak bisa lagi di-cache secara tersendiri.

Kalau Anda ingin angka pasti untuk file tertentu, konverter Image ke Base64 melakukan pengodean di dalam browser Anda dan menampilkan kenaikan ukuran yang presisi, sehingga Anda bisa memutuskan dengan data nyata, bukan sekadar aturan praktis. Panduan ini menelusuri apa sebenarnya data URI itu, matematika di balik pajak ukuran, matriks keputusan untuk menentukan kapan penyematan (inlining) sepadan, dan kasus-kasus di mana file biasa lebih unggul.

Apa yang sebenarnya dihasilkan “gambar ke Base64”: data URI

Mengubah gambar menjadi Base64 tidak menghasilkan file. Yang dihasilkan adalah satu string panjang yang mengikuti format data URI yang didefinisikan dalam RFC 2397 (lihat referensi URL data: MDN). String ini terdiri dari tiga bagian:

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA…
└──┬─┘ └───┬───┘ └─┬──┘ └─────────┬──────────┘
data:   MIME type  marker   the encoded image bytes

MIME type memberi tahu browser jenis gambar apa yang sedang ia dekode. Yang umum untuk gambar adalah image/png, image/jpeg, image/gif, image/webp, image/svg+xml, dan image/x-icon untuk favicon. Penanda ;base64, menyatakan bahwa muatan (payload) yang menyusul berupa Base64, bukan teks biasa. Segala sesuatu setelah koma adalah gambar itu sendiri, yang dinyatakan ulang sebagai ASCII yang dapat dicetak.

Bagian terakhir itu penting untuk privasi. Konversinya berjalan sepenuhnya di dalam browser Anda lewat readAsDataURL dari API FileReader, jadi tidak ada apa pun yang diunggah ke server. Anda bisa menjatuhkan tangkapan layar pra-peluncuran, diagram internal, atau karya seni yang belum dirilis ke dalam alat ini, lalu lihat sendiri tab Network tetap kosong. Untuk mekanisme dasar bagaimana byte mentah berubah menjadi string ASCII, memahami Base64 membahas pengodean dari nol, dan panduan lengkap Base64 memperluas ide data-URL yang sama ke font, PDF, dan jenis file lain.

Contoh nyata: PNG transparan 68 byte

Inilah kasus praktis terkecil, yaitu PNG transparan 1×1 berukuran 68 byte di disk, sebagai data URI yang utuh:

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==

Tempel itu ke bilah alamat browser dan Anda akan melihat gambar yang ter-render valid tanpa aktivitas jaringan sama sekali (yah, tidak akan benar-benar terlihat, karena transparan). Perhatikan == di ujungnya: itu padding, yang akan kita bahas nanti. Ini juga persis seperti tampilan Base64 untuk teks, hanya saja diterapkan pada byte gambar alih-alih teks. Kalau Anda hanya perlu mengodekan atau mendekode string teks biasa, alat encode/decode Base64 menangani kasus itu.

Pajak ukuran 33% (dan mengapa ia berlipat)

Base64 bekerja dalam kelompok tetap: setiap 3 byte biner menjadi 4 karakter ASCII. Empat per tiga kira-kira 1,33, dan dari sinilah angka +33% berasal. Tambahkan satu atau dua byte padding plus prefiks data:image/png;base64,, dan overhead-nya sedikit lebih tinggi untuk file mungil. Contoh konkret: PNG 9 KB menjadi sekitar 12 KB teks.

Mengapa tepatnya 3-ke-4? Base64 memakai alfabet 64-karakter, yaitu AZ, az, 09, ditambah + dan /. Enam puluh empat simbol berarti 6 bit informasi per karakter, sementara byte biner masing-masing 8 bit. Kelipatan persekutuan terkecil dari 6 dan 8 adalah 24 bit, yang setara dengan 3 byte atau 4 karakter Base64, jadi encoder melangkah menyusuri gambar 24 bit sekaligus. Ketika panjang gambar bukan kelipatan 3 yang bulat, satu atau dua karakter = melakukan padding pada kelompok terakhir. Begitulah matematikanya, dan angkanya tetap; tidak ada pengaturan encoder yang bisa menyusutkan angka 33% itu.

Angka 33% itu biaya yang terlihat. Biaya tersembunyinya adalah bahwa ia berlipat, dan inilah bagian yang dilewatkan sebagian besar nasihat “sematkan saja”:

  • Gambar diunduh ulang setiap kali file penampungnya berubah. Sebuah logo.png eksternal adalah resource-nya sendiri. Sematkan ia ke dalam styles.css, dan kini setiap penyuntingan pada stylesheet itu, entah penyesuaian warna atau aturan baru, turut membatalkan cache untuk gambar tersebut. Pengunjung mengunduh ulang gambar yang sudah mereka miliki.
  • Ia tidak bisa di-cache secara mandiri. File gambar biasa diambil sekali dan dipakai ulang di setiap halaman dan setiap kunjungan. Data URI yang disematkan menjadi bagian dari dokumen, sehingga ia ikut terkirim lagi di setiap halaman yang menyematkannya dan pada setiap cache miss dokumen tersebut.
  • CSS bersifat render-blocking. Browser tidak akan menggambar (paint) sebelum ia memiliki CSS-nya. Jejalkan data URI besar ke dalam stylesheet, dan Anda memperbesar resource yang memblokir render, sehingga paint pertama bagi seluruh halaman jadi tertunda.

Apakah gzip atau brotli membatalkan angka 33% itu?

Sebagian, tidak sepenuhnya. Teks Base64 cukup repetitif sehingga gzip dan brotli mengompresinya dengan baik, mengembalikan sebagian besar inflasi itu saat melintas di jaringan. Tapi dua hal tetap berlaku. Pertama, Base64 terkompresi biasanya masih sedikit lebih besar daripada biner asli terkompresi, karena Anda menyodorkan titik awal yang kurang efisien kepada kompresor. Kedua, dan ini poin yang lebih besar, kompresi tidak melakukan apa-apa terhadap caching maupun render-blocking. Data URI yang lebih kecil di jaringan tetap diunduh ulang bersama file induknya dan tetap tidak bisa di-cache secara tersendiri.

Dengan kata lain, kompresi tidak sama dengan menghilangkan biaya penyematan. Kalau perbedaan antara minifikasi, gzip, dan brotli masih kabur, panduan minifikasi kode menjabarkan bagaimana lapisan-lapisan itu bertumpuk, dan mengapa memeras byte tidak pernah memperbaiki masalah caching yang ditimbulkan oleh penyematan.

Kapan memakai gambar Base64 (matriks keputusan)

Keputusan ini berpangkal pada beberapa faktor. Berikut faktor-faktornya berdampingan:

FaktorCenderung menyematkan (Base64)Cenderung file biasa
UkuranDi bawah ~2 KB (hijau)Di atas ~10 KB (merah); 2–10 KB adalah pertimbangan kasuistis (amber)
Pemakaian ulangSatu halaman, satu atau dua tempatDiulang di banyak halaman
Frekuensi perubahanHampir tidak pernah berubahSering disunting
KonteksEmail HTML, widget atau bookmarklet mandiri, payload JSON/API, ikon kritis di atas lipatan (above-the-fold) yang layak menukar satu request hematGambar konten, aset bersama yang dapat di-cache

Ambang ukuran itu tidak sembarangan; semuanya mencerminkan lencana lampu lalu lintas yang tertanam di konverter Image ke Base64: hijau di bawah 2 KB, amber sampai 10 KB, merah di atasnya. Alat ini membaca file Anda yang sebenarnya dan memberi tahu bucket mana yang ditempatinya.

Aturan praktis sederhana

Kalau Anda mengingat satu baris saja, jadikan ini: di bawah ~2 KB dan dipakai hanya di satu atau dua tempat, penyematan biasanya sepadan; di atas ~10 KB atau dipakai ulang di banyak halaman, file biasa yang di-cache hampir selalu menang. Wilayah tengah 2–10 KB adalah tempat Anda menimbang request yang hemat melawan cache yang hilang untuk situasi spesifik Anda.

Kecocokan yang baik secara rinci

Beberapa kasus di mana Base64 benar-benar membayar kembali kehadirannya:

  • Email HTML. Banyak klien email memblokir gambar yang di-host secara eksternal secara default demi privasi, dan ini merusak tata letak apa pun yang bergantung pada logo jarak jauh. Data URI mungil yang disematkan akan ter-render seketika tanpa pengambilan dari server. Batasi ini pada logo dan ikon; jangan pernah menyematkan foto ke dalam email.
  • Widget dan bookmarklet mandiri. Bookmarklet atau widget yang dapat disisipkan harus bekerja dengan nol dependensi eksternal. Menyematkan ikon-ikonnya menjaga semuanya dalam satu file yang bisa dijatuhkan begitu saja.
  • Payload JSON dan API. Mengirim thumbnail di dalam dokumen JSON atau file konfigurasi terkadang menjadi opsi paling bersih: satu kali pulang-pergi, satu objek, tanpa request kedua yang perlu disambungkan.
  • Ikon kritis di atas lipatan. Ketika logo mungil menjadi bagian dari Largest Contentful Paint Anda dan Anda ingin memangkas satu request dari jalur kritis, penyematan bisa membantu. Tekankan pada kata mungil.

Satu pola mengikat semua ini: masing-masing adalah kasus di mana aset itu bepergian bersama sesuatu yang lain dan kalau tidak demikian akan butuh kanal pengirimannya sendiri. Email tidak bisa mengandalkan CDN Anda. Bookmarklet tidak punya file kedua untuk diambil. Respons JSON adalah satu payload tunggal. Dalam tiap kasus, alternatif dari penyematan bukan “file yang di-cache” tapi “gambar yang hilang”, dan ini mengubah perhitungannya sepenuhnya. Itulah ujian sebenarnya untuk kecocokan Base64 yang baik: bukan soal “apakah ia kecil”, tapi “apakah file terpisah memang sebuah opsi di sini”.

Kapan TIDAK menyematkan: caching, lazy loading, dan Core Web Vitals

Sisi sebaliknya lebih panjang, karena penyematan diam-diam menonaktifkan beberapa hal yang dilakukan browser dengan baik.

Anda kehilangan caching mandiri. Ini paling terasa menyengat bagi pengunjung yang kembali. Gambar biasa bersemayam di cache mereka setelah kunjungan pertama dan memuat seketika selamanya. Gambar yang disematkan tidak punya entri cache tersendiri; ia menumpang bersama dokumen setiap saat, sehingga pengunjung berulang membayar biaya byte itu berkali-kali.

Anda kehilangan lazy loading. Atribut loading="lazy" memungkinkan browser menunda gambar yang ada di bawah lipatan sampai pengguna menggulir mendekatinya. Data URI di-parse dan “diunduh” pada saat HTML dibaca, jadi tidak ada yang bisa ditunda. Sematkan selusin gambar di bawah lipatan, dan Anda memaksa semuanya masuk ke pemuatan awal.

Anda memperbesar resource yang render-blocking. Seperti dicatat sebelumnya, data URI di dalam CSS menggembungkan resource yang memblokir paint pertama. Semakin besar stylesheet itu, semakin lama halaman terlihat kosong.

Dekode lebih mahal di ponsel. Sebuah data URI didekode dari Base64 setiap kali dokumennya dimuat, dan di ponsel kelas bawah kerja CPU itu menumpuk. Lebih buruk lagi, byte-nya tidak pernah masuk ke cache disk browser, jadi gambar berat yang disematkan didekode ulang setiap kunjungan, alih-alih di-cache dan didekode sekali seperti file biasa.

Ada juga alasan historis mengapa nasihat ini bergeser. Argumen asli untuk penyematan, yang disuarakan lantang di era HTTP/1.1, adalah pengurangan request: setiap koneksi hanya bisa mengambil satu resource pada satu waktu, jadi halaman dengan 40 ikon kecil membayar 40 kali pulang-pergi. HTTP/2 mengubahnya dengan melakukan multiplexing banyak request melalui satu koneksi, yang membuat file-file kecil ekstra menjadi murah. Imbalan besar dari penyematan, yaitu request yang lebih sedikit, sebagian besar menguap, sementara biayanya tetap tinggal: caching yang hilang, tidak ada lazy loading, dan file render-blocking yang lebih besar. Kalau Anda membaca artikel-artikel lama yang antusias tentang sprite Base64, timbanglah mereka terhadap protokol yang sebenarnya dijalankan situs Anda hari ini.

Sudut pandang Core Web Vitals

Penyematan berdampak dua arah pada LCP (Largest Contentful Paint). Untuk gambar kecil di atas lipatan yang memang menjadi elemen LCP, menghilangkan satu request bisa menggeser LCP lebih awal. Tapi sematkan gambar besar dan hasilnya sebaliknya: Anda menunda dokumen atau stylesheet tempat gambar itu berada, sehingga LCP terdorong lebih lambat bagi seluruh halaman. Ambang ukuranlah yang menentukan ke arah mana hasilnya.

Untuk CLS (Cumulative Layout Shift), penyematan tidak mengubah apa pun pada aturan intinya: gambar tetap memerlukan width dan height eksplisit (atau kotak aspect-ratio) agar browser bisa memesan ruang sebelum gambar ter-render. Data URI tanpa dimensi menggeser tata letak persis seperti gambar jarak jauh tanpa dimensi.

Tuas yang lebih baik daripada penyematan biasanya adalah menyusutkan sumbernya. Mengompresi gambar sebelum Anda mengodekannya membuat file maupun data URI yang dihasilkan jadi lebih kecil. Panduan kompresi gambar browser vs Node membahas cara melakukannya di sisi klien atau dalam langkah build, dan WebP vs AVIF vs JPEG membantu Anda memilih format yang memang sudah kecil sejak awal.

Cara menyematkan gambar di HTML, CSS, Markdown, dan JSON

Setelah Anda punya data URI, berikut cara ia masuk ke setiap konteks. Inilah keempat snippet siap-tempel yang dihasilkan konverter Image ke Base64 untuk Anda.

HTML: tempel URI ke dalam src apa pun:

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA…" alt="logo">

CSS: bungkus dalam url() untuk sebuah background-image (ini pola kanonis base64 image in CSS):

.icon {
  background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0i…");
}

Markdown: tautan gambar mandiri untuk README, GitHub issue, dan notebook di mana Anda tidak bisa meng-host file:

![chart](data:image/jpeg;base64,/9j/4AAQSkZJRgABAQ…)

JSON: aset tertanam di dalam payload API atau konfigurasi:

{ "icon": "data:image/png;base64,iVBORw0KGgo…" }

Keempatnya bekerja di mana pun sebuah URL diterima: img src, background CSS, mask-image, bahkan <link> favicon. Setiap browser modern mendukung skema data:.

Membuatnya dengan cepat

Membuat ini secara manual rawan kesalahan: satu MIME type yang salah atau satu jeda baris yang nyasar, dan gambar diam-diam gagal ter-render. Jatuhkan file Anda ke konverter Image ke Base64 dan ia menghasilkan keempat snippet beserta tombol salinnya masing-masing, ditambah kenaikan ukuran yang pasti sehingga Anda tahu sejak awal apakah aset itu memang layak disematkan.

SVG: kasus khusus di mana Base64 biasanya kalah

SVG mematahkan logika yang biasa, karena SVG adalah teks, bukan biner. Base64 ada untuk membuat data biner aman sebagai teks, padahal SVG sudah berupa teks XML. Mengodekannya sebagai Base64 hanya menggembungkan string yang tidak butuh pengodean, dan dalam prosesnya membuatnya tak terbaca. Jadi untuk SVG secara khusus, Base64 hampir selalu pilihan yang salah.

Bandingkan tiga cara menyematkan ikon yang sama:

/* 1. Base64 data URI — adds the 33% tax to text that didn't need it */
.a { background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0i…"); }

/* 2. URL-encoded data URI — percent-encode a handful of characters, no 33% tax */
.b { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'…%3C/svg%3E"); }

/* 3. Inline <svg> directly in the HTML — fully styleable with CSS */
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
  <path d="M12 2 L22 22 H2 Z" fill="currentColor" />
</svg>

Opsi 2 (URL-encoding) biasanya lebih kecil daripada opsi 1, tetap dapat dibaca manusia, dan terkompresi lebih baik. Anda hanya melakukan percent-encode pada karakter yang akan merusak URI, yaitu <, >, #, dan tanda kutip, sambil membiarkan sisanya tetap terbaca. Pendekatan URL encoder/decoder didokumentasikan di dalam alatnya sendiri; pakai Base64 SVG hanya ketika sebuah pipeline build secara khusus menuntutnya.

Mengapa sebuah <svg> inline sering mengalahkan ikon PNG Base64

Kalau Anda memilih antara ikon PNG berkode Base64 dan sebuah <svg> inline, SVG biasanya menang di setiap sumbu. Ia berskala ke ukuran apa pun tanpa menjadi buram, ia tidak membawa pajak 33%, dan, tidak seperti data URI mana pun, Anda bisa menatanya dengan CSS, menganimasikannya, dan mewarnainya ulang dengan currentColor. PNG Base64 adalah gumpalan beresolusi tetap yang tidak bisa Anda sentuh begitu dikodekan. Cadangkan Base64 raster untuk kasus di mana Anda benar-benar membutuhkan foto atau tangkapan layar raster secara inline.

Mendekode ke arah sebaliknya: Base64 kembali menjadi gambar

Masalah kebalikannya sama lazimnya: Anda punya string Base64, entah ditarik dari respons API, sebaris log, kolom basis data, atau stylesheet yang sedang Anda debug, dan Anda perlu melihat gambar yang sebenarnya.

Dua detail sering menjerat orang. Pertama, Base64 mentah versus data URI utuh. Data URI lengkap (data:image/png;base64,…) membawa MIME type-nya sendiri; payload telanjang (iVBORw0KGgo…) tidak. Untuk me-render payload telanjang, Anda menambahkan prefiks data: yang benar di depannya atau membiarkan sebuah alat menyimpulkan formatnya dari byte-byte awal: iVBORw0KGgo berarti PNG, /9j/ berarti JPEG, R0lGOD berarti GIF.

Kedua, pembungkusan baris (line wrapping). Base64 dari email atau peralatan lama sering dibungkus pada 76 karakter sesuai RFC 2045. Karakter newline itu harus dilepas sebelum pendekodean, atau stringnya menjadi tidak valid di dalam atribut HTML atau url().

Di browser, Anda bisa menyerahkan data URI utuh langsung ke sebuah <img>:

<img src="data:image/png;base64,iVBORw0KGgo…" alt="decoded">

Di server, Node merekonstruksi file dari payload-nya:

import { writeFileSync } from "node:fs";

const b64 = "iVBORw0KGgoAAAANSUhEUgAA…"; // payload mentah, tanpa prefiks data:
writeFileSync("output.png", Buffer.from(b64, "base64"));

Untuk jalur tanpa-kode, pakai konverter Base64 ke Image: tempel string (dengan atau tanpa prefiks, lengkap dengan jeda baris), pratinjau, baca dimensi dan MIME type-nya, lalu unduh PNG, JPG, GIF, atau SVG yang nyata. Alat ini melepas spasi-kosong, mentoleransi prefiks yang hilang, dan mendeteksi formatnya dari magic byte secara otomatis.

Satu pemeriksaan kewarasan yang patut dilakukan pada gambar yang sudah didekode: lihat dimensi yang dilaporkannya. Kalau Anda menarik satu string dari file yang menampung beberapa string dan hasilnya 1×1, kemungkinan besar Anda menyambar tracking pixel alih-alih aset yang Anda inginkan. Dan ingatlah bahwa pendekodean murni mekanis dan lossless: PNG Base64 kembali sebagai PNG yang sama persis, byte demi byte, tanpa kompresi ulang. Satu-satunya yang berubah sepanjang jalan hanyalah wadahnya, dari string teks saat keluar menjadi file biner saat kembali.

FAQ

Perlukah saya mengubah gambar saya menjadi Base64?

Hanya ketika itu sepadan: ikon atau logo yang kecil (di bawah ~2 KB), jarang berubah, dan di mana memangkas satu request HTTP itu berarti, ditambah email HTML, widget mandiri, dan payload JSON. Gambar besar atau apa pun yang dipakai ulang di banyak halaman hampir selalu sebaiknya tetap menjadi file biasa, supaya Anda mempertahankan caching dan lazy loading.

Seberapa besar Base64 membuat gambar membengkak?

Sekitar +33%. Base64 mengodekan setiap 3 byte biner sebagai 4 karakter ASCII, ditambah sedikit padding dan prefiks data:. PNG 9 KB menjadi kira-kira 12 KB teks. Untuk mengubah gambar menjadi Base64 dan melihat kenaikan pasti untuk file Anda, alat ini melaporkan angka presisinya di bilah metadata.

Apakah Base64 membuat gambar memuat lebih cepat?

Untuk ikon di atas lipatan yang sangat kecil, ia bisa, dengan menghemat satu kali pulang-pergi request. Untuk gambar yang lebih besar atau dipakai ulang, biasanya lebih lambat: Anda kehilangan caching mandiri, Anda tidak bisa men-lazy-load-nya, dan menyematkannya ke dalam CSS memperbesar resource yang render-blocking. Ukuran adalah faktor penentunya.

Bisakah saya memakai gambar Base64 di CSS?

Bisa: background-image: url("data:image/png;base64,…"). Ini baik-baik saja untuk ikon mungil. Hanya ingat bahwa data URI itu menjadi bagian dari stylesheet, sehingga seluruh file diunduh ulang setiap kali CSS berubah, dan gambar itu tidak bisa di-cache terpisah darinya.

Sebaiknya saya memakai SVG atau Base64 untuk ikon?

Utamakan sebuah <svg> inline atau data URI SVG yang di-URL-encode. SVG adalah teks, berskala dengan rapi, dan tidak membawa pajak 33%, sehingga biasanya lebih kecil daripada PNG Base64 dan Anda bisa menatanya dengan CSS. Pakai Base64 hanya ketika Anda secara khusus membutuhkan ikon raster.

Bagaimana cara mengubah string Base64 kembali menjadi gambar?

Di browser, jatuhkan URI data:image/…;base64,… utuh ke dalam sebuah <img src>. Di server, pakai Buffer.from(b64, "base64") untuk menulis file. Payload mentah perlu ditambahi prefiks data:, dan string yang terbungkus baris perlu newline-nya dilepas terlebih dahulu. Alat Base64 ke Image menangani semua itu dan memungkinkan Anda mengunduh hasilnya.

Tag: base64 data-uri images performance css web-performance

Artikel Terkait

Lihat semua artikel