2011-05-17 17 views
39

यदि मेरे पास उन बच्चों के साथ मूल तत्व है जिनके पास ईवेंट श्रोताओं को बाध्य किया गया है, तो क्या मुझे माता-पिता को साफ़ करने से पहले उन ईवेंट श्रोताओं को हटाने की ज़रूरत है? (यानी, parent.innerHTML = '';) अगर घटना श्रोताओं को डीओएम से हटा दिया जाता है तो क्या ईवेंट श्रोताओं को तत्व से अनबाउंड नहीं किया जा सकता है?क्या मुझे तत्वों को हटाने से पहले ईवेंट श्रोताओं को हटाने की आवश्यकता है?

उत्तर

24

लघु जवाब: हाँ

लांग जवाब: अधिकतर ब्राउज़र इस सही ढंग से संभाल और उन संचालकों खुद को हटा दें। कुछ पुराने ब्राउज़र हैं (आईई 6 और 7, अगर मुझे सही याद है) जो इसे गड़बड़ कर रहे हैं। हां, मेमोरी लीक हो सकती है। आपको इसके बारे में चिंता करने की ज़रूरत नहीं है, लेकिन आपको इसकी आवश्यकता है। this document पर एक नज़र डालें।

+0

वास्तव में: हालांकि अधिकांश मौजूदा ब्राउज़र इससे अधिक प्रभावित नहीं होंगे, आईई 7 अभी भी आमतौर पर उपयोग किया जाता है। इसके अलावा [जावास्क्रिप्ट में मेमोरी लीक पैटर्न] पर एक नज़र डालें (http://www.ibm.com/developerworks/web/library/wa-memleak/)। –

+6

क्या कोई इस ब्राउज़र को वर्तमान ब्राउज़र बाजार के लिए अपडेट करने के लिए पर्याप्त जानता है? या यह एक अलग सवाल के लायक है? आईई 7 मैंने सोचा था [बहुत अधिक चरणबद्ध] [http://theie7countdown.com/), जबकि [ie8] (http://theie8countdown.com/) अभी भी आसपास लटक रहा है। आईई 8 संभाल घटना श्रोताओं को संभालता है? –

+3

6 साल बाद, मुझे लगता है कि 'IE <10' को सुरक्षित रूप से बहिष्कृत माना जा सकता है और इस बिंदु पर याहू और एओएल के अलावा अन्य साइटों पर जाने वाले किसी भी व्यक्ति द्वारा उपयोग नहीं किया जा सकता है।कोई भी जो इस बिंदु पर आईई का अनियंत्रित रूप से उपयोग करता है, शायद किसी भारतीय फोन घोटाले से पीड़ित होने की संभावना अधिक है या किसी भी तरह से ब्राउज़र के अपने केकड़े को धीमा करने के साथ ईवेंट हैंडलर के साथ समस्या होने की तुलना में वायरस प्राप्त हो सकता है। –

21

बस यहां जानकारी अपडेट करने के लिए। मैं विभिन्न ब्राउज़रों का परीक्षण कर रहा हूं, विशेष रूप से आईफ्रेम ऑनलोड घटनाओं पर गोलाकार रूप से निर्भर घटना श्रोताओं के लिए मेमोरी लीक के लिए।

इस्तेमाल किया (jsfiddle स्मृति परीक्षण के साथ हस्तक्षेप, तो यह परीक्षण करने के लिए अपने खुद के सर्वर का उपयोग) कोड:

<div> 
    <label> 
     <input id="eventListenerCheckbox" type="checkbox" /> Clear event listener when removing iframe 
    </label> 
    <div> 
     <button id="startTestButton">Start Test</button> 
    </div> 
</div> 

<div> 
    <pre id="console"></pre> 
</div> 

<script> 

    (function() { 
     var consoleElement = document.getElementById('console'); 
     window.log = function(text) { 
      consoleElement.innerHTML = consoleElement.innerHTML + '<br>' + text; 
     }; 
    }()); 

    (function() { 
     function attachEvent(element, eventName, callback) { 
      if (element.attachEvent) 
      { 
       element.attachEvent(eventName, callback); 
      } 
      else 
      { 
       element[eventName] = callback; 
      } 
     } 

     function detachEvent(element, eventName, callback) { 
      if (element.detachEvent) 
      { 
       element.detachEvent(eventName, callback); 
      } 
      else 
      { 
       element[eventName] = null; 
      } 
     } 

     var eventListenerCheckbox = document.getElementById('eventListenerCheckbox'); 
     var startTestButton = document.getElementById('startTestButton'); 
     var iframe; 
     var generatedOnLoadEvent; 

     function createOnLoadFunction(iframe) { 
      var obj = { 
       increment: 0, 
       hugeMemory: new Array(100000).join('0') + (new Date().getTime()), 
       circularReference: iframe 
      }; 

      return function() { 
       // window.log('iframe onload called'); 
       obj.increment += 1; 
       destroy(); 
      }; 
     } 

     function create() { 
      // window.log('create called'); 
      iframe = document.createElement('iframe'); 

      generatedOnLoadEvent = createOnLoadFunction(iframe); 
      attachEvent(iframe, 'onload', generatedOnLoadEvent); 

      document.body.appendChild(iframe); 
     } 

     function destroy() { 
      // window.log('destroy called'); 
      if (eventListenerCheckbox.checked) 
      { 
       detachEvent(iframe, 'onload', generatedOnLoadEvent) 
      } 

      document.body.removeChild(iframe); 
      iframe = null; 
      generatedOnLoadEvent = null; 
     } 

     function startTest() { 
      var interval = setInterval(function() { 
       create(); 
      }, 100); 

      setTimeout(function() { 
       clearInterval(interval); 
       window.log('test complete'); 
      }, 10000); 
     } 

     attachEvent(startTestButton, 'onclick', startTest); 
    }()); 

</script> 

अगर कोई स्मृति रिसाव है, इस्तेमाल किया स्मृति के बाद 1000kb या उससे कम के आसपास में वृद्धि हो जाएगी परीक्षण चलाए जाते हैं। हालांकि, अगर स्मृति रिसाव है, तो स्मृति में लगभग 16,000kb की वृद्धि होगी। ईवेंट श्रोता को हटाने से पहले हमेशा कम स्मृति उपयोग (कोई रिसाव) में परिणाम नहीं होता है।

परिणाम:

  • IE6 - स्मृति रिसाव
  • IE7 - स्मृति रिसाव
  • IE8 - कोई स्मृति रिसाव
  • IE9 - स्मृति रिसाव (???)
  • IE10 - स्मृति रिसाव (???)
  • आईई 11 - कोई मेमोरी लीक
  • एज (20) - कोई मेमोरी लीक
  • क्रोम (50) - कोई मेमोरी लीक
  • फ़ायरफ़ॉक्स (46) - कहना मुश्किल है, बुरी तरह से रिसाव नहीं करता है, तो हो सकता है कि केवल अक्षम कचरा कलेक्टर? किसी स्पष्ट कारण के लिए अतिरिक्त 4 एमबी के साथ समाप्त होता है। रक्त स्राव बढ़त अनुप्रयोगों शायद घटना श्रोताओं नहीं हटाने के साथ भाग प्राप्त कर सकते हैं:
  • ओपेरा (36) - कोई स्मृति रिसाव

निष्कर्ष - कोई स्मृति

  • सफारी (9) रिसाव। लेकिन परेशान होने के बावजूद मैं अभी भी इसे अच्छा अभ्यास मानता हूं।

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

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