Saya menggunakan beberapa plugin, widget khusus, dan beberapa pustaka lain dari JQuery. sebagai hasilnya saya memiliki beberapa file .js dan .css. Saya perlu membuat loader untuk situs saya karena perlu beberapa waktu untuk memuat. alangkah baiknya jika saya dapat menampilkan loader sebelum mengimpor semua:
<script type="text/javascript" src="js/jquery-1.6.2.min.js"></script>
<script type="text/javascript" src="js/myFunctions.js"></script>
<link type="text/css" href="css/main.css" rel="stylesheet" />
...
....
etc
Saya telah menemukan beberapa tutorial yang memungkinkan saya mengimpor pustaka JavaScript secara asinkron. misalnya saya bisa melakukan sesuatu seperti:
(function () {
var s = document.createElement('script');
s.type = 'text/javascript';
s.async = true;
s.src = 'js/jquery-ui-1.8.16.custom.min.js';
var x = document.getElementsByTagName('script')[0];
x.parentNode.insertBefore(s, x);
})();
untuk beberapa alasan ketika saya melakukan hal yang sama untuk semua file saya, halaman tidak berfungsi. Saya telah berusaha begitu lama untuk mencoba menemukan di mana masalahnya tetapi saya tidak dapat menemukannya. Pertama saya pikir itu mungkin karena beberapa fungsi javascript bergantung pada yang lain. tetapi saya memuatnya dalam urutan yang benar menggunakan fungsi waktu habis ketika satu selesai saya melanjutkan dengan yang berikutnya dan halaman masih berperilaku aneh. misalnya saya tidak dapat mengklik tautan dll ... meskipun animasi masih berfungsi ..
Pokoknya
Inilah yang saya pikirkan ... Saya percaya browser memiliki cache, itulah sebabnya butuh waktu lama untuk memuat halaman untuk pertama kalinya dan kali berikutnya cepat. jadi yang saya pikirkan adalah mengganti halaman index.html saya dengan halaman yang memuat semua file ini secara asynchronous. ketika ajax selesai memuat semua file tersebut dialihkan ke halaman yang saya rencanakan untuk digunakan. saat menggunakan halaman itu seharusnya tidak membutuhkan waktu lama untuk memuat karena file-file tersebut harus sudah dimasukkan ke dalam cache browser. di halaman indeks saya (halaman tempat file .js dan .css dimuat secara asinkron), saya tidak peduli jika ada error. Saya hanya akan menampilkan loader dan mengarahkan halaman setelah selesai ...
Apakah ide ini alternatif yang bagus? atau haruskah saya terus mencoba menerapkan metode asynchronous?
EDIT
cara saya memuat semua asinkron seperti:
importScripts();
function importScripts()
{
//import: jquery-ui-1.8.16.custom.min.js
getContent("js/jquery-1.6.2.min.js",function (code) {
var s = document.createElement('script');
s.type = 'text/javascript';
//s.async = true;
s.innerHTML=code;
var x = document.getElementsByTagName('script')[0];
x.parentNode.insertBefore(s, x);
setTimeout(insertNext1,1);
});
//import: jquery-ui-1.8.16.custom.min.js
function insertNext1()
{
getContent("js/jquery-ui-1.8.16.custom.min.js",function (code) {
var s = document.createElement('script');
s.type = 'text/javascript';
s.innerHTML=code;
var x = document.getElementsByTagName('script')[0];
x.parentNode.insertBefore(s, x);
setTimeout(insertNext2,1);
});
}
//import: jquery-ui-1.8.16.custom.css
function insertNext2()
{
getContent("css/custom-theme/jquery-ui-1.8.16.custom.css",function (code) {
var s = document.createElement('link');
s.type = 'text/css';
s.rel ="stylesheet";
s.innerHTML=code;
var x = document.getElementsByTagName('script')[0];
x.parentNode.insertBefore(s, x);
setTimeout(insertNext3,1);
});
}
//import: main.css
function insertNext3()
{
getContent("css/main.css",function (code) {
var s = document.createElement('link');
s.type = 'text/css';
s.rel ="stylesheet";
s.innerHTML=code;
var x = document.getElementsByTagName('script')[0];
x.parentNode.insertBefore(s, x);
setTimeout(insertNext4,1);
});
}
//import: jquery.imgpreload.min.js
function insertNext4()
{
getContent("js/farinspace/jquery.imgpreload.min.js",function (code) {
var s = document.createElement('script');
s.type = 'text/javascript';
s.innerHTML=code;
var x = document.getElementsByTagName('script')[0];
x.parentNode.insertBefore(s, x);
setTimeout(insertNext5,1);
});
}
//import: marquee.js
function insertNext5()
{
getContent("js/marquee.js",function (code) {
var s = document.createElement('script');
s.type = 'text/javascript';
s.innerHTML=code;
var x = document.getElementsByTagName('script')[0];
x.parentNode.insertBefore(s, x);
setTimeout(insertNext6,1);
});
}
//import: marquee.css
function insertNext6()
{
getContent("css/marquee.css",function (code) {
var s = document.createElement('link');
s.type = 'text/css';
s.rel ="stylesheet";
s.innerHTML=code;
var x = document.getElementsByTagName('script')[0];
x.parentNode.insertBefore(s, x);
setTimeout(insertNext,1);
});
}
function insertNext()
{
setTimeout(pageReadyMan,10);
}
}
// get the content of url and pass that content to specified function
function getContent( url, callBackFunction )
{
// attempt to create the XMLHttpRequest and make the request
try
{
var asyncRequest; // variable to hold XMLHttpRequest object
asyncRequest = new XMLHttpRequest(); // create request object
// register event handler
asyncRequest.onreadystatechange = function(){
stateChange(asyncRequest, callBackFunction);
}
asyncRequest.open( 'GET', url, true ); // prepare the request
asyncRequest.send( null ); // send the request
} // end try
catch ( exception )
{
alert( 'Request failed.' );
} // end catch
} // end function getContent
// call function whith content when ready
function stateChange(asyncRequest, callBackFunction)
{
if ( asyncRequest.readyState == 4 && asyncRequest.status == 200 )
{
callBackFunction(asyncRequest.responseText);
} // end if
} // end function stateChange
dan bagian yang aneh adalah bahwa semua gaya bekerja ditambah semua fungsi javascript. halaman dibekukan karena beberapa alasan ...
sumber
document.head.appendChild
, namun ada beberapa masalah khusus dengan menambahkan skrip ke<head>
; tidak ada yang dapat mencegah skrip dimuat dan dijalankan.document.write
sebelum dokumen dimuat, skrip akan dijalankan secara sinkron sebagai bagian dari memuat laman, dan tidak akan menyertakan perilaku panggilan balik asinkron sendiri. Jika Anda membuat elemen skrip dan menambahkannya ke halaman, Anda akan memiliki akses untuk menambahkan event listener untuk memicu secara asinkron. tl; dr: itu tergantung bagaimana Anda memuat skrip dengan JS.Atribut 'async' baru HTML5 seharusnya melakukan trik. 'defer' juga didukung di sebagian besar browser jika Anda peduli dengan IE.
async - HTML
defer - HTML
Saat menganalisis kode unit iklan adsense baru, saya melihat atribut dan pencarian membawa saya ke sini: http://davidwalsh.name/html5-async
sumber
async
ataudefer
itu akan memblokir rendering saat dimuat. Pengaturanasync
akan memberitahukannya untuk tidak memblokir dan menjalankan skrip secepatnya. Pengaturandefer
akan memberitahukannya untuk tidak memblokir tetapi menunggu dengan menjalankan skrip sampai halaman selesai. Biasanya tidak ada masalah untuk menjalankan skrip secepatnya selama mereka tidak memiliki dependensi (mis. JQuery). Jika satu skrip memiliki ketergantungan pada yang lain, gunakanonLoad
untuk menunggu.Saya memuat skrip secara asinkron (html 5 memiliki fitur itu) ketika semua skrip selesai memuat, saya mengarahkan halaman ke index2.html di mana index2.html menggunakan perpustakaan yang sama. Karena browser memiliki cache setelah halaman dialihkan ke index2.html, index2.html dimuat dalam waktu kurang dari satu detik karena memiliki semua yang dibutuhkan untuk memuat halaman. Di halaman index.html saya juga memuat gambar yang saya rencanakan untuk digunakan sehingga browser menempatkan gambar-gambar itu di cache. jadi index.html saya terlihat seperti:
Hal menyenangkan lainnya tentang ini adalah saya dapat menempatkan loader di halaman dan ketika halaman selesai memuat loader akan hilang dan dalam hitungan milidetik halaman baru akan berjalan.
sumber
Contoh dari google
sumber
Beberapa catatan:
s.async = true
tidak terlalu benar untuk doctype HTML5, benars.async = 'async'
(sebenarnya menggunakantrue
benar , terima kasih kepada amn yang menunjukkannya di komentar di bawah)Karena ada alasan baru-baru ini untuk memuat file secara asinkron, tetapi secara berurutan, saya akan merekomendasikan cara yang lebih berorientasi fungsional daripada contoh Anda (hapus
console.log
untuk penggunaan produksi :)):sumber
s.async = true
adalah benar . Propertiasync
ditentukan secara eksplisit sebagai boolean dalam rekomendasi HTML 5 W3C di w3.org/TR/html5/scripting-1.html#attr-script-async . Anda mengacaukanasync
atribut denganasync
properti yang diekspos oleh objek yang mengimplementasikanHTMLScriptElement
antarmuka DOM. Memang, ketika memanipulasi atribut terkait dari elemen melalui sesuatu sepertiElement.setAttribute
, Anda harus menggunakanelement.setAttribute("async", "async")
karena semua atribut HTML adalah teks pertama dan terpenting.Berkat HTML5, Anda sekarang dapat mendeklarasikan skrip yang ingin Anda muat secara asinkron dengan menambahkan "asinkron" di tag:
Catatan: Atribut async hanya untuk skrip eksternal (dan sebaiknya hanya digunakan jika atribut src ada).
Catatan: Ada beberapa cara untuk mengeksekusi skrip eksternal:
Lihat ini: http://www.w3schools.com/tags/att_script_async.asp
sumber
Saya akan menyelesaikan jawaban zzzzBov dengan memeriksa keberadaan callback dan mengizinkan lewatnya argumen:
sumber
Berikut adalah solusi kontemporer yang bagus untuk pemuatan skrip asinkron meskipun hanya menangani skrip js dengan async false .
Ada artikel bagus yang ditulis di www.html5rocks.com - Selami perairan keruh pemuatan skrip .
Setelah mempertimbangkan banyak kemungkinan solusi, penulis menyimpulkan bahwa menambahkan skrip js ke akhir elemen badan adalah cara terbaik untuk menghindari pemblokiran perenderan halaman oleh skrip js.
Sementara itu, penulis menambahkan solusi alternatif lain yang bagus untuk orang-orang yang putus asa untuk memuat dan mengeksekusi skrip secara asinkron.
Mengingat Anda memiliki empat skrip bernama
script1.js, script2.js, script3.js, script4.js
maka Anda dapat melakukannya dengan menerapkan async = false :Sekarang, Spec mengatakan : Unduh bersama, jalankan secara berurutan segera setelah semua unduhan.
Firefox <3.6, Opera berkata: Saya tidak tahu apa itu "async", tapi kebetulan saya mengeksekusi skrip yang ditambahkan melalui JS sesuai urutan penambahannya.
Safari 5.0 mengatakan: Saya mengerti "async", tapi tidak mengerti menyetelnya ke "false" dengan JS. Saya akan menjalankan skrip Anda segera setelah mendarat, dalam urutan apa pun.
IE <10 mengatakan: Tidak tahu tentang "async", tetapi ada solusi untuk menggunakan "onreadystatechange".
Segala sesuatu yang lain mengatakan: Saya teman Anda, kami akan melakukan ini berdasarkan buku.
Sekarang, kode lengkap dengan IE <10 solusi:
sumber
Salah satu alasan mengapa skrip Anda dimuat dengan sangat lambat adalah jika Anda menjalankan semua skrip Anda saat memuat halaman, seperti ini:
dari pada:
Bit kedua dari skrip ini menunggu sampai browser telah memuat semua kode Javascript Anda sebelum mulai menjalankan skrip Anda, membuatnya tampak bagi pengguna bahwa halaman telah dimuat lebih cepat.
Jika Anda ingin meningkatkan pengalaman pengguna dengan mengurangi waktu pemuatan, saya tidak akan memilih opsi "layar pemuatan". Menurut pendapat saya itu akan jauh lebih menjengkelkan daripada hanya memuat halaman lebih lambat.
sumber
Saya sarankan Anda melihat Modernizr . Ini adalah pustaka kecil yang ringan sehingga Anda dapat memuat javascript secara asinkron dengan fitur yang memungkinkan Anda memeriksa apakah file dimuat dan mengeksekusi skrip di tempat lain yang Anda tentukan.
Berikut contoh loading jquery:
sumber
Saya menulis sedikit posting untuk membantu hal ini, Anda dapat membaca lebih lanjut di sini https://timber.io/snippets/asynchronously-load-a-script-in-the-browser-with-javascript/ , tetapi saya telah melampirkan kelas helper di bawah ini. Ini secara otomatis akan menunggu skrip untuk memuat dan mengembalikan atribut jendela yang ditentukan setelah itu.
Penggunaannya seperti ini:
sumber
Anda mungkin menemukan artikel wiki ini menarik: http://ajaxpatterns.org/On-Demand_Javascript
Ini menjelaskan bagaimana dan kapan menggunakan teknik tersebut.
sumber
Nah,
x.parentNode
mengembalikan elemen HEAD, jadi Anda memasukkan skrip tepat sebelum tag head. Mungkin itu masalahnya.Coba
x.parentNode.appendChild()
saja.sumber
Lihat https://github.com/stephen-lazarionok/async-resource-loader ini . Ini memiliki contoh yang menunjukkan bagaimana memuat JS, CSS dan banyak file dengan satu tembakan.
sumber
Anda dapat menggunakan LABJS atau RequreJS
Pemuat skrip seperti
LABJS
,RequireJS
akan meningkatkan kecepatan dan kualitas kode Anda.sumber
Apakah Anda pernah mempertimbangkan untuk Fetch Injection? Saya meluncurkan pustaka sumber terbuka yang disebut fetch-inject untuk menangani kasus seperti ini. Beginilah tampilan loader Anda menggunakan lib:
Untuk kompatibilitas mundur, deteksi fitur fitur dan kembali ke Injeksi XHR atau Elemen DOM Skrip, atau cukup sebariskan tag ke dalam halaman menggunakan
document.write
.sumber
Berikut adalah solusi khusus saya untuk menghilangkan JavaScript yang memblokir perenderan:
Singkatnya, itu memuat semua skrip Anda secara asinkron, dan kemudian mengeksekusinya secara konsekuen.
Repo Github : https://github.com/mudroljub/js-async-loader
sumber
No 'Access-Control-Allow-Origin' header is present on the requested resource
Di sini sedikit fungsi ES6 jika seseorang ingin menggunakannya di React misalnya
sumber
Saya akan menyarankan untuk melihat ke dalam mengecilkan file terlebih dahulu dan melihat apakah itu memberi Anda peningkatan kecepatan yang cukup besar. Jika host Anda lambat, dapat mencoba meletakkan konten statis tersebut di CDN.
sumber