अतुल्यकालिक रूप से स्क्रिप्ट लोड करें


125

मैं JQuery से कई प्लगइन्स, कस्टम विगेट्स और कुछ अन्य पुस्तकालयों का उपयोग कर रहा हूं। परिणामस्वरूप मेरे पास कई .js और .css फ़ाइलें हैं। मुझे अपनी साइट के लिए लोडर बनाने की आवश्यकता है क्योंकि लोड करने में कुछ समय लगता है। यह अच्छा होगा अगर मैं सभी आयात करने से पहले लोडर प्रदर्शित कर सकता हूं:

<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

मुझे कई ट्यूटोरियल मिले हैं जो मुझे एसिंक्रोनस रूप से जावास्क्रिप्ट लाइब्रेरी आयात करने में सक्षम बनाते हैं। उदाहरण के लिए मैं कुछ ऐसा कर सकता हूं:

  (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);
    })();

किसी कारण से जब मैं अपनी सभी फाइलों के लिए वही काम करता हूं जो पृष्ठ काम नहीं करते हैं। मैं इतने लंबे समय से कोशिश कर रहा हूं कि जहां समस्या है, उसे ढूंढने की कोशिश करूं लेकिन मैं अभी इसे नहीं ढूंढ सका हूं। पहले मैंने सोचा कि यह शायद इसलिए था क्योंकि कुछ जावास्क्रिप्ट कार्य दूसरों पर निर्भर थे। लेकिन मैंने उन्हें सही क्रम में टाइम आउट फ़ंक्शन का उपयोग करके लोड किया जब एक पूरा किया मैं अगले के साथ आगे बढ़ा और पृष्ठ अभी भी अजीब व्यवहार करता है। उदाहरण के लिए मैं लिंक आदि पर क्लिक नहीं कर पा रहा हूँ ... एनिमेशन अभी भी काम करते हैं ..

वैसे भी

यहाँ मैं क्या सोच रहा हूँ ... मेरा मानना ​​है कि ब्राउज़रों के पास एक कैश है इसलिए पहली बार पृष्ठ लोड करने में बहुत समय लगता है और अगली बार यह जल्दी होता है। इसलिए मैं जो करने की सोच रहा हूं वह मेरे index.html पेज को एक ऐसे पेज के साथ बदल रहा है जो इस सभी फाइलों को अतुल्यकालिक रूप से लोड करता है। जब अजाक्स को उन सभी फाइलों को लोड करने के लिए किया जाता है, जो उस पृष्ठ पर पुनर्निर्देशित होती हैं, जिसका उपयोग करने की मेरी योजना है। उस पृष्ठ का उपयोग करते समय इसे लोड करने में लंबा समय नहीं लेना चाहिए क्योंकि फ़ाइलों को ब्राउज़र के कैश पर शामिल किया जाना चाहिए। मेरे अनुक्रमणिका पृष्ठ पर (पृष्ठ जहां .js और .css फ़ाइल अतुल्यकालिक रूप से लोड हो जाती है) मैं त्रुटियों को प्राप्त करने की परवाह नहीं करता। मैं बस एक लोडर प्रदर्शित कर रहा हूँ और जब किया पेज पुनः निर्देशित ...

क्या यह विचार एक अच्छा विकल्प है? या मुझे अतुल्यकालिक तरीकों को लागू करने की कोशिश करते रहना चाहिए?


संपादित करें

जिस तरह से मैं सब कुछ async लोड करता हूं वह इस तरह है:

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

और अजीब बात यह है कि सभी शैली का काम प्लस सभी जावास्क्रिप्ट कार्य करता है। पृष्ठ किसी कारण के लिए जमे हुए है, हालांकि ...

जवाबों:


176

Async लोडिंग के लिए कुछ समाधान:

//this function will work cross-browser for loading scripts asynchronously
function loadScript(src, callback)
{
  var s,
      r,
      t;
  r = false;
  s = document.createElement('script');
  s.type = 'text/javascript';
  s.src = src;
  s.onload = s.onreadystatechange = function() {
    //console.log( this.readyState ); //uncomment this line to see which ready states are called.
    if ( !r && (!this.readyState || this.readyState == 'complete') )
    {
      r = true;
      callback();
    }
  };
  t = document.getElementsByTagName('script')[0];
  t.parentNode.insertBefore(s, t);
}

यदि आपको पहले ही पेज पर jQuery मिल गया है, तो उपयोग करें:

$.getScript(url, successCallback)*

