2009-12-04 12 views
6

क्या कोई मुझे साबित कर सकता है कि उन्हें बदलने से पहले डोम तत्वों को हटाने के संबंध में here (नीचे कॉपी) की सलाह दी गई है और फिर उन्हें फिर से सम्मिलित करना हमेशा तेज है।जावास्क्रिप्ट प्रदर्शन - डोम रीफ्लो - Google आलेख

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

लेख ....

बाहर का प्रवाह डोम हेरफेर

यह पैटर्न हमें कई तत्वों को बनाने और उन्हें डोम एक भी पुनर्प्रवाहित ट्रिगर में डालने की सुविधा देता है। यह दस्तावेज़ फ्रेगमेंट नामक कुछ का उपयोग करता है। हम डीओएम के बाहर एक दस्तावेज़फ्रेगमेंट बनाते हैं (इसलिए यह प्रवाह के बाहर है)। इसके बाद हम इसमें कई तत्व बनाते हैं और जोड़ते हैं। अंत में, हम दस्तावेज़ तत्वों में सभी तत्वों को डीओएम में ले जाते हैं लेकिन एक एकल रिफ्लो ट्रिगर करते हैं। समस्या

चलिए एक ऐसा फ़ंक्शन बनाते हैं जो तत्व के भीतर सभी एंकरों के लिए क्लासनाम विशेषता को बदलता है। हम बस प्रत्येक एंकर के माध्यम से पुनरावृत्ति करके और अपने href विशेषताओं को अद्यतन करके ऐसा कर सकते हैं। समस्या यह है कि इससे प्रत्येक एंकर के लिए एक रिफ्लो हो सकता है।

function updateAllAnchors(element, anchorClass) { 
    var anchors = element.getElementsByTagName('a'); 
    for (var i = 0, length = anchors.length; i < length; i ++) { 
    anchors[i].className = anchorClass; 
    } 
} 

समाधान

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

/** 
* Remove an element and provide a function that inserts it into its original position 
* @param element {Element} The element to be temporarily removed 
* @return {Function} A function that inserts the element into its original position 
**/ 
function removeToInsertLater(element) { 
    var parentNode = element.parentNode; 
    var nextSibling = element.nextSibling; 
    parentNode.removeChild(element); 
    return function() { 
    if (nextSibling) { 
     parentNode.insertBefore(element, nextSibling); 
    } else { 
     parentNode.appendChild(element); 
    } 
    }; 
} 

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

function updateAllAnchors(element, anchorClass) { 
    var insertFunction = removeToInsertLater(element); 
    var anchors = element.getElementsByTagName('a'); 
    for (var i = 0, length = anchors.length; i < length; i ++) { 
    anchors[i].className = anchorClass; 
    } 
    insertFunction(); 
} 

उत्तर

5

आपको जावास्क्रिप्ट प्रोफाइलिंग से इसके लिए सार्थक आंकड़े प्राप्त करना मुश्किल लगेगा क्योंकि आप वास्तव में पश्चाताप और पुन: प्रवाह को बचाने पर हैं जो अधिकांश प्रोफाइलिंग टूल में दिखाई नहीं देंगे। आप Firebug paint events extension का उपयोग करके आपको यह दिखाने के लिए उपयोग कर सकते हैं कि आप कितने पश्चाताप कर रहे हैं।

+0

अच्छा विस्तार हालांकि दोनों उदाहरण मेरे लिए समान मात्रा में रेड्रॉज करते हैं। किसी भी मौके पर आप pastebin.me पर डेमो दे सकते हैं :) – redsquare

+0

मैं स्वीकार करूंगा कि एक्सटेंशन चीजों को बहुत धीमा कर देता है, इसलिए कभी-कभी कम्प्यूटेशनल हेवी ऑपरेशंस पर अंतर देखना मुश्किल हो सकता है। Google मानचित्र ज़ूमिंग। – Alex

1

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

एक समानता: यदि आप टॉय स्टोरी 4 पर काम कर रहे एक एनिमेटर थे, और निकट-फाइनल में आपको एक दृश्य के कपड़े भौतिकी में बदलाव करने के लिए आवश्यक परिवर्तन देखा गया था, तो क्या आप पूर्ण परिवर्तन करते समय अपने बदलाव करेंगे, विवरण का निरीक्षण करने के लिए विवरण फिर से प्रस्तुत करता है, या बनावट और रंग बंद कर देता है और संकल्प को कम करते समय संकल्प को कम करता है?

+0

मैं आंकड़े हैं:

