क्या ब्राउज़र हर पेज लोड पर जावास्क्रिप्ट को पार्स करता है?


190

क्या ब्राउज़र (IE और फ़ायरफ़ॉक्स) पृष्ठ को ताज़ा करने के लिए हर बार लिंक की गई जावास्क्रिप्ट फ़ाइलों को पार्स करते हैं?

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

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


4
मेरा 2 सी: मुझे लगता है कि कैश्ड जावास्क्रिप्ट फ़ाइलों के प्रदर्शन के लाभ सार्थक अनुकूलन होने के लिए बहुत कम हैं।
इतय ममन

2
मेरे बेंचमार्क से, यह वास्तव में मायने रखता है। उदाहरण के लिए jQuery लोड समय लगभग 30msecs (एक तेज़ डेस्कटॉप मशीन पर) है, जिसमें से 20% केवल कोड को निष्पादन योग्य प्रतिनिधित्व में पार्स कर रहे हैं, और बाकी इसे निष्पादित कर रहा है, अर्थात इस मामले में jQuery ऑब्जेक्ट को इनिशियलाइज़ कर रहा है। यदि आप मोबाइल पर हैं, और आप दो या तीन पुस्तकालयों का उपयोग करते हैं, तो यह विलंब प्रासंगिक हो सकता है, क्योंकि जावास्क्रिप्ट निष्पादन अवरुद्ध है, और पेज अनिवार्य रूप से रिक्त है जब तक कि प्रत्येक जेएस स्क्रिप्ट को मेमोरी में लोड नहीं किया जाता है।
djjeck

जवाबों:


338

ये विवरण हैं जो मैं खोदने में सक्षम हूं। यह पहले ध्यान देने योग्य है कि हालांकि जावास्क्रिप्ट को आमतौर पर वीएम पर व्याख्या और चलाने के लिए माना जाता है, यह वास्तव में आधुनिक दुभाषियों के साथ ऐसा नहीं है, जो स्रोत को सीधे मशीन कोड (आईई के अपवाद के साथ) में संकलित करते हैं।


क्रोम: वी 8 इंजन

V8 में एक संकलन कैश है। इस स्टोर ने जावास्क्रिप्ट को 5 कचरा संग्रह के लिए स्रोत के हैश का उपयोग करके संकलित किया। इसका मतलब यह है कि स्रोत कोड के दो समान टुकड़े स्मृति में कैश प्रविष्टि को साझा करेंगे, भले ही वे कैसे शामिल किए गए थे। जब पृष्ठ पुनः लोड किए जाते हैं तो यह कैश साफ़ नहीं किया जाता है।

स्रोत


अपडेट - 19/03/2015

Chrome टीम ने जावास्क्रिप्ट स्ट्रीमिंग और कैशिंग के लिए अपनी नई तकनीकों के बारे में विवरण जारी किया है ।

  1. स्क्रिप्ट स्ट्रीमिंग

स्क्रिप्ट स्ट्रीमिंग जावास्क्रिप्ट फ़ाइलों के पार्सिंग का अनुकूलन करती है। [...]

संस्करण 41 में शुरू, क्रोम ने async और deferred लिपियों को एक अलग थ्रेड पर डाउनलोड करते ही शुरू कर दिया। इसका मतलब है कि डाउनलोडिंग समाप्त होने के बाद पार्सिंग सिर्फ मिलीसेकंड पूरा कर सकता है, और पृष्ठों में परिणाम 10% अधिक तेजी से होता है।

  1. कोड कैशिंग

आम तौर पर, वी 8 इंजन हर यात्रा पर पेज के जावास्क्रिप्ट को संकलित करता है, इसे निर्देश में बदल देता है जो एक प्रोसेसर समझता है। यह संकलित कोड एक बार पृष्ठ से दूर जाने पर उपयोगकर्ता द्वारा छोड़ दिया जाता है क्योंकि संकलित कोड संकलन समय पर मशीन की स्थिति और संदर्भ पर अत्यधिक निर्भर होता है।

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


ओपेरा: काराकन इंजन

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

इसलिए जावास्क्रिप्ट को पूरे पृष्ठ पर लोड किया गया है, एक ही स्क्रिप्ट के दो अनुरोधों के परिणामस्वरूप पुन: संकलन नहीं होगा।

स्रोत


फ़ायरफ़ॉक्स: स्पाइडरमोंकी इंजन

