2012-01-25 19 views
194

HTML पृष्ठ में जावास्क्रिप्ट को शामिल करने के कई अलग-अलग तरीके हैं। मैं इन विकल्पों के बारे में पता है: या बाहरी यूआरआई स्क्रिप्ट के क्रम लोड और निष्पादित करें

  • < सिर> या < body> टैग में शामिल से लोड [1, 2]

    • इनलाइन कोड
    • होने से कोई भी, defer या async विशेषता (केवल बाहरी स्क्रिप्ट)
    • स्थिर स्रोत में शामिल है या अन्य स्क्रिप्ट्स (अलग-अलग पार्स राज्यों पर, विभिन्न विधियों के साथ) द्वारा गतिशील रूप से जोड़ा गया है

    हार्डडिस्क, जावास्क्रिप्ट: यूआरआई और onEvent-सामग्री [3] से ब्राउज़रों की गणना नहीं कर रहा है, जेएस निष्पादित करने के लिए पहले से ही 16 विकल्प हैं और मुझे यकीन है कि मैं कुछ भूल गया हूं।

    मैं तेजी से (समांतर) लोडिंग से इतना चिंतित नहीं हूं, मैं निष्पादन आदेश के बारे में अधिक उत्सुक हूं (जो लोडिंग ऑर्डर और document order पर निर्भर हो सकता है)। क्या कोई अच्छा (क्रॉस-ब्राउजर) संदर्भ है जो वास्तव में सभी मामलों को कवर करता है? ईजी। http://www.websiteoptimization.com/speed/tweak/defer/ केवल उनमें से 6 के साथ सौदा करता है, और ज्यादातर पुराने ब्राउज़र का परीक्षण करता है।

    जैसा कि मुझे डर है, यहां मेरा विशिष्ट प्रश्न है: मुझे प्रारंभिकरण और स्क्रिप्ट लोडिंग के लिए कुछ (बाहरी) प्रमुख स्क्रिप्ट मिल गई हैं। तब मुझे शरीर के अंत में दो स्थैतिक, इनलाइन स्क्रिप्ट मिल गई हैं। पहला व्यक्ति स्क्रिप्ट लोडर को गतिशील रूप से शरीर में एक और स्क्रिप्ट तत्व (बाह्य जेएस संदर्भित) जोड़ देता है। स्थैतिक, इनलाइन स्क्रिप्ट्स का दूसरा जोड़ा, बाहरी स्क्रिप्ट से जेएस का उपयोग करना चाहता है। क्या इसे दूसरे पर भरोसा किया जा सकता है (और क्यों :-)?

  • +0

    क्या आपने स्टीव साउडर द्वारा [अवरुद्ध किए बिना स्क्रिप्ट लोड हो रहा है] देखा है (https://www.stevesouders.com/blog/2009/04/27/loading-scripts-without-blocking/)? यह अब थोड़ा सा दिनांकित है, लेकिन अभी भी एक विशिष्ट स्क्रिप्ट लोडिंग तकनीक के बाद ब्राउज़र व्यवहार में कुछ मूल्यवान अंतर्दृष्टि शामिल है। –

    उत्तर

    239

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

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

    एकाधिक एसिंक चीजों के बीच कोई अनुमानित आदेश नहीं है। अगर किसी को अनुमानित आदेश की आवश्यकता होती है, तो उसे एसिंक स्क्रिप्ट से लोड अधिसूचनाओं के लिए पंजीकरण करके और उचित चीजें लोड होने पर मैन्युअल रूप से जावास्क्रिप्ट कॉल को अनुक्रमित करके कोड करना होगा।

    जब एक स्क्रिप्ट टैग गतिशील रूप से डाला जाता है, तो निष्पादन आदेश कैसे व्यवहार करता है ब्राउज़र पर निर्भर करेगा। आप देख सकते हैं कि फ़ायरफ़ॉक्स this reference article में कैसे व्यवहार करता है। संक्षेप में, फ़ायरफ़ॉक्स के नए संस्करण गतिशील रूप से जोड़े गए स्क्रिप्ट टैग को एसिंक में डिफ़ॉल्ट करते हैं जब तक स्क्रिप्ट टैग अन्यथा सेट नहीं किया जाता है।

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

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

    स्क्रिप्ट वाली स्क्रिप्ट IE और WebKit में एसिंक्रोनस रूप से निष्पादित, लेकिन तुल्यकालिक:

    यहाँ उस लेख से एक उद्धरण है।

    एचटीएमएल 5 spec (नए अनुपालन ब्राउज़रों के लिए) का प्रासंगिक हिस्सा here है। एसिंक व्यवहार के बारे में वहां बहुत कुछ लिखा गया है। जाहिर है, यह spec पुराने ब्राउज़र (या मैल-पुष्टिकरण ब्राउज़र) पर लागू नहीं होता है, जो व्यवहार है जिसे आपको निर्धारित करने के लिए शायद परीक्षण करना होगा।

    एचटीएमएल 5 कल्पना से एक उद्धरण:

    फिर, निम्नलिखित विकल्पों के उस स्थिति का वर्णन के पहले पालन किया जाना चाहिए: तत्व एक src विशेषता है, और तत्व है

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

    कार्य करने के लिए नेटवर्किंग कार्य स्रोत कार्य कतार पर फ़ंक्शन कतार पर रखता है यह कार्य पूरा करने के लिए तत्व को " पर पार्सर-निष्पादित" ध्वज सेट करना होगा। पार्सर स्क्रिप्ट निष्पादित करने में संभाल लेंगे।

    तत्व एक src विशेषता है, और तत्व के रूप में फ़्लैग किया गया है "पार्सर वाली", और तत्व एक async विशेषता तत्व दस्तावेज़ के लंबित पार्स-अवरुद्ध स्क्रिप्ट है नहीं है पार्सर जिसने तत्व बनाया है। (वहाँ एक बार में केवल दस्तावेज़ प्रति ऐसे ही एक स्क्रिप्ट हो सकता है।)

    कार्य उस कार्य कतार पर नेटवर्किंग कार्य स्रोत स्थानों एक बार प्राप्त कर रहा है एल्गोरिथ्म पूरा कर लिया है सेट करना होगा तत्व की ' करने के लिए तैयार हो parser- निष्पादित "ध्वज। पार्सर स्क्रिप्ट निष्पादित करने में संभाल लेंगे।

    तत्व एक src विशेषता नहीं है, तो, और तत्व है के रूप में "पार्सर वाली" चिह्नित किये, और HTML पार्सर या XML पार्सर कि स्क्रिप्ट तत्व बनाया के दस्तावेज एक शैली पत्रक है अवरुद्ध स्क्रिप्ट तत्व की लंबित पार्सिंग-अवरुद्ध स्क्रिप्ट है जो तत्व बनाते हुए पार्सर का दस्तावेज़ है। (केवल एक समय में प्रति दस्तावेज़ एक ऐसी स्क्रिप्ट हो सकती है।)

    तत्व "पार्सर-निष्पादित होने के लिए तैयार" ध्वज सेट करें। पार्सर स्क्रिप्ट निष्पादित करने में संभाल लेंगे।

    तत्व एक src विशेषता है, एक async विशेषता, नहीं है और "बल async" झंडा सेट तत्व स्क्रिप्ट होगा की सूची के अंत में जोड़ा जाना चाहिए नहीं है जितनी जल्दी संभव हो सके पर स्क्रिप्ट तत्व के दस्तावेज़ से जुड़े एक स्क्रिप्ट एल्गोरिदम तैयार करने के क्रम में निष्पादित करें।

    कार्य उस कार्य कतार पर नेटवर्किंग कार्य स्रोत स्थानों एक बार प्राप्त कर रहा है एल्गोरिथ्म पूरा कर लिया है के लिए निम्न चरण चलाना चाहिए:

    तत्व अब स्क्रिप्ट की सूची में पहले तत्व नहीं है, तो यह है कि जितनी जल्दी संभव हो सके इसे ऊपर जोड़ा गया था, फिर तत्व को तैयार के रूप में चिह्नित करें लेकिन के बिना इन चरणों को निरस्त करें।

    निष्पादन: स्क्रिप्ट की इस सूची में पहली स्क्रिप्ट तत्व से संबंधित स्क्रिप्ट ब्लॉक निष्पादित करें जो जितनी जल्दी हो सके निष्पादित करेगा।

    स्क्रिप्ट की इस सूची से पहला तत्व निकालें जो जल्द से जल्द निष्पादित करेगा।

    यदि स्क्रिप्ट की यह सूची जल्द से जल्द निष्पादित हो जाएगी अभी भी खाली नहीं है और पहली प्रविष्टि को पहले ही तैयार के रूप में चिह्नित किया गया है, तो निष्पादन लेबल वाले चरण पर वापस जाएं।

    तत्व एक src विशेषता तत्व स्क्रिप्ट है कि जैसे ही स्क्रिप्ट तत्व का दस्तावेज़ के संभव के रूप में समय में निष्पादित करेंगे एक स्क्रिप्ट एल्गोरिथ्म शुरू कर दिया तैयार की सेट में जोड़ा जाना चाहिए है।

    कार्य है कि नेटवर्किंग कार्य कतार एक बार प्राप्त कर रहा है एल्गोरिथ्म स्क्रिप्ट ब्लॉक पर अमल करना होगा पूरा कर लिया है और पर काम स्रोत स्थानों तो स्क्रिप्ट के सेट है कि संभव के रूप में जल्द ही के रूप में निष्पादित करेंगे से तत्व को हटा दें।

    अन्यथा उपयोगकर्ता एजेंट तुरंत स्क्रिप्ट ब्लॉक पर अमल करना होगा, भले ही अन्य लिपियों पहले से ही क्रियान्वित कर रहे हैं।

    +0

    उत्तर के लिए धन्यवाद, लेकिन समस्या यह है कि स्क्रिप्ट * गतिशील रूप से पृष्ठ में जोड़ा गया है, जिसका अर्थ है [इसे async माना जाता है] (http://stackoverflow.com/questions/3408805/is-the-async- गुण-संपत्ति-उपयोगी-अगर एक स्क्रिप्ट है-गतिशील वर्धित करने वाली)। या यह केवल में काम करता है? और मेरा अनुभव यह भी है कि उन्हें दस्तावेज़ आदेश में निष्पादित किया गया है? – Bergi

    +0

    @ बर्गि - यदि यह गतिशील रूप से जोड़ा गया है, तो यह एसिंक है और निष्पादन आदेश अनिश्चित है जब तक कि आप इसे नियंत्रित करने के लिए कोड नहीं लिखते। – jfriend00

    +0

    बस, [कोलिंक राज्य] (http://stackoverflow.com/a/8996905/1048572) विपरीत ... – Bergi

    11

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

    // file: test.php 
    sleep(10); 
    die("alert('Done!');"); 
    
    // HTML file: 
    <script type="text/javascript" src="test.php"></script> 
    

    गतिशील रूप से जोड़ा स्क्रिप्ट जैसे ही वे दस्तावेज़ के साथ जोड़े जाते क्रियान्वित कर रहे हैं:

    इस तथ्य का परीक्षण करने के।

    इस तथ्य का परीक्षण करने के: - "! हैलो"

    <!DOCTYPE HTML> 
    <html> 
    <head> 
        <title>Test</title> 
    </head> 
    <body> 
        <script type="text/javascript"> 
         var s = document.createElement('script'); 
         s.type = "text/javascript"; 
         s.src = "link.js"; // file contains alert("hello!"); 
         document.body.appendChild(s); 
         alert("appended"); 
        </script> 
        <script type="text/javascript"> 
         alert("final"); 
        </script> 
    </body> 
    </html> 
    

    अलर्ट के आदेश "संलग्न" है> -> "अंतिम"

    यदि किसी स्क्रिप्ट में आप उस तत्व तक पहुंचने का प्रयास करते हैं जो अभी तक नहीं पहुंचा है (उदाहरण: <script>do something with #blah</script><div id="blah"></div>) तो आपको एक त्रुटि मिलेगी।

    कुल मिलाकर, हाँ आप बाहरी स्क्रिप्ट शामिल कर सकते हैं और फिर अपने कार्यों और चरों तक पहुंच सकते हैं, लेकिन केवल तभी जब आप वर्तमान <script> टैग से बाहर निकलें और एक नया प्रारंभ करें।

    +0

    मैं उस व्यवहार की पुष्टि कर सकता हूं। लेकिन हमारे फीडबैक पृष्ठों पर संकेत हैं, यह केवल तभी काम कर सकता है जब test.php कैश किया जाता है। क्या आप इस बारे में कोई विशिष्ट/संदर्भ लिंक जानते हैं? – Bergi

    +4

    link.js अवरुद्ध नहीं है। लंबे समय तक डाउनलोड अनुकरण करने के लिए अपने PHP के समान एक स्क्रिप्ट का उपयोग करें। – 1983

    +10

    यह उत्तर गलत है। यह हमेशा ऐसा नहीं होता है कि "गतिशील रूप से जोड़े गए स्क्रिप्ट को दस्तावेज़ में संलग्न होने के तुरंत बाद निष्पादित किया जाता है"। कभी-कभी यह सच है (उदाहरण के लिए फ़ायरफ़ॉक्स के पुराने संस्करणों के लिए), लेकिन आमतौर पर यह नहीं है। निष्पादन आदेश, जैसा कि jfriend00 के उत्तर में उल्लिखित है, निर्धारित नहीं है। –

    संबंधित मुद्दे