Neden şarkı değiştikçe telefon yavaşlıyor?
Bir restoran düşünün. Her müşteri yemek bitirdiğinde garson kirli tabakları masada bırakıyor. Yeni müşteri gelince yanına yeni tabak koyuyor.
Masada 5 kirli tabak birikiyor!
Her müşteri bitirdiğinde garson önce kirli tabakları topluyor, sonra yeni müşteriye temiz tabak getiriyor.
Her zaman sadece 1 tabak!
Player bellekte bir "ses kutusu" (audio element) oluşturuyor
Player yeni bir "ses kutusu" oluşturuyor AMA eskisini tam temizlemiyor
Bellekte 10 tane yarı-temizlenmiş "ses kutusu" birikmiş. Telefon yavaşlıyor.
⚠️ Eski telefonlarda 100 MB = Donma başlangıcı
// 🧹 Mevcut temizlik - setTimeout ile 100ms gecikme
setTimeout(() => {
// ❌ Sorun 1: Sadece ID kontrolü yapılıyor
if (oldAudioId && oldAudioId !== currentActiveAudioId) {
const oldAudio = document.getElementById(oldAudioId);
if (oldAudio) {
safeAudioCleanup(oldAudio);
// ⚠️ removeChild YOK - DOM'da kalıyor!
}
}
// ✅ Blob URL temizleniyor
if (self._currentBlobUrl) {
revokeBlobUrl(self._currentBlobUrl);
}
// ⚠️ HLS destroy çağrılıyor AMA...
oldHls.destroy();
// ❌ Buffer'lar hemen serbest kalmıyor
}, 100);
safeAudioCleanup() sadece src ve event'leri temizliyor,
removeChild() çağrılmıyor.
// safeAudioCleanup içeriği (satır 130-149):
audio.pause();
audio.removeAttribute('src');
audio.load();
// ❌ document.body.removeChild(audio) YOK!
hls.destroy() çağrılsa bile MediaSource buffer'ları
garbage collector'ı bekliyor. Eski telefonlarda GC yavaş çalışıyor.
Crossfade aktifken 2 audio element aynı anda çalıyor. Her biri ~20MB buffer kullanıyor. Eski şarkının crossfade bitişi beklenmiyor, direkt yeni şarkı başlıyor.
| Fonksiyon | Dosya:Satır | Görevi |
|---|---|---|
safeAudioCleanup() |
player-core.js:130 | Audio element temizleme |
playSongFromQueue() |
player-core.js:3531 | Şarkı çalma başlatma |
completeCrossfade() |
player-core.js:2290 | Crossfade sonlandırma |
stopPlayback() |
player-core.js:4340 | Player durdurma |
_cleanupPreloadedNext() |
player-core.js:6970 | Preload temizleme |
// safeAudioCleanup sonrasına eklenecek:
if (oldAudio && oldAudio.parentNode) {
oldAudio.parentNode.removeChild(oldAudio);
}
// Tüm temizliği tek noktada yapan fonksiyon:
fullCleanupOldSong(oldHls, oldAudioId, oldBlobUrl) {
// 1. HLS destroy (buffer'ları serbest bırakır)
if (oldHls) oldHls.destroy();
// 2. Audio element'i DOM'dan kaldır
const oldAudio = document.getElementById(oldAudioId);
if (oldAudio) {
safeAudioCleanup(oldAudio);
if (oldAudio.parentNode) {
oldAudio.parentNode.removeChild(oldAudio);
}
}
// 3. Blob URL'yi revoke et
if (oldBlobUrl) URL.revokeObjectURL(oldBlobUrl);
}
// Mobil cihazlarda GC'yi zorlama:
if (isMobileDevice()) {
// Boş array oluşturup hemen sil - GC tetikler
setTimeout(() => {
let temp = new Array(1000);
temp = null;
}, 200);
}