Muzibu Player - Mobil Donma Analizi

Performans sorunları ve çözüm önerileri

11 Kritik Bulgu

Ö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)

5+ MB
Session başına memory leak
50+
Concurrent interval/timeout
~50%
CPU usage (idle durumda)

Ö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İK

Basit 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İK

Basit 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İK

Basit 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ÜKSEK

Basit 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ÜKSEK

Basit 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ÜKSEK

Basit 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

ORTA

Basit 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

ORTA

Basit 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

1

Stream URL Cache'e Limit Ekle

LRU cache implementasyonu, max 20-30 entry, 5 dakika TTL

player-core.js:899-908
2

Interval Cleanup Sistemi

Her setInterval öncesi clearInterval çağır, tek interval ID tut

player-core.js:5463-5506
3

Audio Element Pool

Tek audio element reuse et veya element.remove() ile temizle

player-core.js:2159, 2811
4

Queue Refill Guard

_queueRefillInProgress flag ekle, concurrent call engelle

player-core.js:7170-7210
5

Buffer Monitor Devre Dışı Bırak

_bufferHealthEnabled false ise interval başlatma

buffer-monitor.js
6

CSS Animasyonu GPU-Accelerate Et

background-position yerine transform: translateX() kullan

player.blade.php:15-36
7

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