Script yang ditaruh tanpa perhitungan dapat membuat halaman terasa berhenti di tengah jalan: paragraf tampil separuh, lalu layar diam menunggu file JavaScript selesai. Mekanisme classic, defer, dan async telah dibahas tuntas pada chapter Script dan Defer; chapter ini menilai ulang ketiganya dari sudut performa, lalu menyusun satu contoh head yang menerapkan semuanya. Sasarannya jelas: memastikan parsing dokumen tidak pernah tertahan oleh unduhan maupun eksekusi script.
Biaya Script Classic terhadap Parsing #
Browser mengurai HTML memakai parser yang membaca dokumen dari atas ke bawah. Ketika parser tiba pada script classic, parser berhenti: file diunduh bila eksternal, kode dieksekusi sampai tuntas, dan hanya setelah itu parsing dilanjutkan. Biayanya ada dua lapis — waktu unduhan di jaringan dan waktu eksekusi di perangkat — dan keduanya ditanggung pada momen paling sensitif, yaitu ketika halaman sedang dibentuk. File 200 KB pada jaringan lambat dapat menahan seluruh konten di bawah tag selama berdetik-detik.
Perbandingan Strategi dan Dampaknya #
| Strategi | Parser | Waktu eksekusi | Dampak performa |
|---|---|---|---|
| classic | Berhenti saat tiba di tag | Langsung | Paling berat; konten menunggu |
| defer | Tidak terhenti; unduh paralel | Setelah parsing selesai | Paling aman untuk script aplikasi |
| async | Tidak terhenti; unduh paralel | Begitu unduhan selesai, dapat menyela parsing | Baik, tetapi urutan tidak terjamin |
module (type="module") | Tidak terhenti | Setelah parsing, seperti defer bawaan | Baik; standar aplikasi modern |
Urutan eksekusi yang terjaga pada defer menjadikannya pilihan utama untuk script aplikasi: kode berjalan setelah DOM terbentuk, dan tag tetap boleh berada di head sehingga unduhan dimulai sedini mungkin. async cocok untuk script mandiri yang tidak bergantung pada halaman maupun script lain, misalnya penghitung kunjungan. type="module" memberikan perilaku defer tanpa perlu atribut tambahan, sebagaimana dibahas pada chapter sebelumnya.
preconnect dan dns-prefetch untuk Pihak Ketiga #
Script pihak ketiga hampir selalu berada di origin berbeda — domain CDN misalnya — dan koneksi ke origin baru berarti berurusan dengan pencarian DNS, pembukaan TCP, dan jabat tangan TLS. Elemen link dengan rel="preconnect" memerintahkan browser menyiapkan koneksi ke origin tersebut lebih awal, jauh sebelum tag yang memakainya ditemukan parser. Versi yang lebih ringan, rel="dns-prefetch", hanya menyelesaikan tahap DNS dan menjadi cadangan untuk browser tanpa dukungan preconnect. Keduanya ditulis di head dan hanya untuk origin yang benar-benar dipakai halaman:
<link rel="preconnect" href="//cdn.example.com">
<link rel="dns-prefetch" href="//cdn.example.com">Penulisan href tanpa skema (//) membuat contoh berlaku untuk protokol http maupun https sekaligus.
Contoh: Head yang Benar #
File berikut merangkai strategi chapter ini pada satu head: persiapan koneksi untuk CDN, lalu script dengan defer yang merujuk file aplikasi.js — sediakan file tersebut sendiri, atau hapus barisnya saat mencoba.
<!doctype html>
<html lang="id">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="preconnect" href="//cdn.example.com">
<link rel="dns-prefetch" href="//cdn.example.com">
<title>Halaman Utama Toko Budi</title>
<script src="aplikasi.js" defer></script>
</head>
<body>
<h1>Toko Budi</h1>
<p>Perlengkapan dapur dan rumah tangga. Katalog lengkap diurus oleh aplikasi.js setelah halaman tampil.</p>
</body>
</html>Output yang Dihasilkan:
Urutan yang terjadi:
1. Parser menemukan link preconnect -> koneksi ke cdn.example.com
disiapkan lebih awal
2. Parser menemukan script defer -> aplikasi.js diunduh paralel,
parsing terus berjalan
3. Halaman tampil penuh tanpa menunggu script
4. Setelah parsing selesai, aplikasi.js dieksekusiMari kita telaah peran setiap baris penting:
- Baris 6 (
linkpreconnect): browser menyiapkan koneksi ke cdn.example.com lebih awal, sebelum resource dari origin itu diminta. - Baris 7 (
linkdns-prefetch): cadangan ringan yang hanya menyelesaikan tahap DNS. - Baris 9 (
script defer): unduhan paralel dimulai saat parser mencapai head, eksekusi menunggu dokumen selesai; parser tidak pernah berhenti. - Baris 12–13 (isi body): konten murni HTML yang tampil tanpa menunggu script mana pun.
Dengan head seperti ini, script tidak lagi mengganggu ritme parsing. Sumbangan performa berikutnya datang dari isi dokumennya sendiri: markup yang ramping.
Referensi resmi untuk pendalaman:
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
contoh-head-benar.html
Unduh berkas<!doctype html>
<html lang="id">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="preconnect" href="//cdn.example.com">
<link rel="dns-prefetch" href="//cdn.example.com">
<title>Halaman Utama Toko Budi</title>
<script src="aplikasi.js" defer></script>
</head>
<body>
<h1>Toko Budi</h1>
<p>Perlengkapan dapur dan rumah tangga. Katalog lengkap diurus oleh aplikasi.js setelah halaman tampil.</p>
</body>
</html>