Dipublikasikan: 23 November 2024
Pengembangan berbasis modul menawarkan beberapa keuntungan nyata dalam hal kemampuan penyimpanan dalam cache, yang membantu Anda mengurangi jumlah byte yang perlu dikirimkan kepada pengguna. Tingkat perincian kode yang lebih baik juga membantu cerita pemuatan, dengan memungkinkan Anda memprioritaskan kode penting dalam aplikasi.
Namun, dependensi modul menyebabkan masalah pemuatan, karena browser perlu menunggu modul dimuat sebelum mengetahui dependensinya. Salah satu cara untuk mengatasinya adalah dengan memuat dependensi secara otomatis, sehingga browser mengetahui semua file sebelumnya dan dapat membuat koneksi tetap sibuk.
<link rel="preload">
<link rel="preload">
adalah cara meminta resource secara deklaratif terlebih dahulu,
sebelum browser membutuhkannya.
<head>
<link rel="preload" as="style" href="critical-styles.css">
<link rel="preload" as="font" crossorigin type="font/woff2" href="myfont.woff2">
</head>
Hal ini berfungsi dengan baik terutama dengan resource seperti font, yang sering kali disembunyikan di dalam file CSS, terkadang beberapa tingkat. Dalam situasi tersebut, browser harus menunggu beberapa roundtrip sebelum mengetahui bahwa browser perlu mengambil file font berukuran besar, padahal browser dapat menggunakan waktu tersebut untuk memulai download dan memanfaatkan bandwidth koneksi penuh.
<link rel="preload">
dan header HTTP-nya yang setara memberikan cara sederhana dan deklaratif
untuk memberi tahu browser secara langsung tentang file penting yang akan diperlukan
sebagai bagian dari navigasi saat ini. Saat melihat pramuat, browser akan memulai download
prioritas tinggi untuk resource, sehingga pada saat benar-benar diperlukan, resource tersebut
sudah diambil atau sebagian sudah ada. Namun, hal ini tidak berlaku untuk modul.
Mengapa <link rel="preload">
tidak berfungsi untuk modul?
Di sinilah kesulitan mungkin muncul. Ada beberapa mode kredensial untuk resource, dan agar mendapatkan hit cache, kredensial tersebut harus cocok. Jika tidak, Anda akan mengambil resource dua kali. Tidak perlu dikatakan, pengambilan ganda itu buruk, karena menghabiskan bandwidth pengguna dan membuat mereka menunggu lebih lama, tanpa alasan yang baik.
Untuk tag <script>
dan <link>
, Anda dapat menetapkan mode kredensial dengan atribut
crossorigin
. Namun, ternyata <script type="module">
tanpa
atribut crossorigin
menunjukkan mode kredensial omit
, yang tidak ada
untuk <link rel="preload">
. Artinya, Anda harus
mengubah atribut crossorigin
di <script>
dan <link>
menjadi salah satu
nilai lainnya, dan Anda mungkin tidak memiliki cara mudah untuk melakukannya jika yang Anda
coba pramuat adalah dependensi modul lain.
Selain itu, mengambil file hanyalah langkah pertama dalam benar-benar menjalankan kode.
Pertama, browser harus mengurai dan mengompilasi kode tersebut. Idealnya,
hal ini juga harus dilakukan sebelumnya, sehingga saat modul diperlukan, kode
sudah siap dijalankan. Namun, V8 (mesin JavaScript Chrome) mengurai dan mengompilasi modul
dengan cara yang berbeda dari JavaScript lainnya. <link rel="preload">
tidak
menyediakan cara untuk menunjukkan bahwa file yang dimuat adalah modul, sehingga yang dapat dilakukan browser
adalah memuat file dan menyimpannya dalam cache. Setelah skrip dimuat menggunakan tag <script type="module">
(atau dimuat oleh modul lain), browser akan mengurai dan mengompilasi kode sebagai modul JavaScript.
Jadi, apakah <link rel="modulepreload">
hanya <link rel="preload">
untuk modul?
Singkatnya, ya. Dengan memiliki jenis link
tertentu untuk memuat modul secara otomatis, kita dapat
menulis HTML sederhana tanpa perlu khawatir dengan mode kredensial yang kita gunakan. Setelan default
akan berfungsi.
<head>
<link rel="modulepreload" href="super-critical-stuff.mjs">
</head>
[...]
<script type="module" src="super-critical-stuff.mjs">
Dan karena browser sekarang tahu bahwa yang Anda pramuat adalah modul, browser dapat menjadi pintar dan mengurai serta mengompilasi modul segera setelah selesai mengambil, bukan menunggu hingga mencoba dijalankan.
Namun, bagaimana dengan dependensi modul?
Pertanyaan yang bagus. Memang ada sesuatu yang belum dibahas dalam artikel ini: rekursi.
Spesifikasi <link rel="modulepreload">
sebenarnya memungkinkan pemuatan opsional, tidak hanya
modul yang diminta, tetapi juga semua hierarki dependensinya. Browser tidak harus
melakukannya, tetapi dapat melakukannya.
Jadi, apa solusi lintas browser terbaik untuk memuat modul dan hierarki dependensinya secara otomatis, karena Anda memerlukan hierarki dependensi lengkap untuk menjalankan aplikasi?
Browser yang memilih untuk memuat dependensi secara rekursif harus memiliki penghapusan duplikat modul yang andal, jadi secara umum praktik terbaiknya adalah mendeklarasikan modul dan daftar datar dependensinya, dan memercayai browser untuk tidak mengambil modul yang sama dua kali.
<head>
<!-- dog.js imports dog-head.js, which in turn imports
dog-head-mouth.js, which imports dog-head-mouth-tongue.js. -->
<link rel="modulepreload" href="dog-head-mouth-tongue.mjs">
<link rel="modulepreload" href="dog-head-mouth.mjs">
<link rel="modulepreload" href="dog-head.mjs">
<link rel="modulepreload" href="dog.mjs">
</head>
Apakah memuat modul secara otomatis membantu performa?
Pemuatan awal dapat membantu memaksimalkan penggunaan bandwidth, dengan memberi tahu browser tentang hal yang perlu diambil sehingga tidak terjebak tanpa melakukan apa pun selama perjalanan bolak-balik yang lama. Jika Anda bereksperimen dengan modul dan mengalami masalah performa karena hierarki dependensi yang dalam, membuat daftar data preload yang datar pasti dapat membantu.
Meskipun demikian, performa modul masih dalam proses, jadi pastikan Anda memperhatikan dengan cermat apa yang terjadi di aplikasi Anda dengan Alat Developer, dan pertimbangkan untuk memaketkan aplikasi Anda ke dalam beberapa bagian untuk sementara. Namun, ada banyak pekerjaan modul yang sedang berlangsung di Chrome, sehingga kami semakin dekat untuk memberi bundler istirahat yang pantas mereka dapatkan.