यहाँ दस्तावेज खंडों के प्रदर्शन लाभ (जो वर्तमान में jQuery में उपयोग में हैं) पर जॉन Resig के नोट्स में से कुछ हैं। लाभ कहाँ हैं। सिद्धांत महान है। इराक की तरह WOMD था, देखो क्या हुआ। मैं अभी भी नहीं देखता कि यह जेएस को कैसे तेज बनाता है। मैंने इसे प्रोफाइल किया है और कोई फायदा नहीं देख सकता। बस आश्चर्य हुआ कि मैं क्या लापता था। – redsquare

+0

@redsquare: उस लेख का शीर्षक भ्रामक है, और कुछ तरीकों से गलत है। यह जेएस को जरूरी नहीं बनाता है ... यह ब्राउज़र को डोम प्रस्तुत करने के लिए तेज़ी से बनाता है। दूसरे शब्दों में, जेएस बस तेज़ (या यहां तक ​​कि धीमा) चला सकता है, लेकिन पृष्ठ तेजी से दिखाई देगा, क्योंकि ब्राउजर को कम समय में रिफ्लोइंग और रीपैंटिंग करना पड़ता है। ब्राउज़र और एचटीएमएल और सीएसएस प्रस्तुत करने का तरीका है बहाना और पुनर्भुगतान करना। जेएस प्रदर्शन ब्राउज़र प्रतिपादन प्रदर्शन के समान नहीं है। उदाहरण के तौर पर, तालिकाएं प्रस्तुत करने के लिए महंगी होती हैं, भले ही आपकी साइट में कोई जेएस न हो। – Pauan

+0

@redsquare: मुझे लगता है कि उन्होंने इसे "जावास्क्रिप्ट तेज करना" कहा है क्योंकि जेएस * आमतौर पर * चीज है जो रिफ्लो और पश्चाताप करता है। दूसरे शब्दों में, अपना जेएस कोड बदलकर, आप पृष्ठ को तेज़ी से प्रकट कर सकते हैं। लेकिन यह तेजी से दिखाई नहीं दे रहा है क्योंकि जेएस तेज़ है, यह तेजी से दिखाई दे रहा है क्योंकि ब्राउज़र कम हो रहा है और कम मरम्मत कर रहा है। उदाहरण के लिए, एक जावा एप्लेट जो डीओएम में हेरफेर करता है, उतना ही खराब होगा, इसलिए इसे "जावास्क्रिप्ट स्पीड" कहने के लिए गलत है। यह वास्तव में गति प्रदान करता है। – Pauan

2

मैंने पृष्ठ पर कुछ लिंक डाले और पृष्ठ में अभी भी तत्वों के साथ वर्ग नाम सेट करने की तुलना में आलेख में विधि का परीक्षण किया। मैंने फ़ायरफ़ॉक्स 3, आईई 8 और क्रोम 3 में कोशिश की।

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

किसी भी उचित संख्या में लिंक (कुछ हज़ार तक) के लिए, तत्वों को हटाने और जोड़ने के लिए थोड़ा धीमा है।

बहुत बड़ी संख्या में लिंक (10 000) के लिए, तत्वों को हटाने और जोड़ने के लिए थोड़ा तेज़ है।

हालांकि, अंतर काफी छोटा है। आपको किसी भी अंतर को ध्यान में रखने में सक्षम होने के लिए कई हज़ार लिंक होना चाहिए, और 10 000 लिंक पर अभी भी केवल 20% अंतर की तरह कुछ है।

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

0

पृष्ठ पर देखने के अलावा, एक रिफ्लो समाप्त होने पर कहने का कोई विश्वसनीय तरीका नहीं है।

बिताए गए समय की गणना करने वाले तत्वों को एक साथ या एक-एक करके तत्वों को जोड़ने या बदलने के लिए वही है। स्क्रिप्ट तत्वों के बीच ब्राउज़र की प्रतीक्षा नहीं करता है, ब्राउज़र पकड़ता है।

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

यदि आप यह नहीं बता सकते कि कौन सा बेहतर है, तो एक-एक-एक-एक-एक-एक-एक संस्करण देखने के लिए एक डिज़ाइनर प्राप्त करें- लेकिन दो डिज़ाइनर से न पूछें!

2

यह डोम के बजाए तत्वों को प्रारंभ करने के लिए दस्तावेज़ फ़्रेगमेंट्स का उपयोग करने जैसा ही कम है। दस्तावेज़ खंड तेजी से समाप्त होते हैं क्योंकि उनके पास चिंता करने के लिए रास्ता कम संरचना और वास्तविक प्रतिपादन होता है।

http://ejohn.org/blog/dom-documentfragments/

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