Performans borcunun sinsi yanı, ölçülmediğinde görünmez kalmasıdır. Sayfa hâlâ açılıyordur, özellikler çalışıyordur; ancak yükleme süresi altı ayda 200 ms artmış, INP değeri kabul edilebilir sınırı geçmiş, LCP eşiğe yaklaşmıştır. Bu sürüngen bozulma, anlık bir arızanın aksine alarm üretmez. Alarm üretmediği için de birikimine sessizce izin verilir.

Güncellenmemiş bağımlılıklar bundle'a gizli ağırlık ekler

Npm paketleri zaman içinde gelişir. Kütüphane yazarları gereksiz bağımlılıkları temizler, ağır modülleri daha hafif alternatiflerle değiştirir, tree shaking uyumluluğunu iyileştirir. Bu geliştirmelerin bir projeye yansıması için bağımlılıkların düzenli güncellenmesi gerekir. Güncellenmediğinde proje eski sürümün taşıdığı tüm yükü korumaya devam eder.

Bunun ötesinde, büyük major sürüm atlamaları bundle boyutunu beklenmedik biçimde değiştirebilir. İki yıl önce seçilen bir kütüphanenin güncel alternatifleri artık çok daha hafif olabilir. Eski bir sürüme bağlı kalmanın maliyeti başlangıçta sıfır görünür; ancak ekosistemin ilerlemesiyle birlikte bu maliyet büyür. Bundle analizi düzenli yapıldığında, güncel olmayan büyük bağımlılıklar görünür hale gelir ve değiştirilmesi için bir gerekçe oluşur.

Bağımlılık sürümlerinin donması güvenlik açıklarını da beraberinde getirir; ancak performans boyutunda daha az konuşulan bir sorun vardır: eski bir kütüphanenin ürettiği çıktı, modern build araçlarının optimizasyonlarından yararlanamayabilir. Tree shaking, modern modül formatları ve yeni bundler optimizasyonları eski paketlerin anlayabileceği formatlarda gelmeyebilir. Bu uyumsuzluk, paketin olduğundan büyük görünmesine ve olduğundan fazla kod taşımasına yol açar.

CSS dosyasının büyümesi kritik yola sessizce biniş yapar

Bir projenin CSS dosyası genellikle tek yönlü büyür. Her yeni özellik yeni stil kuralları ekler; eski özellikler kaldırıldığında artık kullanılmayan stiller çoğu zaman geride kalır. Altı ay sonra bir bileşen silinmiş ama ona ait CSS hâlâ dosyada duruyor olabilir. Bu birikme, kullanılmayan CSS miktarını artırır ve dosyanın gereksiz yere büyümesine neden olur.

CSS dosyasının boyutu, ilk sayfa yüklemesini doğrudan etkiler. Render engelleyen bir kaynak olarak yüklenen büyük bir stil dosyası, tarayıcının sayfayı görsel olarak render etmesini geciktirir. Bu gecikme LCP süresine doğrudan yansır. Coverage aracının düzenli kullanımı — hangi stillerin gerçekten kullanıldığını ölçmek — bu birikimi görünür kılar. Pratikte bir projenin CSS kullanım oranının %40'ın altına düştüğü sıkça görülür; bu, dosyanın yarısından fazlasının gereksiz olduğu anlamına gelir.

CSS mimarisindeki teknik borç başka bir biçimde de ortaya çıkar: geçici olarak eklenen !important kuralları, giderek artan özgüllük savaşları ve global seçicilerin birikmesi. Bu sorunların hiçbiri doğrudan ölçülebilir bir performans maliyeti yaratmaz; ancak stili düzenlemeyi giderek zorlaştırır ve bakım sürecini ağırlaştırır. CSS'i düzenlemek güçleştikçe gereksiz stilleri temizleme motivasyonu azalır ve birikim hızlanır.

JavaScript yığılması main thread baskısını artırır

JavaScript dosyaları da CSS gibi büyür; ancak maliyeti farklı bir mekanizmayla gelir. Her eklenen script yalnızca ağ üzerinden indirme maliyeti taşımaz; parse edilmesi ve çalıştırılması da main thread üzerinde iş yaratır. Zaman içinde büyüyen bir bundle, kullanıcının etkileşime geçmeden önce beklediği süreyi artırır.

Teknik borcun JavaScript boyutuna özgü bir tezahürü, geçici çözümlerin birikmesidir. Bir özellik hızlıca gönderilmek zorundayken eklenen ağır bir polyfill, daha temiz bir çözüm bulunana kadar bekleyen büyük bir yardımcı fonksiyon, artık ihtiyaç duyulmayan ama kaldırılmamış bir analitik script. Bu parçaların her biri küçük görünür; toplam bundle'daki ağırlıkları ise zaman içinde birikir.

Code splitting yapılandırılmamış veya eski bir yaklaşımla yapılmışsa, başlangıç bundle'ı her yeni özellikle birlikte büyür. İlk kurulumda makul görünen bir chunk stratejisi, iki yıl sonra artık uygun olmayabilir. Projenin büyümesiyle birlikte chunk sınırlarını gözden geçirmek ve gerektiğinde yeniden yapılandırmak, bu yığılmayı kontrol altında tutmanın pratik yoludur.

Ölçüm altyapısı yoksa bozulma fark edilmez

Teknik borcun performansı sessizce aşındırmasının temel nedeni, ölçüm altyapısının eksikliğidir. Core Web Vitals değerleri takip edilmiyorsa, altı ayda oluşan 300 ms LCP artışı bir bildirim üretmez. Bundle boyutu izlenmiyorsa, her deploy'da eklenen 5 KB fark edilmez; ancak bir yılda toplam 60 KB'a ulaşır.

