2013-03-24 36 views
14

Verileri uzun süre dinamik olarak yükleyen bir web uygulamasına sahibim. Verilerin içinde, tarayıcıya daha sonra görüntülenen görüntülere bağlantılar vardır.Tarayıcı kaynaklarının düzgün bir şekilde imha edilmesi

örn.

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

Ekranda verileri işlemek için bağlayıcı Knockoutjs 'ın şablonu kullanıyorum.

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

Yani bir Ajax çağrı yoluyla nesne değişiklikleri, Knockoutjs şablon verileri ile yeniden oluşturulur ve görseller değiştirmek her zaman.

Uzun bir süre sonra, bu görüntüler oluşur ve daha fazla bellek tüketir. Modern tarayıcılar daha iyi başa çıkıyor gibi görünüyor, ancak sorun esas olarak IE8 ile (< IE8'i desteklemiyoruz). Modern tarayıcılarda bile, tarayıcı, tarayıcının donacağı kadar yüksek olacak.

Görüntü kaynaklarının oluşturduğu bir örnek için bu ekran görüntüsüne bakın.

enter image description here

yerine bir <img /> etiketi kullanımına ilişkin bir <iframe /> kullanmak ne olacağını görmeye karar verdi. Şimdi ne olacak

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

çerçeve oluşturulduğunu, ancak en kısa sürede imageUrl değiştikçe, çerçeve sadece güncellemeler ve ek kaynak yaratmaz gibi

Yani benim kod artık görünüyor. Ben aşağı tarayıcı bellek kullanımı tutmak istiyorsanız

enter image description here

enter image description here

Yani, bu <iframe /> tekniği kullanabilirsiniz, ama bunu sevmiyorum. Bu uygulamada birçok değişiklik yapmak için beni zorluyor, ayrıca iframe'leri kullanmam gerek!

Her iki teknik kullanılarak ne kadar bellek kullanıldığını görmek için çeşitli testler yapıyorum ve aynı süre zarfında bellek 81.000k - 98.000k ile karşılaştırıldığında 81.000k - 200,000k (<img /> ile) artacak bir tarayıcı içinde görüntü kaynaklarını yönetmek için daha iyi bir yolu

Soru

var mı (<iframe /> ile)? Bu resmi düzgün şekilde imha etmenin bir yolu var mı? Web’de bir cevap arandı, ancak şu ana kadar hiçbir şey bulamadım. Çok temel düzeyde

Düzenleme

. Bir görüntüyü jQuery yöntemi remove() aracılığıyla kaldırmaya çalıştım, ancak görüntü kaynağı hiçbir zaman kaldırılmaz. Çok basit bir örnek için bu keman'a bakın.http://jsfiddle.net/ezb9e/

kodu:

html

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

JS

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

Bu kancaları kullanmak mümkün olabilir: http://knockoutjs.com/documentation/template-binding.html#note_3_using_afterrender_afteradd_and_beforeremove, yeni bir tane eklenmeden önce DOM'dan kendiniz görüntüyü kendiniz kaldırmak için mi? Bu problemi durdurmalı. – Nik

+0

Önce görüntüyü kaldırmayı denedim ve sonra yeni bir tane ekledim, ancak görüntü kaynakları her zaman biriktiriyor. Bir örnek için bu keman bakın. http://jsfiddle.net/ezb9e/ –

+0

Verileri yenilediğinizde görüntü URL'leri her zaman değişiyor mu, yoksa nispeten sabit mi kalıyor? –

cevap

5

Özel bir bağlama kullanmayı deneyin ve oluşturmak ve bu görüntüleri yok edecektir. Geçen sene bir SVG ile benzer bir problem yaşadım ve yapmak zorunda olduğum şey buydu. İşte

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

orijinal problemini yeniden ediyor: Burada

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

Ve sürümü:

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

Bellek başlangıçta artar, ancak çöp şimdi tekrar her toplanmış olur bu yüzden asla kontrolden çıkmaz. Bu IE9 ve Chrome'da test edilir.

Güncelleştirme Hmmm, şimdi bunun IE8'deki sorunu tamamen giderdiğine inanmıyorum. SIEve'de kemanı çalıştırdım ve bellek hala bu şekilde devam ediyor, ancak sIEve DOM düğümlerine kancalar eklediğinde, bunun sIEve'de çalışmasının bir sonucu olabilir. Yine de krom gayet iyi ve IE9, en azından, tamamen düzeltilmemişse çok daha iyi görünüyor.

+0

Ne yazık ki, IE8'in görüntü oluşturma konusunda oldukça kötü bir bellek sızıntısı var gibi görünüyor. Önerilen bir çözüm (sadece bazı insanlar için çalışıyor gibi görünüyor), * Gelişmiş İnternet Seçenekleri'nde * "SmartScreen Filtresini Etkinleştir" seçeneğini açmaktır. Oldukça geçici bir çözüm, ama gerçekten IE8 desteğine ihtiyacınız varsa ve iframe kullanmak istemiyorsanız buna değer olabilir. Kaynak: http://com.hemiola.com/2009/11/23/memory-leaks-in-ie8/#comment-880 – snickle

İlgili konular