/ Blog/ #javascript

Memuat JavaScript lebih efisien dengan defer dan async

Tayang pada 24 Desember 2024

Dapat dibaca selama 4 menit

Saat kamu memuat script dalam sebuah laman HTML, kamu perlu waspada terhadap kinerja loading halamannya. Salah satu faktor yang sangat mempengaruhi adalah posisi pada dimana dan bagaimana kamu menambah script ke HTML.

Biasanya untuk menyertakan script (misal, dari sebuah file) pada halaman dilakukan seperti berikut:

<script src="script.js"></script>

Ketika HTML parser melihat baris tersebut, request akan dijalankan untuk mendapatkan script dan script tersebut akan di eksekusi.

Saat prosesnya selesai, parser akan memproses isi script dan setiap baris kode HTML nya akan di parse kembali.

Seperti yang kamu bayangkan, operasi seperti ini dapat memberikan dampak yang besar pada waktu pemuatan halaman.

Jika script memerlukan waktu yang lama daripada yang diharapkan, contoh jika jaringannya lambat atau kamu berada di perangkat handphone dan koneksinya jelek, pengunjung kemungkinan akan melihat halaman putih kosong sampai script nya dimuat dan dieksekusi.

Pentingnya Penempatan

Kamu tentu sering menjumpai tag script yang diletakan di dalam tag <head>, bahkan kita mengenali cara ini sejak belajar HTML pertama kali bukan?

<html>
  <head>
    <title>Judulnya</title>
    <script src="script.js"></script>
  </head>
  <body>
    ...
  </body>
</html>

Seperti yang sudah penulis katakan di awal, ketika parser menemukan baris kode ini, parser akan mengambil script dan mengeksekusinya. Setelah itu, lanjut mem-parsing bagian body nya.

Ini tidak baik karena banyak delay yang terjadi diawal sebelum menampilkan halaman dengan lengkap. Solusi untuk mengatasi ini adalah meletakan tag script di bagian bawah halaman, tepatnya setelah tag </body>.

Dengan begitu, script akan di muat dan eksekusi setelah body halamannya sudah di parsing dan dimuat, yang mana merupakan berpengaruh besar selain harus meletakannya di head.

Hal yang paling bisa dilakukan juga jika kamu ingin website/aplikasi mendukung browser lama yang tidak support dua fitur terbarunya HTML: async dan defer.

Async dan Defer

Keduanya (async dan defer) merupakan atribut berbasiis boolean, cara menggunakannya mirip-mirip:

<script async src="script.js"></script>
<script defer src="script.js"></script>

Lebih jelasnya, async didukung pada browser modern, sedangkan browser lawas mendukung penggunaan defer (tidak akan ada fallback disini, misalnya diatur async lalu jadi defer otomatis).

Sekedar info, jika ingin mengetahui lengkap mengenai dukungan browser terhadap suatu fitur, cek di caniuse.com, async dan defer.

Penggunaan atribut ini masih masuk akal ketika meletakan scriptnya di bagian head, dan kelihatan tidak ada guna nya bila meletakknya di bawah body seperti yang penulis tunjukan diatas.

Perbandingan Di Sisi Performa

No defer atau async, di bagian head

Berikut adalah bagaimana ketika halaman memuat script tanpa defer maupun sync, dan meletakannya di bagian head:

Ilustrasi grafis no defer atau async di head

Proses parsing tertunda hingga scriptnya telah diambil dan tereksekusi, setelah itu parsing lanjut lagi.

No defer atau async, di bagian body

Berikut adalah bagaimana halaman memuat script tanpa defer atau async, meletakan <script> di bagian akhir tag body, tepat sebelum di tag penutupnya:

Ilustrasi grafis no defer atau async di body

Proses parsing selesai tanpa ada penundaan, ketika selesai, script diambil dan dieksekusi. Parsing ini dilakukan bahkan sebelum script didownload, akibatnya konten dimunculkan terlebih dahulu ke hadapan user (tidak seperti pada contoh sebelumnya, jauh berbeda)

Dengan async, di bagian body

Berikut adalah cara halaman memuat script dengan async, peletakan script di tag <head>:

Ilustrasi grafis async di body

Script diambil secara asyncrhonous, ketika sudah siap (dieksekusi), parsing HTML dihentikan sementara untuk mengeksekusi script, setelahnya dilanjut kembali

Dengan defer, di bagian head

Berikut adalah cara halaman memuat script dengan defer, peletakan script di tag <head>:

Ilustrasi grafis async di body

Script akan diambil secara asyncrhonous dan hanya dieksekusi tepat setelah parsing HTML selesai.

Proses parsing selesai sama seperti ketika kita meletakan script di akhir tag body, tetapi secara keseluruhan eksekusi script selesai jauh lebih awal, karena script telah terdownload secara paralel bersamaan dengan parsing HTML.

Maka solusi menjadi sebuah keunggulan dalam hal performa ketika memuat website

Block Parsing

async akan memblocking proses parsing HTML, sedangkan defer tidak.

Block Rendering

async ataupun defer tidak “dijamin” dapat memblokir proses rendering. Hal seperti ini tergantung pada pada isi scriptnya (misal, script yang kamu rancang berjalan setelah event onLoad - itupun kamu definisikan sendiri)

domInteractive

Script yang dijalankan dengan defer akan dieksekusi tepat setelah event domInteractive, yang mana terjadi ketika HTML dimuat, di parsing, dan DOM dibangun.

CSS dan Gambar-gambar juga terlibat dalam proses parsing dan pemuatan di tahap tersebut.

Ketika selesai, browser akan memicu event domComplete dan selanjutnya onLoad.

domInteractive sangat penting, karena waktu yang dihasilkan dari proses event ini dijadikan acuan dalam mengukur performa pemuatan website. Lihat MDN untuk info lebih lengkapnya.

Menjaga ketaraturan

Pro tips menggunakan defer: Script yang dimuat menggunakan async akan dieksekusi secara berurutan seperti biasa (saat script sudah benar-benar tersedia). Script yang dimuat menggunakan defer dieksekusi (tepat setelah penguraian HTML selesai) dalam urutan yang didefinisikan di markup.

Jadi, mana yang bagus?

Yang terbaik adalah mempercepat loading halaman website yang menggunakan script adalah meletakan tag <script> di head, dengan atribut defer:

<script defer src="script.js"></script>

Skenario ini memicu event domInteractive lebih cepat.

Mengingat defer memiliki kelebian, kelihatannya async bukan pilihan yang lebih baik dibandingkan defer dalam hal penanganan di berbagai skenario yang ada.

Kecuali kamu tidak keberatan menunda render halaman, pastikan saat halaman diparsing, Kode JavaScript kamu benar-benar sudah berjalan lebih dulu.