2013-03-24 6 views
14

मेरे पास एक वेब एप्लिकेशन है जो लंबे समय तक डेटा में गतिशील रूप से लोड होता है। डेटा के भीतर छवियों के लिंक होते हैं जिन्हें ब्राउज़र में तब प्रस्तुत किया जाता है।उचित रूप से ब्राउज़र संसाधनों का निपटान

उदा।

var object = { 
    Name: ko.observable("Foo"), 
    Ref: ko.observable("Bar"), 
    ImageUrl: ko.observable("http://.....")   
} 

मैं Knockoutjs की स्क्रीन पर डेटा प्रस्तुत करने के लिए बाध्यकारी टेम्पलेट का उपयोग कर रहा हूँ।

<img data-bind="attr: { src: imageUrl }" />   

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

लंबे समय के बाद, ये छवियां बढ़ती हैं और अधिक मेमोरी खाएंगी। आधुनिक ब्राउज़र बेहतर सामना करना प्रतीत होता है, लेकिन समस्या मुख्य रूप से IE8 के साथ है (हम < IE8 का समर्थन नहीं करते हैं)। यहां तक ​​कि आधुनिक ब्राउज़रों में भी स्मृति इतनी अधिक हो जाएगी कि ब्राउजर फ्रीज हो जाए।

छवि संसाधन निर्माण के उदाहरण के लिए इस स्क्रीन शॉट को देखें।

enter image description here

मैं देखने के लिए अगर एक <img /> टैग का उपयोग करने के बजाय, एक <iframe /> का उपयोग क्या होगा फैसला किया।

तो मेरी कोड अब लग रहा है

<iframe data-bind="attr: { src: imageUrl }"></iframe> 

क्या अब क्या होता है की तरह है कि फ्रेम बनाया जाता है, लेकिन जैसे ही imageUrl परिवर्तन के रूप में, फ्रेम बस अद्यतन और अतिरिक्त संसाधनों का निर्माण नहीं करता।

enter image description here

enter image description here

तो अगर मैं ब्राउज़र स्मृति उपयोग नीचे रखना चाहते हैं, मैं इस <iframe /> तकनीक का उपयोग कर सकते हैं, लेकिन मैं इसे पसंद नहीं है। यह मुझे एप्लिकेशन में कई अन्य बदलाव करने के लिए मजबूर करता है, साथ ही मुझे iframes का उपयोग करने की आवश्यकता है!

मैंने यह देखने के लिए अब विभिन्न परीक्षण चलाए हैं कि दोनों तकनीकों का उपयोग करके कितनी मेमोरी का उपयोग किया जाता है, और उसी अवधि में स्मृति 81,000k से 200,000k (<img /> के साथ) 81,000k से 98,000k की तुलना में बढ़ेगी (<iframe /> के साथ)

प्रश्न

वहाँ एक ब्राउज़र के भीतर छवि संसाधनों का प्रबंधन करने के लिए एक बेहतर तरीका है? क्या इस छवि का सही ढंग से निपटान करने का कोई तरीका है? मैंने एक उत्तर के लिए वेब खोजा है, लेकिन अब तक मुझे कुछ भी नहीं मिला है।

संपादित

बहुत बुनियादी स्तर पर। मैंने jQuery विधि remove() के माध्यम से एक छवि को निकालने का प्रयास किया है, लेकिन छवि संसाधन कभी नहीं हटाया जाता है। एक बहुत ही बुनियादी उदाहरण के लिए यह पहेली देखें।http://jsfiddle.net/ezb9e/

कोड:

एचटीएमएल

<img src="http://www.fillmurray.com/200/300" /> 

जे एस

$(function(){ 
    setTimeout(function(){ 
     $('img').remove(); 
     $('body').append($('<img />', { attr: { src: 'http://www.fillmurray.com/300/200' }})); 
    }, 3000);  
}); 
+0

क्या इन हुकों का उपयोग करना संभव हो सकता है: http://knockoutjs.com/documentation/template-binding.html#note_3_using_afterrender_afteradd_and_beforeremove मैन्युअल रूप से डीओएम से छवि को मैन्युअल रूप से हटाने के लिए, नया जोड़ा जाने से पहले? उस समस्या को रोकना चाहिए। – Nik

+0

मैंने पहले ही छवि को हटाने की कोशिश की है, और फिर एक नया जोड़ें, लेकिन छवि संसाधन हमेशा बनाते हैं। एक उदाहरण के लिए यह पहेली देखें। http://jsfiddle.net/ezb9e/ –

+0

क्या आप डेटा रीफ्रेश करते समय छवि यूआरएल हमेशा बदलते हैं, या वे अपेक्षाकृत स्थिर रहते हैं? –

उत्तर

5

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

ko.bindingHandlers.createImage = { 
    update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
    // Use something unique to identify this image object 
    var imageName = viewModel.Name(); 
    var parent = bindingContext.$parent; 

    var imageObject = parent.Images[imageName]; 

    if (imageObject) { 
     $(element).empty() 
     imageObject = null; 
    } 

    imageObject = $(element).append('<img src="' + viewModel.imgSrc() + '" />')[0]; 
    parent.Images[imageName] = imageObject; 
    } 
}; 

यहाँ अपने मूल समस्या पुनः है:

http://jsfiddle.net/manzanotti/ezb9e/5/

और यहाँ मेरी संस्करण है:

http://jsfiddle.net/manzanotti/ezb9e/13/

मेमोरी शुरू में ऊपर जाता है, लेकिन यह कचरा अब और फिर हर एकत्र हो जाता है , इसलिए यह कभी नियंत्रण से बाहर नहीं हो जाता है। यह आईई 9 और क्रोम में परीक्षण किया जाता है।

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

+0

दुर्भाग्यवश, ऐसा लगता है कि आईई 8 की छवि निर्माण के संबंध में बस एक बहुत खराब स्मृति रिसाव है। एक प्रस्तावित समाधान (जो केवल कुछ लोगों के लिए काम करता है), उन्नत इंटरनेट विकल्पों में * * स्मार्टस्क्रीन फ़िल्टर सक्षम करें "चालू करना है। काफी अत्याचारी कामकाज, लेकिन अगर आपको वास्तव में IE8 समर्थन की आवश्यकता है और iframes का उपयोग नहीं करना चाहते हैं तो इसके लायक हो सकते हैं। स्रोत: http://com.hemiola.com/2009/11/23/memory-leaks-in-ie8/#comment-880 – snickle

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