Ada begitu banyak cara untuk memasukkan JavaScript ke halaman html. Saya tahu tentang opsi berikut:
- kode sebaris atau diambil dari URI eksternal
- termasuk dalam tag <head> atau <body> [ 1 , 2 ]
- tidak memiliki,
defer
atauasync
atribut (hanya skrip eksternal) - termasuk dalam sumber statis atau ditambahkan secara dinamis oleh skrip lain (pada kondisi parse yang berbeda, dengan metode yang berbeda)
Tidak menghitung browserscripts dari harddisk, javascript: URI dan onEvent
-attributes [ 3 ], ada yang sudah 16 alternatif untuk mendapatkan JS dieksekusi dan aku yakin aku lupa sesuatu.
Saya tidak begitu peduli dengan pemuatan cepat (paralel), saya lebih ingin tahu tentang urutan eksekusi (yang mungkin tergantung pada urutan pemuatan dan urutan dokumen ). Apakah ada referensi (lintas browser) yang bagus yang benar-benar mencakup semua kasus? Misalnya http://www.websiteoptimization.com/speed/tweak/defer/ hanya berurusan dengan 6 dari mereka, dan menguji sebagian besar browser lama.
Karena saya khawatir tidak ada, inilah pertanyaan spesifik saya: Saya punya beberapa skrip kepala (eksternal) untuk inisialisasi dan pemuatan skrip. Lalu saya punya dua skrip inline statis di ujung badan. Yang pertama memungkinkan pemuat skrip secara dinamis menambahkan elemen skrip lain (merujuk js eksternal) ke tubuh. Skrip inline statis kedua ingin menggunakan js dari skrip eksternal yang ditambahkan. Bisakah ini bergantung pada yang lain yang telah dieksekusi (dan mengapa :-)?
sumber
Jawaban:
Jika Anda tidak secara dinamis memuat skrip atau menandainya sebagai
defer
atauasync
, maka skrip dimuat dalam urutan yang ditemukan di halaman. Tidak masalah apakah itu skrip eksternal atau skrip inline - skrip dieksekusi sesuai urutan yang ditemukan pada halaman. Skrip sebaris yang datang setelah skrip eksternal ditahan hingga semua skrip eksternal yang datang sebelum mereka dimuat dan dijalankan.Skrip Async (terlepas dari bagaimana mereka ditentukan sebagai async) memuat dan berjalan dalam urutan yang tidak terduga. Peramban memuatnya secara paralel dan bebas menjalankannya dalam urutan apa pun yang diinginkan.
Tidak ada urutan yang dapat diprediksi di antara banyak hal async. Jika seseorang membutuhkan pesanan yang dapat diprediksi, maka itu harus dikodekan dengan mendaftar untuk memuat notifikasi dari skrip async dan secara manual mengurutkan panggilan javascript ketika hal-hal yang sesuai dimuat.
Ketika tag skrip dimasukkan secara dinamis, bagaimana perilaku eksekusi akan tergantung pada browser. Anda dapat melihat bagaimana Firefox berperilaku dalam artikel referensi ini . Singkatnya, versi Firefox yang lebih baru default tag tag ditambahkan secara dinamis ke async kecuali tag script telah ditetapkan sebaliknya.
Tag skrip dengan
async
dapat dijalankan segera setelah dimuat. Faktanya, browser dapat menghentikan parser dari apa pun yang sedang dilakukan dan menjalankan skrip itu. Jadi, itu benar-benar dapat berjalan hampir kapan saja. Jika skrip di-cache, mungkin akan segera berjalan. Jika skrip membutuhkan waktu untuk memuat, skrip mungkin berjalan setelah parser selesai. Satu hal yang perlu diingatasync
adalah bahwa ia dapat berjalan kapan saja dan waktu itu tidak dapat diprediksi.Tag skrip dengan
defer
menunggu hingga seluruh pengurai selesai dan kemudian menjalankan semua skrip yang ditandai dengandefer
urutan mereka temui. Ini memungkinkan Anda untuk menandai beberapa skrip yang bergantung satu sama lain sebagaidefer
. Mereka semua akan ditunda sampai setelah parser dokumen selesai, tetapi mereka akan mengeksekusi dalam urutan yang mereka temui menjaga dependensi mereka. Saya pikirdefer
seperti skrip dijatuhkan ke dalam antrian yang akan diproses setelah parser selesai. Secara teknis, browser dapat mengunduh skrip di latar belakang kapan saja, tetapi mereka tidak akan menjalankan atau memblokir parser sampai setelah parser selesai mengurai halaman dan parsing serta menjalankan skrip inline apa pun yang tidak ditandaidefer
atauasync
.Berikut kutipan dari artikel itu:
Bagian yang relevan dari spesifikasi HTML5 (untuk peramban yang lebih baru) ada di sini . Ada banyak tulisan di sana tentang perilaku async. Jelas, spesifikasi ini tidak berlaku untuk browser yang lebih lama (atau browser yang tidak sesuai) yang perilakunya Anda mungkin harus menguji untuk menentukan.
Kutipan dari spesifikasi HTML5:
Bagaimana dengan skrip modul Javascript
type="module"
,?Javascript sekarang memiliki dukungan untuk memuat modul dengan sintaks seperti ini:
Atau, dengan
src
atribut:Semua skrip dengan
type="module"
secara otomatis diberidefer
atribut. Ini mengunduhnya secara paralel (jika tidak sebaris) dengan memuat halaman lain dan kemudian menjalankannya secara berurutan, tetapi setelah pengurai selesai.Modul skrip juga dapat diberikan
async
atribut yang akan menjalankan skrip modul inline sesegera mungkin, tidak menunggu hingga parser selesai dan tidak menunggu untuk menjalankanasync
skrip dalam urutan tertentu relatif terhadap skrip lain.Ada bagan waktu yang cukup berguna yang menunjukkan pengambilan dan pelaksanaan berbagai kombinasi skrip, termasuk skrip modul di sini dalam artikel ini: Javascript Module Loading .
sumber
defer
memberi parser kesempatan untuk memulai unduhannya lebih cepat sambil tetap menunda pelaksanaannya. Perhatikan bahwa jika Anda memiliki banyak skrip dari host yang sama, maka memulai pengunduhan lebih awal sebenarnya dapat memperlambat pengunduhan orang lain dari host yang sama (karena mereka bersaing untuk bandwidth) yang sedang ditunggu halaman Anda (yang tidakdefer
) jadi ini bisa menjadi pedang bermata dua.Browser akan menjalankan skrip sesuai urutan yang ditemukannya. Jika Anda memanggil skrip eksternal, skrip akan memblokir halaman hingga skrip dimuat dan dieksekusi.
Untuk menguji fakta ini:
Script yang ditambahkan secara dinamis dieksekusi segera setelah ditambahkan ke dokumen.
Untuk menguji fakta ini:
Urutan peringatan "ditambahkan" -> "halo!" -> "final"
Jika dalam skrip Anda mencoba mengakses elemen yang belum tercapai (contoh
<script>do something with #blah</script><div id="blah"></div>
:) maka Anda akan mendapatkan kesalahan.Secara keseluruhan, ya Anda dapat memasukkan skrip eksternal dan kemudian mengakses fungsi dan variabelnya, tetapi hanya jika Anda keluar dari
<script>
tag saat ini dan mulai yang baru.sumber
Ringkasan hebat oleh @addyosmani
Tanpa malu-malu disalin dari https://addyosmani.com/blog/script-priorities/
sumber
Setelah menguji banyak opsi, saya telah menemukan bahwa solusi sederhana berikut ini memuat skrip yang dimuat secara dinamis dalam urutan yang ditambahkan di semua browser modern.
sumber