Diğerlerinin yanı sıra varolan bir API'ye dosya yükleme olanağına sahip bir uygulama yapıyorum. Bu API, bir JSON nesnesindeki dosya meta verilerini ve içeriklerini alır, bu nedenle dosyaların ikili içeriğini base64 kodlu dizelere dönüştürmem gerekir.Web çalışanı büyük bir dizi işlerken bellekten çıktı
Bu potansiyel olarak ağır bir işlem olduğundan, işlevi bir web çalışanına taşıdım. Işçi, ikili dosya içeriği (FileReader.readAsArrayBuffer()
döndürdü) ile bir ArrayBuffer
nesnesini alır ve bir base64 kodlanmış dizesi döndürür.
Bu, daha küçük dosyalar için iyi çalışır, ancak en büyük dosyalar için (~ 40 MB) desteklemem gerekiyor, bu da çalışanım için bellek dışı istisnalara neden oluyor (Internet Explorer'da 8007000E). Nadir durumlarda, geçer, ama çoğu zaman işçi sadece ölür. Aynı şey işçiye taşınmadan önce gerçekleşti, ancak tüm tarayıcı sayfası çöktü (IE ve Chrome'da). Chrome, işçilerdeki bellek yükü için IE'ye göre biraz daha esnek görünüyor, ancak hala IE'de (10+) düzgün bir şekilde çalışmam gerekiyor.
Benim işçi:
onmessage = e => {
const bytes = new Uint8Array(e.data);
const l = bytes.length;
const chars = new Array(l);
for (let i = 0, j = l - 1; i <= j; ++i, --j) {
chars[i] = String.fromCharCode(bytes[i]);
chars[j] = String.fromCharCode(bytes[j]);
}
const byteString = chars.join('');
const base64bytes = btoa(byteString);
try {
postMessage(base64bytes, [base64bytes]);
} catch (e) {
postMessage(base64bytes);
}
};
Burada bazı büyük hayır-nos yapma AM? Bellek tüketimini azaltmanın herhangi bir yolu var mı? Düşündüğüm bir çözüm, içeriği tüm dosyadan ziyade parçalar halinde işlemek, sonra ortaya çıkan dizeleri birleştirmek ve onu dışarıda kodlamak olurdu. Bu uygun mu, yoksa kendi sorunlarına neden olacak mı? Bilmediğim başka sihirli işlevler var mı? Ben FileReader.readAsBinaryString()
ile bir umut ışığı vardı, ama şimdi standart (ve IE10 zaten desteklenmez) kaldırıldı, bu yüzden kullanamazsınız.
(Bu soru çok Kod İnceleme de alakalı olabilir, ama benim kod aslında çökmesini olduğundan, ben doğru yeri SO düşündüm idi) Ben yaklaşık olacağını düşündüm
emin değil eğer 'chars' her bir uçtan başlayıp ortada bitirmek? –
Yineleme sayısını azalttığı için (40MB'den 40M'ye 40M'den 20M'ye kadar), optimizasyon denemesi yapıldı. Biraz gitmeden önce yapabileceği boyutu artırdı, ancak hala en büyük dosyalar için yeterli değil. –