Selama section ini kita membedah mesin di balik halaman: parsing, DOM, dan alur pengiriman form. Chapter penutup ini berangkat dari pertanyaan yang lebih besar: bagaimana memastikan halaman yang kita bangun tetap bekerja untuk semua pengunjung, di perangkat apa pun, dalam kondisi jaringan apa pun. Jawabannya adalah prinsip yang selama ini diam-diam kita terapkan di contoh course: progressive enhancement.

Definisi Progressive Enhancement #

Progressive enhancement adalah strategi menyusun halaman berlapis: fondasi HTML dibangun agar berfungsi untuk semua browser dan semua kondisi, lalu lapisan CSS dan JavaScript ditambahkan untuk memperkaya pengalaman bila tersedia. Fitur inti — membaca konten, mengirim form, membuka tautan — tidak boleh bergantung pada lapisan tambahan tersebut. Bila lapisan itu gagal dimuat atau tidak didukung, halaman tetap bekerja dengan fungsi dasarnya.

Lapisan CSS dan JavaScript dipandang sebagai penambah (enhancement), bukan syarat berjalannya fitur; karena itu pekerjaan dimulai dari HTML yang berdiri sendiri.

Praktik yang Kita Terapkan Sejak Awal #

Beberapa kebiasaan dari section sebelumnya ternyata progressive enhancement dalam bentuk paling murni:

  • Form tetap terkirim tanpa JavaScript: setiap form contoh kita memakai action dan method dengan validasi native; tanpa JavaScript, data tetap sampai dan pemeriksaan server tetap menjaga keabsahannya.
  • details tanpa satu baris skrip: element dari section Interactive Elements membuka dan menutup konten murni dengan HTML.
  • Link sungguhan, bukan div dengan onclick: a href dapat dibuka di tab baru, dibookmark, dibaca crawler, dan diumumkan screen reader dengan benar.
  • Validasi native sebelum skrip custom: pemeriksaan bawaan browser bekerja bahkan sebelum JavaScript selesai diunduh.

Tiga Lapis pada Satu Fitur #

Ambil fitur langganan kabar buku yang dikelola Budi. Lapisan pertamanya adalah file contoh pada chapter ini — halaman yang berdiri sendiri tanpa CSS dan JavaScript:

<!doctype html>
<html lang="id">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Langganan Kabar Buku Baru</title>
</head>
<body>
  <h1>Langganan Kabar Buku Baru</h1>
  <form action="/langganan" method="post">
    <p>
      <label for="email">Email</label>
      <input type="email" id="email" name="email" required>
    </p>
    <p>
      <input type="submit" value="Langganan">
    </p>
  </form>
  <details>
    <summary>Kenapa kami meminta email?</summary>
    <p>Email dipakai untuk mengirim kabar buku baru satu kali per pekan.</p>
  </details>
</body>
</html>

Output yang Dihasilkan:

text
Jendela browser menampilkan:
  - Form langganan yang berfungsi penuh: kolom email wajib diisi,
    submit mengirim data ke /langganan
  - Butir "Kenapa kami meminta email?" yang membuka penjelasan saat diklik,
    tanpa satu baris JavaScript pun

Berikut peran setiap bagian fondasi tersebut:

  1. Baris 10 (<form action="/langganan" method="post">): jalur pengiriman bawaan; bila JavaScript gagal dimuat, data tetap terkirim melalui navigasi biasa.
  2. Baris 13 (required): validasi native menjaga kolom email tanpa skrip apa pun.
  3. Baris 16 (tombol submit): satu-satunya kontrol pengiriman; jalurnya diatur platform, bukan skrip.
  4. Baris 19-22 (details): interaksi buka-tutup yang diurus browser; konten di dalamnya tetap terbaca screen reader dan crawler.
  5. Baris 21 (penjelasan email): konten bantuan tetap tersedia di fondasi, bukan disembunyikan di balik skrip.

Lapisan kedua, CSS, mengurus tampilan tanpa mengubah perilaku sama sekali:

css Lapisan 2: CSS untuk tampilan
form { max-width: 24rem; }
input:invalid { border: 2px solid #b91c1c; }

Lapisan ketiga, JavaScript, menambah kenyamanan: mencegat submit, mengirim data dengan fetch, lalu menampilkan pesan tanpa navigasi:

javascript Lapisan 3: JavaScript sebagai penambah
const form = document.querySelector("form");
if (form) {
  form.addEventListener("submit", async (event) => {
    event.preventDefault();
    const response = await fetch(form.action, {
      method: "POST",
      body: new FormData(form)
    });
    if (response.ok) {
      form.textContent = "Terima kasih, langganan tercatat.";
    }
  });
}

Perhatikan dua penjaga pada skrip tersebut: pemeriksaan if (form) membuat skrip berhenti dengan aman bila element form tidak ada, dan form.action dibaca dari markup alih-alih ditulis ulang, sehingga sumber kebenaran tetap pada HTML. Bila skrip gagal dimuat, form kembali ke jalur bawaan: submit penuh dengan navigasi. Itulah pola progressive enhancement — JavaScript memperkaya jalur yang telah bekerja, bukan menggantikannya.

Kontras dengan Graceful Degradation #

Istilah yang perlu dibedakan adalah graceful degradation: arah kerjanya kebalikan — pengalaman penuh dibangun dahulu untuk browser modern, lalu jalur penurunan disiapkan untuk yang lawas. Progressive enhancement bergerak dari dasar ke atas; graceful degradation bergerak dari atas ke dasar. Keduanya dapat berujung pada halaman yang serupa, tetapi titik awal perencanaannya berbeda.

Manfaat yang Nyata #

Strategi ini bukan sekadar kerapian teori; manfaatnya terasa langsung:

  • Aksesibilitas: screen reader dan navigasi keyboard bekerja pada fondasi HTML semantik, tanpa menunggu skrip.
  • SEO: crawler membaca HTML; konten di fondasi terindeks tanpa perlu mengeksekusi JavaScript.
  • Perangkat dan browser lawas: fitur inti tetap hidup di lingkungan yang tidak mendukung API terbaru.
  • Jaringan buruk: HTML yang tiba lebih dulu langsung dapat dipakai, tanpa menunggu CSS dan JavaScript selesai.
  • Pemeliharaan: lapisan yang terpisah membuat sumber masalah lebih mudah dilacak.

Dengan chapter ini, section Browser dan Web Platform tertutup utuh: dari byte yang tiba, token, DOM, alat pemeriksaan, hingga prinsip yang menjaga semuanya tetap bekerja. Bekal tersebut membawa kita ke urutan berikutnya — section Performance dan Optimasi — yang kini dapat berfokus pada sisa pertanyaan: bagaimana membuat halaman yang bekerja itu tampil dengan cepat.

Referensi resmi untuk pendalaman:

Berkas Sumber

Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.

contoh-progressive.html

Unduh berkas
html
<!doctype html>
<html lang="id">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Langganan Kabar Buku Baru</title>
</head>
<body>
  <h1>Langganan Kabar Buku Baru</h1>
  <form action="/langganan" method="post">
    <p>
      <label for="email">Email</label>
      <input type="email" id="email" name="email" required>
    </p>
    <p>
      <input type="submit" value="Langganan">
    </p>
  </form>
  <details>
    <summary>Kenapa kami meminta email?</summary>
    <p>Email dipakai untuk mengirim kabar buku baru satu kali per pekan.</p>
  </details>
</body>
</html>