10.000 Satırlık CSS Dosyasını Küçültmek: Adım Adım Yaklaşım
10.000 satırlık CSS dosyasını Coverage analizi, bileşen bazlı bölme ve critical CSS ayırma adımlarıyla sistematik biçimde küçültmek için önce nereye bakılacağı ve hangi risklere dikkat edilmesi gerektiği.
CSS dosyası büyüdükçe, sorunun tam olarak nerede olduğunu görmek zorlaşır. 10.000 satırın üzerindeki bir stil dosyasına baktığınızda, neyin gereksiz neyin kritik olduğunu sezgiyle ayırt etmek neredeyse imkansız hale gelir. Projeye dahil olan her geliştirici bir şeyler ekler; silen pek çıkmaz; sonunda kimsenin güvenle dokunmadığı bir katman oluşur.
Senaryo tanıdıktır. Bir tasarım sistemi entegre edilir, birkaç bileşen kütüphanesi eklenir, farklı ekipler yıllarca üzerinde çalışır; dosya büyür. Sayfa yükleme sürelerine bakıldığında CSS'in ciddi bir ağırlık taşıdığı görülür ama nereden başlanacağı belirsiz kalır. Üstelik yanlış yerden başlamak - aceleyle seçici silmek - bazı sayfalarda görsel bozulmalara yol açabilir.
Sistematik yaklaşmak bu sorunu yönetilebilir kılar. Coverage analizi, bileşen bazlı bölme ve critical CSS ayırma; bu üç araç birlikte uygulandığında çoğu projede kayda değer iyileşme sağlar. Ama her adımın sınırlarını bilmek, aceleci kararlardan kaçınmak kadar önemlidir.
Coverage Aracı Ne Gösterir, Ne Göstermez?
Chrome DevTools'taki Coverage sekmesi, sayfanın o anki oturumunda hangi CSS kurallarının uygulandığını, hangilerinin hiç çalışmadığını gösterir. Komut menüsünden (Ctrl+Shift+P) "Coverage" yazarak açılır. Kayıt başlatıldıktan sonra sayfada gezinilirse her CSS dosyasının ne kadarının kullanıldığı kırmızı-yeşil çubukla görünür hale gelir; kullanılmamış bayt miktarı ve oran bilgisi de eklenir.
Dikkat gerektiren nokta şudur: Coverage bir anlık görüntüdür. Yalnızca o oturumda tetiklenen stilleri "kullanılmış" sayar. Bir açılır menü, bir modal pencere veya hata mesajı için tanımlanmış kurallar, siz o etkileşimi yapmadıysanız kullanılmamış görünür. Aynı şekilde medya sorguları - farklı ekran genişliklerindeki kurallar - yalnızca o sorgunun eşleştiği görünüm boyutunda işaretlenir.
Coverage çıktısını doğrudan "şu kuralları sil" listesi olarak okumak yanıltıcı olur. Buna rağmen Coverage'ın asıl değeri oransal bakışta yatar. 10.000 satırın yüzde seksen ile doksanı kullanılmamış görünüyorsa, büyük olasılıkla import edilmiş ama hiç özelleştirilmemiş bir kütüphane ya da eski bir tema bloğu vardır; buraya odaklanmak gerekir. Yüzde yirmi kullanılmamış görünen bir dosya farklı bir soruya işaret eder: belki seçici karmaşıklığı ya da tekrar eden tanımlar problemi.
Coverage sadece Chrome'da değil, Firefox DevTools'ta da benzer bir formatta mevcuttur. Firefox, özellikle Profiler ile birlikte kullanıldığında stil hesaplama maliyetini daha ayrıntılı gösterir. İki tarayıcıda kontrol etmek, tarayıcıya özgü davranışlardan kaynaklanan farkları da ortaya çıkarabilir.
Kullanılmayan Kuralları Güvenle Tespit Etmek
Coverage analizi sonrasında PurgeCSS gibi araçlar, HTML ve JavaScript dosyalarınızı tarayarak belirli seçicilerin projede geçip geçmediğini kontrol eder. Bu araçlar statik analiz yapar; JavaScript ile dinamik olarak üretilen sınıf adlarını göremezler. Bir bileşen className={`btn-${variant}`} gibi bir şablon ifadesiyle sınıf oluşturursa, bu tarama sırasında görünmez ve yanlışlıkla silinebilir.
Güvenli bir temizleme süreci için şu sıra işe yarar: araç çıktısını gözden geçirin, dinamik sınıf adlarını safelist (izin listesi) olarak ekleyin, test ortamında çalıştırın ve görsel regresyon testleri ya da en azından elle gezme ile sonucu doğrulayın. Bir sınıfı silerek sayfa düzenini bozmak, silerek kazanılan milisaniyelerden çok daha pahalıya mal olur.
Temizleme mantığı seçicilerin adına değil, kullanımına dayanır. table, td, th gibi HTML etiket seçicileri içerik editörlerin oluşturduğu sayfalarda dinamik olarak ortaya çıkabilir; statik tarama bunları atlar. CMS tabanlı projelerde etiket seçicilerini ve sık kullanılan yardımcı sınıfları safelistte tutmak bu riski azaltır.
Teknik borç bu sürecin tam merkezinde durur: eski tasarımlardan kalan seçiciler, kullanılmayan temalar, farklı bileşen versiyonlarına ait çakışan kurallar zamanla birikir ve hem dosya boyutunu hem tarayıcının stil hesaplama süresini artırır. Temizleme yapılmadan önce bu katmanların nereden geldiğini anlamak, nelerin güvenle silinebileceğini netleştirir.
Bileşen Bazlı CSS Bölme: Dosyayı Mantıksal Parçalara Ayırmak
10.000 satırlık tek bir CSS dosyası büyük ölçüde bir organizasyon sorunudur. Tarayıcı, sayfa render edilmeden önce tüm dosyayı indirip ayrıştırmak zorundadır; bu render-blocking etkisi bütün sayfalarda devreye girer ve yalnızca birkaç bileşen kullanan bir sayfa bile tüm CSS yükünü taşır.
Bileşen bazlı bölmede her bileşen ya da modül kendi CSS dosyasını taşır ve yalnızca o bileşenin render edildiği sayfalarda yüklenir. React, Vue ve Angular ekosistemlerindeki CSS Modules, styled-components ve Tailwind gibi yaklaşımlar bu bölmeyi farklı düzeylerde otomatikleştirir. CSS Modules dosya adı çakışmalarını scope ile çözer; Tailwind ise kullanılan yardımcı sınıfları build sırasında tarayarak yalnızca gerekenleri çıktıya alır. Bir bileşen silindiğinde onun stilleri de projeyle birlikte gider; birikim başlamaz.
Bölme kararı ölçek meselesidir. Küçük bir sitede tek dosyayı temizlemek yeterlidir; bileşen bazlı yapıya geçmek fazladan karmaşıklık yaratır ve öğrenme yükü ekler. Orta ölçekteki projelerde sayfa bazlı bölme, bileşen düzeyindeki ayrıntıya gitmeden render-blocking sorununu hafifletebilir. Büyük projelerde ise tek dosyayı korumak bakım yükünü artırır ve her sayfa için gereksiz CSS yüklenmesine yol açar.
Kod bölme kararında CSS ve JavaScript aynı soruyla yüzleşir: hangi kaynak hangi bağlamda gerçekten gerekli? Bu soruya cevap vermeden yapılan optimizasyonlar çoğunlukla yüzeysel kalır ve yeni bileşenler eklendikçe sorun tekrar baş gösterir.
Critical CSS: İlk Görünümü Öncelikli Yüklemek
Critical CSS, kullanıcının sayfayı ilk açtığında ekranda görünen içerik için gereken minimum stil kümesidir. Bu stilleri satır içi (inline) olarak HTML'e gömmek, harici CSS dosyasının indirilmesini beklemeden tarayıcının ilk boyamayı tamamlamasını sağlar. İlk Anlamlı Boyama (First Contentful Paint) değerini doğrudan etkileyen bu teknik, özellikle bağlantı hızının değişken olduğu mobil kullanıcılar için fark yaratır.
Uygulama süreci şöyle işler: bir araç sayfayı render eder ve yalnızca görünür alandaki öğelere uygulanan kuralları çıkarır. Bu kurallar <head> içine satır içi stil olarak eklenir; geri kalanlar rel="preload" veya JavaScript yardımıyla asenkron olarak yüklenir. Critical CSS'in boyutu çoğu durumda 14-15 KB sıkıştırılmamış boyutun altında tutulur; bu sınırın üzerine çıkıldığında satır içi yapmanın avantajı azalmaya başlar, çünkü HTML boyutu şişer.
Critical CSS yaklaşımı her durumda aynı kolaylıkla uygulanamaz. Çok sayfalı sitelerde her sayfa için farklı kritik CSS hesaplanması gerekir; bu süreç build pipeline'ına ek yük getirir ve her yeni sayfa şablonu için güncelleme ister. SPA yapılarında ise içerik JavaScript ile oluşturulduğu için statik critical CSS üretmek güçleşir; server-side rendering kullanmıyorsanız bu teknik sınırlı fayda sağlar.
Karar verilmeden önce mevcut First Contentful Paint değerinin ne kadar olduğunu ve render-blocking CSS'in buna gerçekte ne kadar katkı yaptığını ölçmek gerekir. Render-blocking kaynakların FCP'yi yalnızca birkaç milisaniye etkilediği bir sayfada, critical CSS için harcanan mühendislik zamanı başka optimizasyonlara yönlendirilebilir.
Seçici Karmaşıklığı ve Özellik Yığılması
Dosya boyutu bazen seçici karmaşıklığından değil, aynı özelliğin tekrar tekrar tanımlanmasından kaynaklanır. .btn, .btn-primary, .btn-primary-large, .btn-primary-large-disabled gibi zincirleme sınıflar CSS'in ne kadar az yeniden kullanım içerdiğini gösterir; her varyant, temel stillerini sıfırdan taşır. Biri siler mi? Pek değil.
Özgüllük (specificity) savaşları da dosya boyutunu dolaylı biçimde artırır. Kazanmak için yazılan !important kullanımları ve derin iç içe geçmiş seçiciler zamanla üstüne yazılmış katmanlar oluşturur. O katmanları silmek riskli görünür; kimse bir şeyin bağlı olup olmadığından emin olamaz; kimse silmez; dosya büyür. 10.000 satırın önemli bir kısmı çoğunlukla bu tür birikimin kalıntısıdır.
Medya sorguları da dağınıklığa katkı sağlar. Her bileşenin kendi medya sorgularını ayrı ayrı tanımladığı projelerde aynı breakpoint onlarca yerde tekrar eder. Bu tekrarlar hem dosya boyutunu artırır hem de bir breakpoint değeri değiştiğinde tüm tekrarları güncelleme yükü doğurur.
Tasarım sistemleri bu yapıyı köklü biçimde değiştirebilir: token bazlı yaklaşım hem tutarlılık hem yeniden kullanım sağlar. Ama yanlış uygulandığında, her token her bileşen için ayrı ayrı genişletildiğinde, tasarım sistemi de dosya büyümesine katkı sağlayabilir.
Minifikasyon ve Sıkıştırma: Son Kilometre
Kullanılmayan kuralları temizleyip dosyayı mantıklı parçalara böldükten sonra minifikasyon ve sıkıştırma devreye girer. Bu adım en mekanik olanıdır. Minifikasyon, boşlukları, yorumları ve gereksiz karakterleri kaldırır; CSS dosyasının boyutunu çoğu durumda yaklaşık yüzde on beş ile otuz arasında düşürür. İşlem production build sürecinde otomatik yapılır; manuel müdahale gerektirmez.
Gzip ve Brotli sıkıştırması ise sunucu katmanında gerçekleşir. Brotli, gzip'e kıyasla metin tabanlı dosyalarda daha iyi sıkıştırma oranı üretir; ancak CPU kullanımı biraz daha yüksektir. Statik dosyalar için önceden sıkıştırılmış (pre-compressed) sürümler sunmak bu maliyeti ortadan kaldırır ve her istekte yeniden sıkıştırma yükünü önler.
Sıkıştırmanın etkisi minifikasyondan çok daha büyüktür. 80 KB boyutundaki ham bir CSS dosyası minifikasyon sonrasında yaklaşık 60-65 KB'a iner; Brotli sıkıştırmasıyla bu 12-15 KB aralığına düşebilir. Sayılar projeye ve içeriğe göre değişir; ama sunucunuzda henüz sıkıştırma etkin değilse, başka bir optimizasyona geçmeden önce bu adımı tamamlamak yerinde olur.
Build sürecinde CSS sıkıştırma ve kod bölme ayarları minifikasyonla birlikte ele alındığında, production çıktısının boyutunu build aşamasında denetim altına almak mümkün hale gelir. Her build sonrasında dosya boyutunu izlemek, yeni eklenen bir bağımlılığın CSS ağırlığını fark ettirmeden artırdığı durumları erkenden yakalar.
Hangi Adıma Önce Bakılmalı?
Sıralama önemlidir. Coverage analizi ile başlamak gerekir; hangi seçicilerin gerçekten kullanıldığını görmeden bölme ya da temizleme kararı vermek kör bir çabaya dönüşür. Büyük bir kütüphanenin büyük bölümünün kullanılmadığı görülüyorsa, öncelik o kütüphaneyi değiştirmek ya da kapsamlı bir subset almaktır; küçük parça parça temizlemekten çok daha fazla etki yaratır.
Sıkıştırma henüz etkin değilse hemen etkinleştirin. Mühendislik maliyeti minimumdur, kazanım anındadır. Critical CSS ise en çok çaba gerektiren adımdır; yalnızca render-blocking CSS'in First Contentful Paint'i gerçekten etkilediği projelerde değer üretir. Diğer adımları tamamlamadan buraya geçmek zamanı verimsiz kullanmak anlamına gelir.
Sayfa yayına çıkmadan önce kontrol edilmesi gereken performans maddelerinde CSS, JavaScript yüküyle birlikte değerlendirilir; birini optimize edip diğerini göz ardı etmek genel performansı sınırlı düzeyde iyileştirir. CSS'teki kazanımların render süresine gerçekten yansıyıp yansımadığını DevTools Performance sekmesinde doğrulamak, yapılan çalışmanın etkisini somutlaştırır.
10.000 satırın tamamını tek seferde temizlemek nadiren doğru yaklaşımdır. Coverage ile kullanılmayanı görmek, birkaç bileşeni ayırmak, sıkıştırmayı açmak: her adımın etkisi ayrı ölçülür, hangisinin gerçekten fark yarattığı orada görünür.
Büyük CSS dosyalarının asıl riski yalnızca yavaş yükleme değil, kontrolsüz büyümedir. Hiç kimsenin silmediği, herkesin üstüne eklediği, kimsenin tüm içeriğini bilmediği bir dosya; bu durum teknik borç birikimi olduğu kadar bir organizasyon sorunudur. Büyük ekiplerde performans disiplini, bu tür yapısal sorunların tekrar oluşmasını engellemenin birincil yoludur.
Coverage sekmesi kullanılmayan kırmızı şeridi milisaniyeler içinde gösterir. İlk oturum, dosyanın hangi yarısının hiç çalışmadığını netleştirir.