উপাদানগুলি সরানোর আগে আমার কি ইভেন্ট শ্রোতাদের সরানোর দরকার আছে?


85

যদি আমার ইভেন্টের শ্রোতাদের সাথে আবদ্ধ বাচ্চাদের সাথে আমার পিতামাতার উপাদান থাকে তবে পিতামাতার সাফ করার আগে আমার কি সেই ইভেন্ট শ্রোতাদের অপসারণ করা দরকার? (যেমন, parent.innerHTML = '';) ইভেন্ট শ্রোতারা যদি ডিওএম থেকে অপসারণ করা হয় তবে কোনও উপাদান থেকে আনবাউন্ড না থাকলে মেমরি ফাঁস হতে পারে?

উত্তর:


51

সংক্ষিপ্ত উত্তর: হ্যাঁ

দীর্ঘ উত্তর: বেশিরভাগ ব্রাউজারগুলি এটিকে সঠিকভাবে পরিচালনা করে এবং সেগুলি হ্যান্ডলারগুলি নিজেরাই সরিয়ে দেয়। কিছু পুরানো ব্রাউজার রয়েছে (আই 6 এবং 7, যদি আমি সঠিকভাবে স্মরণ করি) তবে এটি গণ্ডগোল করছে। হ্যাঁ, মেমরি ফুটো হতে পারে। আপনার এই সম্পর্কে চিন্তা করা উচিত নয়, তবে আপনার প্রয়োজন। কটাক্ষপাত আছে এই দস্তাবেজটি


প্রকৃতপক্ষে: যদিও বেশিরভাগ বর্তমান ব্রাউজারগুলি এ থেকে খুব বেশি ক্ষতিগ্রস্থ হবে না, আই আই 7 এখনও সাধারণভাবে ব্যবহৃত হয়। জাভাস্ক্রিপ্টে মেমরি ফাঁসের নিদর্শনগুলি দেখুন ।
মার্সেল করপেল

7
কেউ কি বর্তমান ব্রাউজারের বাজারের জন্য এটি আপডেট করার মতো যথেষ্ট জ্ঞানযোগ্য? নাকি এটাই আলাদা প্রশ্ন? আই 7 আমি ভেবেছিলাম বেশ কিছুটা পর্যায়ক্রমে বের হয়ে গেছে , যখন ie8 এখনও চারদিকে ঝুলছে। আইই 8 কি পরিত্যক্ত ইভেন্ট শ্রোতাদের পরিচালনা করে?
আইডান মাইলস

30
6 বছর পরে, আমি মনে করি IE < 10নিরাপদে অবহেলিত হিসাবে বিবেচনা করা যেতে পারে এবং ইয়াহু এবং এওএল ছাড়া অন্য যে কোনও সাইটে এই মুহুর্তে যায় এমন কেউ ব্যবহার করে না। যাইহোক, যে কেউ অযৌক্তিকভাবে আইই ব্যবহার করেন সম্ভবত কোনও ভারতীয় ফোন কেলেঙ্কারির শিকার হতে পারে বা ভাইরাসে আক্রান্ত হওয়ার চেয়ে বেশি সম্ভাবনা থাকে ইভেন্ট ইভেন্ট হ্যান্ডলারের যেভাবেই হোক না কেন, তাদের ক্র্যাবকে ধীর করে দেয়।
ব্র্যাডেন সেরা

71

এখানে তথ্য আপডেট করতে। আমি বিভিন্ন ব্রাউজারগুলি পরীক্ষা করে যাচ্ছি, বিশেষত iframe অনলোড ইভেন্টগুলিতে বৃত্তাকার উপর নির্ভরশীল ইভেন্ট শ্রোতাদের জন্য মেমরি ফাঁসের জন্য।

ব্যবহৃত কোডটি (জেএসফিডাল মেমরি পরীক্ষায় হস্তক্ষেপ করে, তাই এটি পরীক্ষা করতে আপনার নিজের সার্ভারটি ব্যবহার করুন):

<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>

যদি মেমরি ফাঁস না হয় তবে পরীক্ষাগুলি চালানোর পরে ব্যবহৃত মেমরিটি প্রায় 1000 কেবি বা তার বেশি বৃদ্ধি পাবে। যাইহোক, যদি মেমরি ফুটো হয় তবে মেমরিটি প্রায় 16,000 কেবি বৃদ্ধি পাবে। ইভেন্ট শ্রোতার প্রথমে অপসারণের ফলে সর্বদা কম মেমরির ব্যবহার হয় (কোনও ফাঁস হয় না)।

ফলাফল:

  • আই 6 - মেমরি ফুটো
  • আই 7 - মেমরি ফুটো
  • আইই 8 - কোনও স্মৃতি ফাঁস নয়
  • আইই 9 - মেমরি ফাঁস (???)
  • আইই 10 - মেমরি ফাঁস (???)
  • আইই 11 - কোনও স্মৃতি ফাঁস নয়
  • প্রান্ত (20) - কোনও মেমরি ফাঁস নয়
  • ক্রোম (50) - কোনও মেমরি ফাঁস নয়
  • ফায়ারফক্স (46) - বলা মুশকিল, খারাপভাবে ফুটো হয় না, তাই কেবলমাত্র অযোগ্য আবর্জনা সংগ্রহকারী? কোন আপাত কারণে অতিরিক্ত 4MB সঙ্গে শেষ।
  • অপেরা (36) - কোনও মেমরি ফাঁস নয়
  • সাফারি (9) - কোনও স্মৃতি ফাঁস নয়

উপসংহার: রক্তপাত প্রবাহ অ্যাপ্লিকেশনগুলি সম্ভবত ইভেন্ট শ্রোতাদের অপসারণ না করে দূরে সরে যেতে পারে। তবে আমি বিরক্তি সত্ত্বেও এটি ভাল অভ্যাস বিবেচনা করব।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.