स्पाइडरमोंकी Nanojitअपने मूल बैक-एंड, एक जेआईटी संकलक के रूप में उपयोग करता है। मशीन कोड को संकलित करने की प्रक्रिया यहां देखी जा सकती है । संक्षेप में, यह लिपियों को पुनः लोड करने के रूप में प्रकट होता है। हालाँकि, अगर हम आंतरिक पर एक नज़र डालते हैं , तो Nanojitहम देखते हैं कि उच्च स्तर की निगरानी jstracer, जो संकलन को ट्रैक करने के लिए उपयोग की जाती है, संकलन के दौरान तीन चरणों के माध्यम से संक्रमण कर सकती है, एक लाभ प्रदान करता है Nanojit:

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

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

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

EDIT : यह बताया गया है कि मोज़िला डेवलपर बोरिस ज़बर्स्की ने कहा है कि गेको अभी तक संकलित स्क्रिप्ट को कैश नहीं करता हैइस SO उत्तर से लिया गया ।


सफारी: JavaScriptCore / SquirelFish इंजन

मुझे लगता है कि इस कार्यान्वयन का सबसे अच्छा जवाब पहले से ही किसी और ने दिया है

वर्तमान में हम bytecode (या मूल कोड) को कैश नहीं करते हैं। यह एक
विकल्प है जिसे हमने माना है, हालांकि, वर्तमान में, कोड पीढ़ी
जेएस निष्पादन समय का एक तुच्छ हिस्सा है (<2%), इसलिए हम
फिलहाल इसका पीछा नहीं कर रहे हैं ।

यह सफारी के प्रमुख डेवलपर, मैकियेज स्टाचोविक द्वारा लिखा गया था । इसलिए मुझे लगता है कि हम इसे सच मान सकते हैं।

मैं किसी भी अन्य जानकारी खोजने में असमर्थ था, लेकिन आप नवीनतम की गति सुधार के बारे में और अधिक पढ़ सकते SquirrelFish Extremeइंजन यहाँ , या स्रोत कोड ब्राउज़ यहाँ यदि आप रोमांच महसूस कर रहे हैं।


IE: चक्र इंजन

इस क्षेत्र में IE9 के जावास्क्रिप्ट इंजन (चक्र) के संबंध में कोई वर्तमान जानकारी नहीं है। अगर किसी को कुछ भी पता है, तो कृपया टिप्पणी करें।

यह काफी अनौपचारिक है, लेकिन IE के पुराने इंजन कार्यान्वयनों के लिए, एरिक लिपर्ट ( JScript का एक MS डेवलपर ) यहां एक ब्लॉग उत्तर में कहता है कि:

JScript क्लासिक इस अर्थ में संकलित भाषा की तरह काम करता है कि किसी भी JScript क्लासिक प्रोग्राम के चलने से पहले, हम पूरी तरह से वाक्यविन्यास कोड की जाँच करते हैं, एक पूर्ण पार्स ट्री जनरेट करते हैं, और एक बाईटेकोड उत्पन्न करते हैं। हम फिर एक बाईटेकोड दुभाषिया के माध्यम से बायटेकोड चलाते हैं। उस अर्थ में, JScript जावा के रूप में "संकलित" हर बिट है। अंतर यह है कि JScript आपको हमारे मालिकाना बायटेकोड को जारी रखने या उसकी जांच करने की अनुमति नहीं देता है । इसके अलावा, JECM बायोटेक की तुलना में बायटेकोड बहुत उच्च-स्तरीय है - JScript क्लासिक बायटेकोड भाषा पार्स ट्री के एक रैखिककरण की तुलना में थोड़ा अधिक है, जबकि JVM बायटेकोड स्पष्ट रूप से एक निम्न-स्तरीय स्टैक मशीन पर काम करने का इरादा है।

इससे पता चलता है कि बायटेकोड किसी भी तरह से कायम नहीं है, और इस तरह से बायटेकोड को कैश नहीं किया जाता है।


10
+1, उत्कृष्ट राइटअप। हालाँकि, फ़ायरफ़ॉक्स के बारे में, कृपया इस StackOverflow प्रश्न को देखें जहाँ मोज़िला डेवलपर बोरिस ज़बर्स्की बताते हैं कि गेको वर्तमान में ऐसा नहीं करता है।
18

धन्यवाद, मैंने देखा कि मेरी यात्रा में कोई अन्य सहायक साक्ष्य नहीं मिल सका। मैं इसके साथ उत्तर संपादित करूंगा।
जीवांश

1
ध्यान दें कि IE के बारे में क्या कहा गया था 2003 में: IE9 का JS इंजन पहली रिलीज 2011 में IE9 में था।
gsnedders

इसके अलावा, ओपेरा ने जेएस बायटेकोड को सिर्फ रीलोड से अधिक पर कैश किया। (उत्पन्न मशीन-कोड कैश नहीं है, हालांकि)।
gsnedders