इसके अतिरिक्त, यह संभव है कि दस्तावेज़ लोड होने से पहले आपकी स्क्रिप्ट लोड / निष्पादित की जा रही है, जिसका अर्थ है कि आपको प्रतीक्षा करने की आवश्यकता होगी document.ready घटनाओं से पहले आप तत्वों के लिए बाध्य हो सकते हैं।

यह विशेष रूप से यह बताना संभव नहीं है कि कोड देखे बिना आपका मुद्दा क्या है।

सबसे सरल उपाय यह है कि आपकी सभी लिपियों को पृष्ठ के निचले भाग में इनलाइन रखा जाए, जिस तरह से वे HTML सामग्री के लोडिंग को ब्लॉक नहीं करते हैं जबकि वे निष्पादित होते हैं। यह प्रत्येक आवश्यक स्क्रिप्ट को अतुल्यकालिक रूप से लोड करने के मुद्दे से भी बचता है।

यदि आपके पास एक विशेष रूप से फैंसी इंटरैक्शन है जो हमेशा उपयोग नहीं किया जाता है जिसे किसी प्रकार की एक बड़ी स्क्रिप्ट की आवश्यकता होती है, तो उस विशेष स्क्रिप्ट को लोड करने से बचने के लिए उपयोगी हो सकता है जब तक कि इसकी आवश्यकता न हो (आलसी लोडिंग)।

* संभवतः भरी हुई लिपियों को $.getScriptकैश नहीं किया जाएगा


कोई भी व्यक्ति जो आधुनिक सुविधाओं जैसे कि Promiseवस्तु का उपयोग कर सकता है , के लिए loadScriptफ़ंक्शन काफी सरल हो गया है:

function loadScript(src) {
    return new Promise(function (resolve, reject) {
        var s;
        s = document.createElement('script');
        s.src = src;
        s.onload = resolve;
        s.onerror = reject;
        document.head.appendChild(s);
    });
}

ध्यान रखें कि यह संस्करण अब एक callbackतर्क को स्वीकार नहीं करता है क्योंकि लौटा हुआ वादा कॉलबैक को संभाल लेगा। जो पहले होता था वह loadScript(src, callback)अब होता loadScript(src).then(callback)

यह विफलताओं का पता लगाने और संभालने में सक्षम होने का अतिरिक्त बोनस है, उदाहरण के लिए कोई भी कॉल कर सकता है ...

loadScript(cdnSource)
    .catch(loadScript.bind(null, localSource))
    .then(successCallback, failureCallback);

... और यह इनायत से सीडीएन आउटेज को संभालेगा।


मैं उस कोशिश को शुरू करने वाला हूं। लेकिन अगर मैं पृष्ठ को एक अलग पृष्ठ पर पुनर्निर्देशित करता हूं तो मैं उन लिपियों को एक अलग पृष्ठ पर लोड करता हूं और उस पृष्ठ पर वही स्क्रिप्ट होती हैं जिन्हें लोड करने में समय नहीं लेना चाहिए। वे कैश में होना चाहिए? तो क्या मुझे इसके बजाय उस तकनीक को लागू नहीं करना चाहिए?
टोनो नाम

1
मैंने शरीर के स्थान पर बच्चे को हेड टैग में बदल दिया और जोड़ दिया ... ..var x = document.getElementsByTagName ('हेड') [0]; x.appendChild (रों);
टोनो नाम

1
@TonoNam, आप बस इस्तेमाल कर सकते हैं document.head.appendChild, हालाँकि इसमें स्क्रिप्ट जोड़ने के साथ कुछ आला मुद्दे हैं <head>; कुछ भी नहीं जो स्क्रिप्ट को लोड करने और निष्पादित करने से रोक देगा।
zzzzBov

1
मुझे t.parentNode.insertBefore (t.parent के विपरीत) का उपयोग करना था।
फिल लानास

1
@MuhammadUmer, यदि आप document.writeदस्तावेज़ को लोड करने से पहले एक अतिरिक्त स्क्रिप्ट टैग लिख रहे हैं , तो स्क्रिप्ट को पृष्ठ लोड करने के हिस्से के रूप में समकालिक रूप से निष्पादित किया जाएगा, और इसमें स्वयं पर कोई अतुल्यकालिक कॉलबैक व्यवहार शामिल नहीं होगा। यदि आप एक स्क्रिप्ट तत्व बना रहे हैं और इसे पृष्ठ पर जोड़ रहे हैं, तो आपके पास अतुल्यकालिक रूप से ट्रिगर करने के लिए इवेंट श्रोताओं को जोड़ने के लिए उपयोग होगा। tl; dr: यह इस बात पर निर्भर करता है कि आप स्क्रिप्ट को JS से कैसे लोड कर रहे हैं।
zzzzBov

