2009-03-24 9 views
27

मैं ब्राउज़र के भीतर एक डोम पेड़ को गहराई से क्लोन करने का सबसे प्रदर्शन करने वाला तरीका जानने की कोशिश कर रहा हूं।डीप क्लोनिंग बनाम आंतरिक HTML की सेटिंग: तेज़ क्या है?

अगर मैं क्या तेजी से हो जाएगा

var div = document.getElementById("source"); 
var markup = div.innerHTML; 

के साथ शुरू,

var target = div.cloneNode(true); 

या

var target = document.cloneNode(false); 
target.innerHTML = markup; 

मैं समझता हूँ ब्राउज़र मंच यहाँ एक बड़ा अंतर कर सकते हैं, इसलिए किसी भी असली दुनिया में इन तुलनाओं की सराहना के बारे में जानकारी की सराहना की जाएगी।

+0

मुझे वह चीज़ नहीं मिलती जो आप खोज रहे हैं। आप एक तत्व क्लोन करना चाहते हैं? 'var target = div.cloneNode (true); 'बस यही किया। क्लोनिंग को 'आंतरिक HTML' के साथ क्या करना है? –

+0

विशिष्ट परिणाम आपके ब्राउज़र पर निर्भर होंगे, लेकिन मुझे jsPerf [here] (http://jsperf.com/clonenode-vs-createelement-performance/39) पर दो प्रासंगिक परीक्षण मिले और [यहां] (http: // jsperf .com/innerclone/13)। – Blazemonger

+0

[आंतरिक HTML घटना श्रोताओं को नष्ट कर देता है] (http://stackoverflow.com/q/595808/1048572), इसका उपयोग न करें। – Bergi

उत्तर

48

चलो परीक्षण करें!

मैं StackOverflow के प्रश्न पृष्ठ की एक प्रति के लिए निम्न कोड जोड़ दिया था (पहले 100 ऑप्स के तीन रन मौजूदा स्क्रिप्ट को दूर करने, और चारों ओर uncommented हर बार timeit में से एक() के साथ खरोंच से चल रहा है,:

function timeit(f) { 
    var start= new Date(); 
    for (var i=100; i-->0;) { 
     f(); 
    } 
    return new Date()-start; 
} 

var c= document.getElementById('content'); 
var clones= []; 

//alert('cloneNode: '+timeit(function() { 
// clones.push(c.cloneNode(true)); 
//})) 

//alert('innerHTML: '+timeit(function() { 
// var d= document.createElement('div'); 
// d.innerHTML= c.innerHTML; 
// clones.push(d); 
//})) 

यहाँ एक कोर 2 Q9300 पर एक VirtualBox पर चल रहे परिणाम हैं: बहुत तेजी से innerHTML प्रति बनाने की बजाय

IE7 
cloneNode: 3238, 3235, 3187 
innerHTML: 8442, 8468, 8552 

Firefox3 
cloneNode: 1294, 1315, 1289 
innerHTML: 3593, 3636, 3580 

Safari3 
cloneNode: 207, 273, 237 
innerHTML: 805, 818, 786 

Chrome1 
cloneNode: 329, 377, 426 
innerHTML: 2327, 2536, 2865 

Opera10 
cloneNode: 801, 791, 771 
innerHTML: 1852, 1732, 1672 

तो cloneNode (सही) है बेशक यह हमेशा जा रहा था; पाठ में एक डोम serialising और। फिर इसे HTML से फिर से पार्स करना कठिन काम है। रीस डीओएम पर बच्चे के ऑपरेशन आमतौर पर धीमे होते हैं कि आप उन्हें एक-एक करके डालने/स्थानांतरित कर रहे हैं; क्लोन नोड जैसे सभी डीओएम ऑपरेशंस को ऐसा करने की ज़रूरत नहीं है।

सफारी आंतरिक रूप से आंतरिक HTML को अद्भुत रूप से करने का प्रबंधन करता है, लेकिन अभी भी क्लोन नोड जितना तेज़ी से नहीं करता है। आईई, जैसा कि अपेक्षित है, एक कुत्ता है।

तो, इंटीरियर HTML कहने वाले सभी लोगों के लिए ऑटो -1 एस स्पष्ट रूप से सवाल उठाए बिना सवाल उठाएगा कि वास्तव में क्या कर रहा था।

और हाँ, jQuery क्लोन के लिए आंतरिक HTML का उपयोग करता है। नहीं यह तेजी से हालांकि है, क्योंकि - स्रोत पढ़ें:

// IE copies events bound via attachEvent when 
// using cloneNode. Calling detachEvent on the 
// clone will also remove the events from the orignal 
// In order to get around this, we use innerHTML. 

jQuery Element.attachEvent का उपयोग करता है() अपने आप ही घटना प्रणाली को लागू करने, इसलिए स्वाभाविक रूप से यह है कि बग से बचने के लिए की जरूरत है। यदि आपको इसकी आवश्यकता नहीं है, तो आप ओवरहेड से बच सकते हैं।

[विषय से संबंधित नहीं एक तरफ: तब फिर से, मैं jQuery पकड़े अप बेस्ट प्रैक्टिस के शिखर के रूप में एक सा गलत हो सकता है, विशेष रूप से अगली पंक्ति को देखते हुए लगता है:

html.replace(/ jQuery\d+="(?:\d+|null)"/g, "") 

यह सही है - jQuery अपनी ही कहते हैं एचटीएमएल तत्वों के मनमाना गुण, और फिर उन्हें क्लोन करते समय उनसे छुटकारा पाने की आवश्यकता होती है (या अन्यथा उनके मार्कअप तक पहुंच प्रदान करती है, जैसे कि $()। html() विधि के माध्यम से)। यह काफी बदसूरत है, लेकिन फिर यह ऐसा करने का सबसे अच्छा तरीका है जो नियमित अभिव्यक्ति का उपयोग कर एचटीएमएल को संसाधित कर रहा है, जो कि मूलभूत गलती है जिसे आप भरोसेमंद 1-प्रतिष्ठा से अधिक उम्मीद करते हैं, दूसरे कॉमिंग बेस्ट जेएस के लेखक की तुलना में एसओ प्रश्नकर्ता फ्रेमवर्क इवर।

आशा है कि आपके पास अपनी टेक्स्ट सामग्री में कहीं भी "jQuery1 =" 2 "" स्ट्रिंग नहीं है, तो यदि आप बस रहस्यमय तरीके से इसे खो देते हैं। धन्यवाद jQuery! इस प्रकार ऑफ-विषय को अलग-अलग समाप्त होता है।]

+0

उत्कृष्ट analisys। एकमात्र छोटी बात यह है कि मैं लूप में हर बार, स्रोत आंतरिक HTML को पूर्व-क्रमबद्ध करने की तलाश में था। लेकिन यह अभी भी धीमा हो जाता है। धन्यवाद। – levik

+0

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

+0

मैं जो करना चाहता हूं वह एक HTML विशेषता के बजाय आईडी के लिए जेएस प्रॉपर्टी सेट करना होगा। आईई में एक बग है जहां गुणों को क्रमबद्ध किया गया है जैसे कि वे गुण थे, लेकिन यह केवल उस जगह पर जाता है जहां संपत्ति मूल्य एक आदिम डेटाटाइप है। ऑब्जेक्ट-प्रकार गुण 'आंतरिक HTML' में शामिल नहीं हैं। तो 'elementnode.jQueryId45438 = [1]' (एक ऐरे ऑब्जेक्ट) सेट करने से jQuery को सीरियलाइजेशन को गड़बड़ किए बिना तत्व पर अपनी अनूठी आईडी डालने की अनुमति मिल जाएगी और किसी भी पोस्ट-टर्मिनल फिक्सअप की आवश्यकता होगी। – bobince

-5

सामान्य आंतरिक HTML में तेज़ है। इसे देखें, benchmark across many platforms:

+0

यह तब उपयोगी होता है जब आप नए तत्व बना रहे हैं बल्कि उन्हें क्लोनिंग करते हैं –

1

हमम ... दिलचस्प बात है, मैंने अभी फ़ायरफ़ॉक्स 3 में एक परीक्षण किया है, और एक गहरा क्लोन आंतरिक HTML मार्ग जाने से लगभग 3 गुना तेज लगता है।

मुझे यकीन है कि आंतरिक HTML व्यक्तिगत डीओएम संचालन से अभी भी तेज है, लेकिन कम से कम गहरे क्लोनिंग के लिए, क्लोन नोड (सत्य) बेहतर अनुकूलित किया जाता है।

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

  • कोई संबंधित समस्या नहीं^_^