2
@ जीवन एक स्रोत के रूप में ऊपर ले लो। (मैं काराकन टीम के लोगों में से एक हूं।)
gsnedders

12

ओपेरा ऐसा करता है, जैसा कि दूसरे उत्तर में बताया गया है। ( स्रोत )

फ़ायरफ़ॉक्स (स्पाइडरमोनी इंजन) बाईटेकोड को कैश नहीं करता है। ( स्रोत )

WebKit (Safari, Konqueror) bytecode को कैश नहीं करता है। ( स्रोत )

मुझे IE [6/7/8] या V8 (Chrome) के बारे में निश्चित नहीं है, मुझे लगता है कि IE कुछ प्रकार की कैशिंग कर सकता है जबकि V8 नहीं है। IE बंद स्रोत है इसलिए मुझे यकीन नहीं है, लेकिन V8 में कैश को "संकलित" कोड से कोई मतलब नहीं हो सकता है क्योंकि वे सीधे मशीन कोड पर संकलित करते हैं।


1
IE6–8 लगभग निश्चित रूप से नहीं होगा। IE9 हो सकता है, लेकिन मेरे पास कोई रास्ता नहीं है। संकलित JS संभावना कहीं भी कैश नहीं है क्योंकि यह अक्सर बहुत बड़ा है।
gsnedders

@gsnedders: मुझे यकीन नहीं है कि IE8 तकनीकी रूप से ऐसा नहीं कर सकता है, ऐसा लगता है कि यह भी बायटेकोड (आधिकारिक नहीं बल्कि करीबी) के लिए संकलित करता है , इसलिए इसे कैश नहीं करने का कोई तकनीकी कारण नहीं है। IE9 देशी कोड को संकलित करने के लिए एक JIT जोड़ता है।
cha0site

2
आईई द्वारा… हमेशा के लिए बायटेकोड का उपयोग किया गया है। यह IE8 में कुछ भी नया नहीं है। यह सिर्फ इतना है कि एक दुभाषिया दिया दुभाषिया का प्रदर्शन पार्स-टाइम की तुलना में इतना धीमा है कि यह पूरी तरह अप्रासंगिक है। IE9 में एक पूरी तरह से नया (खरोंच से) JS इंजन है, इसलिए दोनों के बीच कुछ भी नहीं है।
gsnedders

3

जहां तक ​​मुझे जानकारी है, केवल ओपेरा ने जावास्क्रिप्ट को पार्स किया है। अनुभाग "कैश्ड संकलित कार्यक्रम" यहां देखें


धन्यवाद, क्या आपके पास अन्य ब्राउज़र परिवार पर भी अधिक विवरण हैं?
अंजुल

2

यह कुछ भी नहीं है कि Google डार्ट स्पष्ट रूप से "स्नैपशॉट" के माध्यम से इस समस्या से निपटता है - लक्ष्य कोड के पूर्व संस्करण को लोड करके प्रारंभ और लोडिंग समय को गति देना है।

InfoQ में एक अच्छा राइटअप @ http://www.infoq.com/articles/google-dart है


0

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

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


0

ब्राउज़र निश्चित रूप से कैशिंग का उपयोग करता है, लेकिन हाँ, जब भी पृष्ठ ताज़ा होता है, तो ब्राउज़र हर बार जावास्क्रिप्ट को पार्स करता है। क्योंकि जब भी कोई पेज ब्राउजर द्वारा लोड किया जाता है, तो वह 2 पेड़ बनाता है 1. कंटेंट ट्री और 2. ट्री।

इस रेंडर ट्री में डोम तत्वों के दृश्य लेआउट के बारे में जानकारी शामिल है। इसलिए जब भी कोई पेज लोड होता है, तो जावास्क्रिप्ट को पार्स किया जाता है और जावास्क्रिप्ट द्वारा किसी भी गतिशील परिवर्तन को डोम तत्व, शो / हिडेन एलिमेंट को पोजिशन करना, ऐड / रिमूवल एलिमेंट ब्राउजर को रेंडर ट्री को दोबारा बनाने का कारण बनेगा। लेकिन एफएफ और क्रोम जैसे आधुनिक ब्रॉसर इसे थोड़ा अलग तरीके से संभालते हैं, उनके पास वृद्धिशील प्रतिपादन की अवधारणा है, इसलिए जब भी ऊपर बताए गए द्वारा जेएस द्वारा गतिशील परिवर्तन होते हैं, तो यह उन तत्वों को फिर से प्रस्तुत करने और फिर से प्रस्तुत करने का कारण होगा।

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