33

एचटीएमएल 5 की नई 'एसिंक्स' विशेषता को करना है। यदि आप IE की परवाह करते हैं तो अधिकांश ब्राउज़रों में 'डेफर' भी समर्थित है।

async - HTML

<script async src="siteScript.js" onload="myInit()"></script>

defer - HTML

<script defer src="siteScript.js" onload="myInit()"></script>

नए adsense विज्ञापन इकाई कोड का विश्लेषण करते समय मैंने इस विशेषता पर ध्यान दिया और मुझे यहाँ खोजा गया: http://davidwalsh.name/html5-async


stackoverflow.com/questions/2774373/… पढ़ने के बाद मेरी समझ से , asyn लोडिंग के लिए नहीं है, लेकिन यह निर्धारित करने के लिए कि कब जावास्क्रिप्ट को चलाना है।
जैकडेव

9
आस्थगित विशेषता ब्राउज़र को स्क्रिप्ट के निष्पादन को स्थगित करने का कारण बनता है जब तक कि दस्तावेज़ लोड और पार्स नहीं किया गया है और हेरफेर करने के लिए तैयार है। Async विशेषता के कारण ब्राउज़र स्क्रिप्ट को जितनी जल्दी हो सके
चालू कर

1
"asyn लोडिंग के लिए नहीं है, लेकिन यह निर्धारित करने के लिए कि जावास्क्रिप्ट को कब चलाया जाए" यह विरोधाभासी नहीं है; सभी मामलों में, ब्राउज़र ASAP स्क्रिप्ट को लोड करना शुरू कर देगा। लेकिन बिना async या deferयह लोड करते समय रेंडरिंग को ब्लॉक कर देगा। सेटिंग asyncASAP को स्क्रिप्ट को ब्लॉक और चलाने के लिए नहीं बताएगी। सेटिंग deferयह बताएगी कि ब्लॉक न करें, लेकिन पेज चलने तक स्क्रिप्ट चलाने के साथ प्रतीक्षा करें । आमतौर पर ASAP स्क्रिप्ट को चलाने के लिए कोई समस्या नहीं है क्योंकि उनके पास कोई निर्भरता नहीं है (उदाहरण के लिए jQuery)। यदि किसी स्क्रिप्ट की दूसरे पर निर्भरता है, तो उसके onLoadलिए प्रतीक्षा करें।
स्टिजन डे विट

@StijndeWitt क्या होगा यदि न तो एसिंक्रोन और न ही निर्दिष्ट निर्दिष्ट करें?
मोहम्मद शरीफ C

@MohammedShareefC यदि आप न तो निर्दिष्ट करते हैं, तो आपको सिंक व्यवहार के समान कुछ मिलता है; ब्राउज़र आगे प्रसंस्करण को अवरुद्ध करता है जबकि यह स्क्रिप्ट को डाउनलोड और चलाता है। तो प्रभावी रूप से डिफ़ॉल्ट व्यवहार सिंक है। लेकिन क्योंकि यह प्रदर्शन के लिए हानिकारक है, ब्राउज़र इसके चारों ओर काम करेंगे जितना वे कर सकते हैं। वे सीएसएस आदि को पार्स करने, लोड करने और लगाने के साथ आगे बढ़ सकते हैं ... वे हालांकि अगली स्क्रिप्ट के टुकड़े को चलाना शुरू नहीं कर सकते। तो सामान ब्लॉक हो जाएगा। Async को सेट करके, आप ब्राउज़र को बता रहे हैं कि आगे जाना ठीक है और आप यह सुनिश्चित कर लेंगे कि आप इसे स्वयं काम करेंगे।
स्टिजन डे विट

8