Gerçek kullanıcı verisi — RUM araçlarından gelen alan verisi — bu tür sürüngen bozulmaları en erken yakalayan kaynaktır. Lighthouse veya PageSpeed puanları yapay test ortamında ölçüldüğünden, gerçek kullanıcı çeşitliliğini ve gerçek cihaz profilini yansıtmaz. Bir proje yalnızca lab verisiyle izleniyorsa, gerçek kullanıcıların deneyimlediği bozulma görünmez kalabilir. RUM verisinin zaman içindeki trendini gözlemlemek — yalnızca anlık değeri değil — teknik borcun performansa etkisini somutlaştırır.

CI pipeline'ında otomatik boyut kontrolü bu zincirin önemli bir halkasıdır. Her pull request'te bundle boyutunu bir önceki baseline ile karşılaştıran bir araç — size-limit veya bundlewatch gibi — bireysel değişikliklerin kümülatif etkisini görünür kılar. Tek başına küçük görünen her PR, boyut sınırını aşmadığı sürece geçer; ancak bu kontrol olmadan, küçük PR'ların toplamı eşiği sessizce aşar.

Performans bütçesi olmadan borç sınır tanımaz

Teknik borcun performans boyutunu yönetmenin en etkili yapısal aracı, tanımlanmış ve aktif olarak korunan bir performans bütçesidir. Bütçe olmadan her değişiklik kendi başına değerlendirilir: bu özellik için 10 KB eklemek makul mü? Cevap bağlama göre değişir ve tartışmaya açıktır. Bütçe olduğunda ise cevap nesneldir: sınırı aşıyor mu?

Performans bütçesi yalnızca bundle boyutunu kapsamaz. LCP için hedef süre, CLS için maksimum değer, toplam JavaScript boyutu, üçüncü parti script ağırlığı — bunların hepsi bütçenin parçası olabilir. Bu hedeflerin CI'da otomatik olarak denetlenmesi, teknik borcun fark edilmeden birikmesini yapısal olarak engeller. Bir bütçe ihlali alarmı, tek tek PR'ları gözden geçirmeden kaçırılması imkansız bir sinyal üretir.

Teknik borcu tamamen sıfırlamak ne mümkündür ne de hedeflenmesi gereken bir idealdir; her aktif projede bir miktar borç kaçınılmazdır. Önemli olan bu borcun aktif olarak izlenmesi, dönemsel olarak değerlendirilmesi ve kontrol altında tutulmasıdır. Performans açısından bu izleme; metriklerin zaman içindeki trendini düzenli olarak incelemeyi, bütçe eşiklerini korumayı ve bağımlılıkları düzenli aralıklarla gözden geçirmeyi kapsar. Bu pratikler olmadan teknik borç sessizce birikir ve bir noktada kullanıcı deneyimine doğrudan yansır; pratikler yerleştiğinde ise borç görünür hale gelir, önceliklendirilir ve yönetilebilir bir boyutta kalır. Performans kalitesi bu düzeyde ele alındığında, kod tabanının büyümesiyle birlikte bozulmak yerine olgunlaşır.

Bağımlılık denetimine ek olarak, kullanımdan kalkmış API'lerin ve deprecated pratiklerin taranması da teknik borç yönetiminin bir parçasıdır. Bir framework yeni bir veri çekme yöntemi önerdiğinde veya eski bir pattern'in performans olumsuzluklarını belgelediğinde, bu değişikliği izlemek ve uygulamak vakit alır. Ancak ertelendikçe, eski yaklaşım üzerine inşa edilen yeni özellikler nedeniyle refactor maliyeti katlanır. Özellikle React, Next.js veya büyük UI framework'lerinde her major sürüm bu tür değişiklikler içerir; migration rehberlerini takip etmek ve yüksek öncelikli değişiklikleri backlog'a zamanında almak, ilerleyen dönemde yapılacak büyük yeniden yazım maliyetini önler.

Teknik borcun takibi ekip boyutuna göre farklı pratikler gerektirir. Küçük ekiplerde bir sayfa veya bileşen bazında yapılan periyodik kod incelemeleri, performans açısından sorunlu pratikleri yüzeye çıkarabilir. Büyük ekiplerde ise otomatik araçlar olmadan bu denetim ölçeklenmez. Linting kuralları, bundle boyutu eşikleri ve CI'da çalışan performans testleri, insan dikkatine bağımlı olmadan borcun birikmesini yavaşlatır. İki yaklaşımın birleşimi — otomatik kontroller ile periyodik insan incelemesi — çoğu proje için en sağlam dengeyi sağlar ve performans kalitesinin kalıcı bir ekip pratiği haline gelmesini destekler.

Performans borcunu azaltmak için planlı "temizlik sprint'leri" yararlı olabilir; ancak bu yaklaşım tek başına sürdürülebilir değildir. İki haftada bir temizlik yapılsa bile, iki haftalık geliştirme sürecinde eklenen yeni bileşenler, eklentiler ve özellikler kendi borcunu üretir. Daha kalıcı bir etki için performans konusundaki beklentilerin normal geliştirme sürecine entegre edilmesi gerekir: PR şablonlarında bundle boyutu etkisi sorusu, feature flag ile gönderilecek büyük özellikler için performans ön değerlendirmesi, yeni bağımlılık eklemeden önce boyut ve tree shaking kontrolü. Bu pratikler temizlik yükünü azaltır; çünkü borcu daha az üretirler.