Özet Değerlendirme
Basit Anlatım (Herkes İçin)
Muzibu player'ın mobilde donmasının üç ana sebebi var:
- Bellek Sızıntısı: Player, dinlenen her şarkının bilgisini hafızada tutuyor ve asla silmiyor. 50+ şarkı dinlenince telefon hafızası doluyor.
- Sürekli Kontroller: Player saniyede 10-20 kez "şarkı çalıyor mu?", "buffer dolu mu?" gibi kontroller yapıyor. Bu telefonu yoruyor.
- Temizlenmeyen Öğeler: Her şarkıda yeni ses oynatıcı oluşturuluyor ama eskiler silinmiyor. Sayfada 50+ görünmez oynatıcı birikebilir.
Sonuç: 2-3 dakika kullanımda düşük RAM'li telefonlar (2-4GB) donmaya başlıyor.
Teknik Özet (Geliştiriciler İçin)
Öncelik Sıralaması
| Öncelik | Problem | Dosya | Etki |
|---|---|---|---|
| KRİTİK | Map cache sınırsız büyüme | player-core.js:899-908 | 5+ MB/session |
| KRİTİK | setInterval race condition | player-core.js:5463-5506 | CPU %50+ |
| KRİTİK | Audio element cleanup yok | player-core.js:2159, 2811 | DOM leak |
| YÜKSEK | Crossfade dual audio decode | player-core.js:2148-2159 | Memory pressure |
| YÜKSEK | Queue refill race condition yok | player-core.js:7170-7210 | Infinite loop riski |
| YÜKSEK | Buffer monitor agresif polling | buffer-monitor.js:7021 | CPU %20+ |
| ORTA | CSS gradient animasyon CPU-bound | player.blade.php:15-36 | Jank |
| ORTA | Progress interval temizlenmiyor | player-core.js:2029-2035 | Concurrent intervals |
Detaylı Bulgular
1 Bellek Sızıntısı: Map Cache Sınırsız Büyüme
KRİTİKBasit Anlatım
Player, dinlenen her şarkının stream URL'ini bir "hafıza listesine" (Map) kaydediyor. Problem: Bu liste asla temizlenmiyor. 200 şarkı dinlerseniz, 200 şarkının tüm bilgisi telefon hafızasında kalıyor. Düşük RAM'li telefonlarda (2-4GB) bu 5-10 MB memory waste demek.
Teknik Detay
Dosya: player-core.js
Satır: 899-908
// Problem: Map asla cleanup yapılmıyor
this.streamUrlCache.set(song.song_id, {
stream_url: data.stream_url,
stream_type: data.stream_type,
fallback_url: data.fallback_url,
preview_duration: data.preview_duration,
song: streamData.song, // ← Nested object = ağır veri!
cached_at: Date.now()
});
Çözüm: LRU cache implementasyonu + max 20-30 entry limiti + TTL (5 dakika)
2 setInterval Race Condition
KRİTİKBasit Anlatım
Player'da 3 farklı zamanlayıcı sürekli çalışıyor:
- • Progress tracker: Her 100ms'de "şarkı nerede?" kontrolü
- • Buffer monitor: Her 500ms'de "internet yeterli mi?" kontrolü
- • Queue monitor: Her 10sn'de "sıradaki şarkı var mı?" kontrolü
Sorun: Yeni şarkıya geçildiğinde eski zamanlayıcılar kapatılmıyor, yenileri açılıyor. 20 şarkı sonra 60+ zamanlayıcı aynı anda çalışıyor!
Teknik Detay
Dosya: player-core.js
Satırlar: 5463-5506, 7021, 7157
// Her şarkıda yeni interval oluşturuluyor
this.progressInterval = setInterval(() => {
this.updateProgress(); // DOM update
}, 100);
// Buffer check - 500ms
this._bufferCheckInterval = setInterval(() => {
this.checkBufferHealth();
}, 500);
// ⚠️ clearInterval ÇAĞRILMIYOR!
Çözüm: Her yeni interval öncesi clearInterval(this.progressInterval) çağrılmalı
3 Audio Element appendChild - Cleanup Yok
KRİTİKBasit Anlatım
Her şarkıda sayfaya yeni bir ses oynatıcı elementi ekleniyor
(<audio>).
Eski oynatıcılar asla kaldırılmıyor.
50 şarkı sonra sayfada 50 tane görünmez audio elementi var!
Mobil Safari'de kritik: Her audio elementi için ayrı decode buffer tutuluyor.
Teknik Detay
// Satır 2159, 2811, 6790, 6882
document.body.appendChild(nextAudio); // ← Her crossfade'de
document.body.appendChild(audio); // ← Her playback'te
// ⚠️ removeChild() veya .remove() YOK!
Çözüm: Tek audio element reuse et, veya eski elementi element.remove() ile kaldır
4 Crossfade: Dual Audio Decode
YÜKSEKBasit Anlatım
Crossfade (şarkılar arası yumuşak geçiş) özelliği kapalı olmasına rağmen,
ilgili kodlar bellekte howlNext, hlsNext nesneleri tutuyor.
Aktif olsa bile, iki şarkıyı aynı anda decode etmek mobilde memory pressure yaratıyor.
Teknik Detay
// Satır 486-492 - Kapalı ama object'ler var
crossfadeEnabled: false, // 🚫 DEVRE DIŞI
crossfadeDuration: 0,
howlNext: null, // ← Bellekte yer kaplıyor
hlsNext: null, // ← HLS instance leak
5 Queue Refill: Race Condition Riski
YÜKSEKBasit Anlatım
Her 10 saniyede "sırada şarkı kaldı mı?" kontrolü yapılıyor. Eğer internet yavaşsa ve API cevap vermeden 10 saniye geçerse, ikinci bir istek daha gönderiliyor. Yavaş internet = sonsuz istek döngüsü riski.
Teknik Detay
// Satır 7170-7210
async checkAndRefillQueue() {
if (queueLength <= 3) {
await this.loadEmergencyQueue(); // ← No guard!
}
}
// ⚠️ _queueRefillInProgress flag YOK!
Çözüm: _queueRefillInProgress flag ekle, concurrent call'ları engelle
6 Buffer Monitor: Agresif 500ms Polling
YÜKSEKBasit Anlatım
Buffer health monitor kapalı olmasına rağmen interval hâlâ çalışıyor. Her 500ms'de buffer kontrolü yapılıyor ve console'a log yazılıyor. Bu, CPU'nun sürekli meşgul kalmasına neden oluyor.
Teknik Detay
// buffer-monitor.js
_bufferHealthEnabled: false, // Auto-pause kapalı
// AMA interval HALA ÇALIŞIYOR!
this._bufferCheckInterval = setInterval(() => {
console.log("🛡️ BUFFER:", this.getBufferedAmount());
}, 500);
7 CSS Gradient Animasyon: CPU-Bound
ORTABasit Anlatım
Player arka planında sürekli hareket eden gradient animasyonu var.
Bu animasyon background-position kullanıyor ki bu
GPU hızlandırması almıyor.
Düşük güçlü telefonlarda jank (takılma) yapıyor.
Teknik Detay
/* player.blade.php - Satır 15-36 */
@keyframes gradientShift {
0%, 100% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
}
.mobile-player-wrapper {
animation: gradientShift 8s ease infinite;
}
Çözüm: transform: translateX() kullan veya animasyonu kaldır, will-change ekle
8 Mobile Safari: Device Memory Check Yok
ORTABasit Anlatım
Kod içinde "device profiler" var ama iOS'ta deviceMemory API'si çalışmıyor.
Bu yüzden tüm cihazlar aynı ayarlarla çalıştırılıyor.
Eski iPhone 8 ile iPhone 15 Pro Max aynı agresiflikte preload yapıyor.
Teknik Detay
// device-profiler.js - Satır 57
memory: nav.deviceMemory || null, // iOS: null
cores: nav.hardwareConcurrency || null, // iOS: null
// Hiçbir fallback yok!
Önerilen Düzeltmeler
Stream URL Cache'e Limit Ekle
LRU cache implementasyonu, max 20-30 entry, 5 dakika TTL
player-core.js:899-908
Interval Cleanup Sistemi
Her setInterval öncesi clearInterval çağır, tek interval ID tut
player-core.js:5463-5506
Audio Element Pool
Tek audio element reuse et veya element.remove() ile temizle
player-core.js:2159, 2811
Queue Refill Guard
_queueRefillInProgress flag ekle, concurrent call engelle
player-core.js:7170-7210
Buffer Monitor Devre Dışı Bırak
_bufferHealthEnabled false ise interval başlatma
buffer-monitor.js
CSS Animasyonu GPU-Accelerate Et
background-position yerine transform: translateX() kullan
player.blade.php:15-36
Mobil Cihaz Adaptif Ayarlar
iOS için connection type + user agent bazlı profilleme
device-profiler.js
Hızlı Kazanımlar (Hemen Yapılabilir)
1. Buffer Monitor Kapat
Zaten disabled ama interval çalışıyor. Tamamen kaldır.
Beklenen iyileşme: CPU %15-20 azalma
2. Cache Limiti Ekle
streamUrlCache'e max 30 entry limiti ekle.
Beklenen iyileşme: 3-5MB memory tasarrufu
3. Progress Interval Fix
Her şarkıda clearInterval() çağır.
Beklenen iyileşme: CPU %10-15 azalma
4. Gradient Animasyonu Kaldır
Mobilde statik arka plan, masaüstünde animasyon.
Beklenen iyileşme: GPU/CPU %5-10 azalma