मैंने स्क्रिप्ट को अतुल्यकालिक रूप से लोड किया है (html 5 में वह सुविधा है) जब सभी लिपियों को लोड करने के लिए मैंने पृष्ठ को index2.html पर पुनः निर्देशित कर दिया, जहां index2.html समान पुस्तकालयों का उपयोग करता है। क्योंकि ब्राउज़र में एक बार कैश होता है, जब पेज index2.html पर रीडायरेक्ट होता है, index2.html एक सेकंड से भी कम समय में लोड हो जाता है क्योंकि इसमें पेज लोड करने की आवश्यकता होती है। अपने index.html पेज में, मैं उन चित्रों को भी लोड करता हूं जो मैं उपयोग करने की योजना बनाता हूं ताकि ब्राउज़र उन छवियों को कैश पर रखें। इसलिए मेरा index.html ऐसा दिखता है:

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    <title>Project Management</title>

    <!-- the purpose of this page is to load all the scripts on the browsers cache so that pages can load fast from now on -->

    <script type="text/javascript">

        function stylesheet(url) {
            var s = document.createElement('link');
            s.type = 'text/css';
            s.async = true;
            s.src = url;
            var x = document.getElementsByTagName('head')[0];
            x.appendChild(s);
        }

        function script(url) {
            var s = document.createElement('script');
            s.type = 'text/javascript';
            s.async = true;
            s.src = url;
            var x = document.getElementsByTagName('head')[0];
            x.appendChild(s);
        }

        //load scritps to the catche of browser
        (function () {            
                stylesheet('css/custom-theme/jquery-ui-1.8.16.custom.css');
                stylesheet('css/main.css');
                stylesheet('css/marquee.css');
                stylesheet('css/mainTable.css');

                script('js/jquery-ui-1.8.16.custom.min.js');
                script('js/jquery-1.6.2.min.js');
                script('js/myFunctions.js');
                script('js/farinspace/jquery.imgpreload.min.js');
                script('js/marquee.js');            
        })();

    </script>

    <script type="text/javascript">
       // once the page is loaded go to index2.html
        window.onload = function () {
            document.location = "index2.html";
        }
    </script>

</head>
<body>

<div id="cover" style="position:fixed; left:0px; top:0px; width:100%; height:100%; background-color:Black; z-index:100;">Loading</div>

<img src="images/home/background.png" />
<img src="images/home/3.png"/>
<img src="images/home/6.jpg"/>
<img src="images/home/4.png"/>
<img src="images/home/5.png"/>
<img src="images/home/8.jpg"/>
<img src="images/home/9.jpg"/>
<img src="images/logo.png"/>
<img src="images/logo.png"/>
<img src="images/theme/contentBorder.png"/>

</body>
</html>

इसके बारे में एक और अच्छी बात यह है कि मैं पृष्ठ में एक लोडर रख सकता हूं और जब पृष्ठ लोड हो जाता है तो लोडर चला जाएगा और मिलीसेकंड के एक मैट में नया पृष्ठ चालू हो जाएगा।


1
@MohammedShareefC यह विडंबना है। सामान को प्रीलोड करने के लिए एक विशेष पेज एक अच्छा विचार एसईओ बुद्धिमान की तरह नहीं लगता है। प्रीलोडिंग महान है, लेकिन आपको इसे प्राप्त करने के लिए पुनर्निर्देशित करने की आवश्यकता नहीं है। बस एक छिपे हुए div में लिंक चिपकाएं और ब्राउज़र आपके लिए स्वचालित रूप से इसका ख्याल रखेगा। फिर पुनर्निर्देशित न करें बल्कि वास्तविक पृष्ठ को प्रस्तुत करें। COP-PASTERS READ THIS : कृपया इस HTML का कोई भी उपयोग करने से पहले कृपया ISO-88591 एन्कोडिंग को UTF-8 में बदल दें ताकि बाकी हम जल्द ही एन्कोडिंग नरक से बाहर निकल सकें। धन्यवाद!
स्टिजन डे विट

कृपया मेरा नया उत्तर देखें: stackoverflow.com/questions/7718935/load-scripts-asynchronously/…
asmmahmud

8

उदाहरण गूगल से

<script type="text/javascript">
  (function() {
    var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
    po.src = 'https://apis.google.com/js/plusone.js?onload=onLoadCallback';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
  })();
</script>

8

कई नोट:

  • s.async = trueएचटीएमएल 5 सिद्धांत के लिए बहुत सही नहीं है, सही है s.async = 'async'(वास्तव में उपयोग true सही है , एमएन के लिए धन्यवाद जिसने इसे टिप्पणी में बताया है नीचे )
  • आदेश को नियंत्रित करने के लिए टाइमआउट का उपयोग करना बहुत अच्छा और सुरक्षित नहीं है, और आप सभी टाइमआउट के योग के लिए लोडिंग समय को बहुत बड़ा बनाते हैं!

चूंकि अतुल्यकालिक रूप से फ़ाइलों को लोड करने का एक हालिया कारण है, लेकिन क्रम में, मैं आपके उदाहरण पर थोड़ा अधिक कार्यात्मक-संचालित तरीका सुझाऊंगा ( console.logउत्पादन उपयोग के लिए हटाएं :)):

