Belajar Astro - Images & Asset Optimization
Episode 9 of 24

Belajar Astro - Images & Asset Optimization

Episode ini membahas optimasi gambar di Astro: komponen Image dan Picture dari astro:assets untuk responsive image, pengelolaan aset dan file statis di public dan src/assets, lazy loading media, serta cache control dan integrasi CDN.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Pendahuluan

Gambar menyumbang porsi terbesar dari berat sebuah halaman web. Satu foto yang di-upload mentah bisa berukuran beberapa megabyte — jauh lebih besar dari seluruh CSS dan HTML halaman. Episode 9 ini membahas cara Astro menangani gambar dan aset agar situs tetap cepat.

Astro menyediakan pipeline aset modern di astro:assets: komponen Image dan Picture yang mengoptimasi gambar secara otomatis, format modern seperti AVIF dan WebP, serta lazy loading bawaan. Kalian juga akan belajar mengelola file statis di public dan folder src/assets.

Dengan memahami pipeline ini, halaman kalian akan memuat jauh lebih cepat tanpa menambah beban server.

Menggunakan astro:assets untuk Gambar Responsif

Komponen Image

Komponen Image dari astro:assets mengoptimasi gambar saat build. Simpan gambar asli di src/assets, lalu gunakan:

JSGambar dengan Image
---
import { Image } from "astro:assets";
import fotoHero from "../assets/hero.jpg";
---
 
<Image
  src={fotoHero}
  alt="Foto utama halaman"
  width={1200}
  height={630}
  format="avif"
  loading="lazy"
/>

Pada kode di atas, format="avif" menghasilkan gambar dalam format modern, dan Astro otomatis membuat beberapa ukuran untuk responsive. Komponen Image menghasilkan tag <img> dengan atribut srcset yang optimal.

Komponen Picture untuk Art Direction

Untuk kontrol penuh — misalnya crop berbeda untuk mobile dan desktop — gunakan komponen Picture:

JSGambar dengan Picture
---
import { Picture } from "astro:assets";
import banner from "../assets/banner.jpg";
---
 
<Picture
  src={banner}
  formats={["avif", "webp"]}
  widths={[320, 640, 1024]}
  sizes="(max-width: 768px) 100vw, 640px"
  alt="Banner promosi"
/>

Picture menghasilkan elemen <picture> dengan elemen <source> untuk setiap format dan ukuran. Browser memilih kombinasi terbaik berdasarkan viewport.

Catatan tentang @astrojs/image

Di versi Astro awal, optimasi gambar ditangani package terpisah @astrojs/image. Package itu kini deprecated — mulai Astro 3, fungsionalitasnya diserap ke astro:assets yang bawaan. Selalu gunakan astro:assets untuk project baru.

Asset Handling dan Static File Management

public versus src/assets

Dua tempat menyimpan aset dengan perilaku berbeda:

  • public/: file dicopy apa adanya ke dist/ tanpa proses. Cocok untuk favicon, robots.txt, dan file yang tidak butuh optimasi.
  • src/assets: file diproses pipeline aset — dioptimasi, di-hash, dan direferensikan dari kode.
Pembagian aset
public/favicon.svg      →  dist/favicon.svg (copy langsung)
src/assets/hero.jpg     →  dist/assets/hero-abc123.avif (dioptimasi)

Aturan praktis: letakkan gambar yang dipakai di kode di src/assets, dan file yang dipakai apa adanya (seperti robots.txt) di public.

Import Aset dari Markdown

Konten Markdown juga bisa memakai pipeline aset dengan mengimport gambar di frontmatter dan memakai getImage di halaman:

JSgetImage untuk gambar dari koleksi
---
import { getImage } from "astro:assets";
import { getCollection } from "astro:content";
 
const posts = await getCollection("blog");
const hero = posts[0].data.cover;
const optimized = await getImage({ src: hero, format: "webp" });
---
 
<img src={optimized.src} alt={posts[0].data.title} />

getImage mengembalikan URL hasil optimasi tanpa harus memakai komponen Image langsung — fleksibel untuk gambar dinamis dari collection.

Lazy Loading Media dan Performance Best Practice

Lazy Loading Bawaan

Astro menambahkan atribut loading="lazy" pada gambar di bawah fold secara otomatis ketika kalian memakai astro:assets. Gambar di atas fold sebaiknya di-priority dengan loading="eager" agar langsung dimuat — contohnya gambar hero.

JSGambar hero dimuat segera
<Image src={hero} alt="Hero" loading="eager" fetchpriority="high" />

Atribut fetchpriority="high" memberi tahu browser bahwa gambar ini penting dan harus diprioritaskan.

Mengatur Dimensi Selalu

Selalu beri width dan height — baik di komponen Image maupun CSS. Ini mencegah layout shift (konten melompat saat gambar selesai dimuat) dan menjaga nilai Cumulative Layout Shift (CLS) tetap rendah.

Cache Control dan CDN Integration

Cache Header untuk Gambar

Gambar hasil build biasanya di-cache lama karena nama filenya mengandung hash — konten baru mendapat nama baru. Untuk deployment yang memakai CDN, set header cache:

Cache header contoh di Vercel
# vercel.json
{ "headers": [
  { "source": "/_astro/(.*)", "headers": [
    { "key": "Cache-Control", "value": "public, max-age=31536000, immutable" }
  ] }
] }

Nama file ber-hash memungkinkan cache satu tahun penuh secara aman — ketika gambar berubah, nama file ikut berubah sehingga browser otomatis mengambil versi baru.

Memakai CDN

Setelah build, seluruh dist/ bisa disajikan lewat CDN untuk distribusi global. Kalian akan menyusun strategi CDN dan cache yang lebih menyeluruh di episode 14.

Tip

Periksa ukuran gambar dengan membuka DevTools tab Network dan menyortir berdasarkan ukuran. Jika ada gambar di atas 200 KB, hampir pasti layak dioptimasi dengan astro:assets.

Penutup

Episode 9 membekali kalian optimasi gambar dan aset: komponen Image dan Picture dari astro:assets untuk gambar responsif, manajemen aset di public versus src/assets, lazy loading dan prioritas muat, serta cache control untuk integrasi CDN.

Inti yang harus dibawa pulang:

  • astro:assets menggantikan @astrojs/image yang sudah deprecated.
  • Image menghasilkan gambar responsive; Picture untuk art direction.
  • Simpan aset terproses di src/assets, file copy di public.
  • Lazy loading otomatis; gambar hero pakai loading="eager".
  • Selalu beri dimensi untuk mencegah layout shift.
  • File ber-hash aman di-cache setahun di CDN.

Di episode 10 selanjutnya kita akan membahas forms dan interactions: penanganan form di halaman Astro, interaksi sisi klien dengan komponen yang di-hydrate, validasi UI dan progressive enhancement, serta pengiriman form melalui fungsi serverless. Interaktivitas kalian mulai melayani pengguna nyata.