(function() {
    var prot = ("https:"===document.location.protocol?"https://":"http://");

    var scripts = [
        "path/to/first.js",
        "path/to/second.js",
        "path/to/third.js"
    ];

    function completed() { console.log('completed'); }  // FIXME: remove logs

    function checkStateAndCall(path, callback) {
        var _success = false;
        return function() {
            if (!_success && (!this.readyState || (this.readyState == 'complete'))) {
                _success = true;
                console.log(path, 'is ready'); // FIXME: remove logs
                callback();
            }
        };
    }

    function asyncLoadScripts(files) {
        function loadNext() { // chain element
            if (!files.length) completed();
            var path = files.shift();
            var scriptElm = document.createElement('script');
            scriptElm.type = 'text/javascript';
            scriptElm.async = true;
            scriptElm.src = prot+path;
            scriptElm.onload = scriptElm.onreadystatechange = \
                checkStateAndCall(path, loadNext); // load next file in chain when
                                                   // this one will be ready 
            var headElm = document.head || document.getElementsByTagName('head')[0];
            headElm.appendChild(scriptElm);
        }
        loadNext(); // start a chain
    }

    asyncLoadScripts(scripts);
})();

4
s.async = trueहै सहीasyncW3C/ TR / html5 / scripting-1.html#attr-script-async पर W3C के HTML 5 सिफारिश में बूलियन के रूप में संपत्ति को स्पष्ट रूप से निर्दिष्ट किया गया है । आप DOM इंटरफ़ेस को लागू करने वाली वस्तुओं द्वारा उजागर की गई संपत्ति के साथ async विशेषता को भ्रमित कर रहे हैं । वास्तव में, जब कुछ के माध्यम से तत्व की संगत विशेषता को हेरफेर करते हैं , तो आपको उपयोग करना चाहिए क्योंकि सभी HTML विशेषताएँ पहले और सबसे महत्वपूर्ण पाठ हैं। asyncHTMLScriptElementElement.setAttributeelement.setAttribute("async", "async")
amn

"चूंकि हाल ही में फ़ाइलों को अतुल्यकालिक रूप से लोड करने का एक कारण है, लेकिन क्रम में, मैं आपके उदाहरण पर थोड़ा और अधिक कार्यात्मक-चालित तरीका सुझाऊंगा [...]"। मुझे पता है कि एसिंक्स आमतौर पर "बेहतर" है, लेकिन आप किस "हाल के" कारण का उल्लेख कर रहे हैं?
BluE

मैंने I if ((files.length) पूरा ’(); एक 'वापसी' जोड़ने: 'अगर (फाइलें!) (पूर्ण) {पूरा (); वापसी;} '
Fil

4

HTML5 के लिए धन्यवाद, अब आप उन लिपियों को घोषित कर सकते हैं जिन्हें आप टैग में "एसिंक्स" जोड़कर अतुल्यकालिक रूप से लोड करना चाहते हैं:

<script async>...</script>

नोट: Async विशेषता केवल बाहरी स्क्रिप्ट के लिए है (और इसका उपयोग केवल तभी किया जाना चाहिए जब src विशेषता मौजूद हो)।

नोट: बाहरी स्क्रिप्ट निष्पादित किए जाने के कई तरीके हो सकते हैं:

  • यदि async मौजूद है: स्क्रिप्ट को पृष्ठ के बाकी हिस्सों के साथ अतुल्यकालिक रूप से निष्पादित किया जाता है (पृष्ठ निष्पादित करते समय स्क्रिप्ट निष्पादित की जाएगी)
  • यदि async मौजूद नहीं है और defer मौजूद है: पृष्ठ निष्पादित होने पर स्क्रिप्ट निष्पादित हो जाती है
  • यदि न तो एसिंक्स या डेफ़र मौजूद है: ब्राउज़र को पेज को जारी रखने से पहले स्क्रिप्ट को तुरंत लाया और निष्पादित किया जाता है

इसे देखें: http://www.w3schools.com/tags/att_script_async.asp


2

मैं कॉलबैक की उपस्थिति के लिए एक चेक के साथ zzzzBov के उत्तर को पूरा करूंगा और तर्क पारित करने की अनुमति दूंगा:

    function loadScript(src, callback, args) {
      var s, r, t;
      r = false;
      s = document.createElement('script');
      s.type = 'text/javascript';
      s.src = src;
      if (typeof(callback) === 'function') {
        s.onload = s.onreadystatechange = function() {
          if (!r && (!this.readyState || this.readyState === 'complete')) {
            r = true;
            callback.apply(args);
          }
        };
      };
      t = document.getElementsByTagName('script')[0];
      t.parent.insertBefore(s, t);
    }

2

यहाँ अतुल्यकालिक स्क्रिप्ट लोड करने के लिए एक महान समकालीन समाधान है, हालांकि यह केवल async झूठी के साथ js स्क्रिप्ट को संबोधित करता है ।

Www.html5rocks.com में एक बेहतरीन लेख लिखा गया है - स्क्रिप्ट लोडिंग के पानी में गहरी डुबकी

कई संभावित समाधानों पर विचार करने के बाद, लेखक ने निष्कर्ष निकाला कि बॉडी एलिमेंट के अंत में js लिपियों को जोड़ना js लिपियों द्वारा पेज रेंडरिंग से बचने का सबसे अच्छा संभव तरीका है।

इस बीच, लेखक ने उन लोगों के लिए एक और अच्छा वैकल्पिक समाधान जोड़ा, जो अतुल्यकालिक रूप से स्क्रिप्ट को लोड करने और निष्पादित करने के लिए बेताब हैं।

आपके द्वारा नामित चार लिपियों को ध्यान में रखते हुए आप इसे async = false लगाने केscript1.js, script2.js, script3.js, script4.js साथ कर सकते हैं :

[
  'script1.js',
  'script2.js',
  'script3.js',
  'script4.js'
].forEach(function(src) {
  var script = document.createElement('script');
  script.src = src;
  script.async = false;
  document.head.appendChild(script);
});

अब, युक्ति का कहना है : एक साथ डाउनलोड करें, सभी डाउनलोड होते ही क्रम में निष्पादित करें।

फ़ायरफ़ॉक्स <3.6, ओपेरा कहते हैं: मुझे नहीं पता कि यह "async" बात क्या है, लेकिन यह सिर्फ इतना होता है कि मैं जेएस के माध्यम से जोड़े गए स्क्रिप्ट को निष्पादित कर रहा हूं ताकि वे जोड़ रहे हैं।

सफारी 5.0 कहता है: मैं "async" समझता हूँ, लेकिन इसे JS के साथ "असत्य" सेट करना नहीं समझता। जैसे ही वे भूमि पर आएँगे, मैं आपकी लिपियों पर अमल करूँगा।

IE <10 कहते हैं: "async" के बारे में कोई विचार नहीं है, लेकिन "onreadystatechange" का उपयोग कर एक समाधान है।

बाकी सब कहते हैं: मैं तुम्हारा दोस्त हूं, हम किताब द्वारा ऐसा करने जा रहे हैं।

अब, IE <10 समाधान के साथ पूर्ण कोड:

var scripts = [
  'script1.js',
  'script2.js',
  'script3.js',
  'script4.js'
];
var src;
var script;
var pendingScripts = [];
var firstScript = document.scripts[0];

// Watch scripts load in IE
function stateChange() {
  // Execute as many scripts in order as we can
  var pendingScript;
  while (pendingScripts[0] && ( pendingScripts[0].readyState == 'loaded' || pendingScripts[0].readyState == 'complete' ) ) {
    pendingScript = pendingScripts.shift();
    // avoid future loading events from this script (eg, if src changes)
    pendingScript.onreadystatechange = null;
    // can't just appendChild, old IE bug if element isn't closed
    firstScript.parentNode.insertBefore(pendingScript, firstScript);
  }
}

// loop through our script urls
while (src = scripts.shift()) {
  if ('async' in firstScript) { // modern browsers
    script = document.createElement('script');
    script.async = false;
    script.src = src;
    document.head.appendChild(script);
  }
  else if (firstScript.readyState) { // IE<10
    // create a script and add it to our todo pile
    script = document.createElement('script');
    pendingScripts.push(script);
    // listen for state changes
    script.onreadystatechange = stateChange;
    // must set src AFTER adding onreadystatechange listener
    // else we’ll miss the loaded event for cached scripts
    script.src = src;
  }
  else { // fall back to defer
    document.write('<script src="' + src + '" defer></'+'script>');
  }
}

1

आपकी स्क्रिप्ट इतनी धीरे-धीरे लोड हो सकती है इसका एक कारण यह है कि यदि आप पेज लोड करते समय अपनी सभी स्क्रिप्ट चला रहे हैं, तो इस तरह से:

callMyFunctions();

के बजाय:

$(window).load(function() {
      callMyFunctions();
});

स्क्रिप्ट का यह दूसरा बिट इंतजार करता है जब तक कि ब्राउज़र ने आपके सभी जावास्क्रिप्ट कोड को पूरी तरह से लोड नहीं किया है, इससे पहले कि वह आपकी किसी भी स्क्रिप्ट को निष्पादित करना शुरू कर दे, यह उपयोगकर्ता को दिखाई देता है कि पेज तेजी से लोड हुआ है।

यदि आप लोडिंग समय कम करके उपयोगकर्ता के अनुभव को बढ़ाने के लिए देख रहे हैं, तो मैं "लोडिंग स्क्रीन" विकल्प के लिए नहीं जाऊंगा। मेरी राय में कि पृष्ठ लोड अधिक धीरे-धीरे होने की तुलना में बहुत अधिक कष्टप्रद होगा।


1

मेरा सुझाव है कि आप मॉर्डनिज़र पर एक नज़र डालें । इसकी एक छोटी सी लाइट वेट लाइब्रेरी जिसे आप अपने जावास्क्रिप्ट को उन विशेषताओं के साथ लोड कर सकते हैं जो आपको यह जांचने की अनुमति देती हैं कि क्या फ़ाइल लोड की गई है और आपके द्वारा निर्दिष्ट अन्य में स्क्रिप्ट निष्पादित करें।

यहाँ लोडिंग jquery का एक उदाहरण है:

Modernizr.load([
  {
    load: '//ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.js',
    complete: function () {
      if ( !window.jQuery ) {
            Modernizr.load('js/libs/jquery-1.6.1.min.js');
      }
    }
  },
  {
    // This will wait for the fallback to load and
    // execute if it needs to.
    load: 'needs-jQuery.js'
  }
]);

1

मैंने इसके साथ मदद करने के लिए एक छोटी सी पोस्ट लिखी है, आप यहाँ और अधिक पढ़ सकते हैं https://timber.io/snippets/asynchronously-load-a-script-in-the-browser-with-javascript/ , लेकिन मैंने संलग्न किया है नीचे सहायक वर्ग। यह स्वचालित रूप से एक स्क्रिप्ट के लिए एक निर्दिष्ट विंडो विशेषता को लोड और वापस करने के लिए प्रतीक्षा करेगा।

export default class ScriptLoader {
  constructor (options) {
    const { src, global, protocol = document.location.protocol } = options
    this.src = src
    this.global = global
    this.protocol = protocol
    this.isLoaded = false
  }

  loadScript () {
    return new Promise((resolve, reject) => {
      // Create script element and set attributes
      const script = document.createElement('script')
      script.type = 'text/javascript'
      script.async = true
      script.src = `${this.protocol}//${this.src}`

      // Append the script to the DOM
      const el = document.getElementsByTagName('script')[0]
      el.parentNode.insertBefore(script, el)

      // Resolve the promise once the script is loaded
      script.addEventListener('load', () => {
        this.isLoaded = true
        resolve(script)
      })

      // Catch any errors while loading the script
      script.addEventListener('error', () => {
        reject(new Error(`${this.src} failed to load.`))
      })
    })
  }

  load () {
    return new Promise(async (resolve, reject) => {
      if (!this.isLoaded) {
        try {
          await this.loadScript()
          resolve(window[this.global])
        } catch (e) {
          reject(e)
        }
      } else {
        resolve(window[this.global])
      }
    })
  }
}

उपयोग इस प्रकार है:

const loader = new Loader({
    src: 'cdn.segment.com/analytics.js',
    global: 'Segment',
})

// scriptToLoad will now be a reference to `window.Segment`
const scriptToLoad = await loader.load()

1

आपको यह विकी लेख दिलचस्प लग सकता है: http://ajaxpatterns.org/On-Demand_Javascript

यह बताता है कि ऐसी तकनीक का उपयोग कैसे और कब करना है।


दुर्भाग्य से, लिंक मृत प्रतीत होता है। :(
एरिक Seastrand

@ ऐसा इसलिए है क्योंकि यह डायनामिकली लोडिंग कोड का एक प्राचीन तरीका है: D
tereško

0

ठीक है, x.parentNodeहेड तत्व लौटाता है, इसलिए आप हेड टैग से ठीक पहले स्क्रिप्ट डाल रहे हैं। शायद यही समस्या है।

x.parentNode.appendChild()इसके बजाय कोशिश करें ।


0

इस https://github.com/stephen-lazarionok/async-resource-loader को देखें । इसका एक उदाहरण है कि एक शॉट के साथ जेएस, सीएसएस और कई फ़ाइलों को लोड करने का तरीका दिखाया गया है।


Jquery निर्भरता से छुटकारा पाने के लिए इसे थोड़ा बदलना संभव है
स्टीफन एल।

0

आप LABJS या RequreJS का उपयोग कर सकते हैं

स्क्रिप्ट लोडर जैसे LABJS, RequireJSआपके कोड की गति और गुणवत्ता में सुधार करेगा।


0

क्या आपने Fetch Injection का उपयोग करने पर विचार किया है? मैंने इस तरह के मामलों को संभालने के लिए एक ओपन सोर्स लाइब्रेरी लाईच-इंजेक्ट नाम से लुढ़काया । यहां बताया गया है कि आपका लोडर लीब का उपयोग करके कैसा दिख सकता है:

fetcInject([
  'js/jquery-1.6.2.min.js',
  'js/marquee.js',
  'css/marquee.css',
  'css/custom-theme/jquery-ui-1.8.16.custom.css',
  'css/main.css'
]).then(() => {
  'js/jquery-ui-1.8.16.custom.min.js',
  'js/farinspace/jquery.imgpreload.min.js'
})

बैकवर्ड संगतता लाभ उठाने के लिए एक्सएचआर इंजेक्शन या स्क्रिप्ट डोम तत्वों का पता लगाने और गिरने-वापस करने या उपयोग करने वाले पृष्ठ में केवल टैग इनलाइन करें document.write


0

जावास्क्रिप्ट को रेंडर करने वाले ब्लॉक को खत्म करने के लिए मेरा कस्टम समाधान है:

// put all your JS files here, in correct order
const libs = {
  "jquery": "https://code.jquery.com/jquery-2.1.4.min.js",
  "bxSlider": "https://cdnjs.cloudflare.com/ajax/libs/bxslider/4.2.5/jquery.bxslider.min.js",
  "angular": "https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0-beta.2/angular.min.js",
  "ngAnimate": "https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0-beta.2/angular-animate.min.js"
}
const loadedLibs = {}
let counter = 0

const loadAsync = function(lib) {
  var http = new XMLHttpRequest()
  http.open("GET", libs[lib], true)
  http.onload = () => {
    loadedLibs[lib] = http.responseText
    if (++counter == Object.keys(libs).length) startScripts()
  }
  http.send()
}

const startScripts = function() {
  for (var lib in libs) eval(loadedLibs[lib])
  console.log("allLoaded")
}

for (var lib in libs) loadAsync(lib)

संक्षेप में, यह आपकी सभी लिपियों को अतुल्यकालिक रूप से लोड करता है, और फिर उन्हें परिणामस्वरूप निष्पादित करता है।

गितुब रेपो : https://github.com/mudroljub/js-async-loader


1
काम नहीं करता हैNo 'Access-Control-Allow-Origin' header is present on the requested resource
अब्राम

1
वह कोरस समस्या है। stackoverflow.com/questions/20035101/…
दामजन पाव्लिका

0

यहां थोड़ा ईएस 6 कार्य करता है यदि कोई उदाहरण के लिए रिएक्ट में इसका उपयोग करना चाहता है

import {uniqueId} from 'lodash' // optional
/**
 * @param {String} file The path of the file you want to load.
 * @param {Function} callback (optional) The function to call when the script loads.
 * @param {String} id (optional) The unique id of the file you want to load.
 */
export const loadAsyncScript = (file, callback, id) => {
  const d = document
  if (!id) { id = uniqueId('async_script') } // optional
  if (!d.getElementById(id)) {
    const tag = 'script'
    let newScript = d.createElement(tag)
    let firstScript = d.getElementsByTagName(tag)[0]
    newScript.id = id
    newScript.async = true
    newScript.src = file
    if (callback) {
      // IE support
      newScript.onreadystatechange = () => {
        if (newScript.readyState === 'loaded' || newScript.readyState === 'complete') {
          newScript.onreadystatechange = null
          callback(file)
        }
      }
      // Other (non-IE) browsers support
      newScript.onload = () => {
        callback(file)
      }
    }
    firstScript.parentNode.insertBefore(newScript, firstScript)
  } else {
    console.error(`The script with id ${id} is already loaded`)
  }
}


-3

मैं सुझाव दूंगा कि आप पहले फाइलों को छोटा करें और देखें कि क्या इससे आपको बड़ी गति मिलती है। यदि आपका होस्ट धीमा है, तो उस स्थिर सामग्री को CDN पर डालने का प्रयास कर सकते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.