ERETEK
BİLGİ SİSTEMLERİ

JavaScript Bütçesi: Üçüncü Taraf Betikleri Ölçmek ve Sınırlamak

Analitik, sohbet, harita ve reklam betiklerinin gerçek maliyetini ölçün; sahipli envanter, async/defer, facade, Tag Manager kuralları ve Lighthouse CI denetimi.

Bu makalede7 bölüm
Teknik özet
Teknoloji
JavaScript, async/defer, Google Tag Manager, Chrome DevTools Coverage, Lighthouse CI
Konu
Sayfadaki JavaScript yükünün ölçülmesi ve bütçeyle yönetilmesi
Seviye
Orta
Ön koşullar
  • Sitenin şablon ve etiket yönetimine erişim
  • Chrome DevTools temel kullanımı
  • CI/CD hattında komut çalıştırma yetkisi (bütçe denetimi için)

Sayfa ağırlaşmışsa ve kimse yeni kod yazmadığını söylüyorsa, betik listesine bakın. Kurumsal sitelerde JavaScript yükünün büyük kısmı sitenin kendi kodundan değil, zamanla eklenen üçüncü taraf betiklerden gelir: analitik, reklam pikselleri, canlı sohbet, harita, video, A/B test ve ısı haritası araçları. Her biri ayrı bir ekip tarafından, ayrı bir gerekçeyle eklenir. Toplam maliyeti kimse takip etmez. Bu rehber JavaScript yükünü ölçmek, bir performans bütçesiyle sınırlamak ve bütçeyi yayın sürecinde otomatik denetlemek için sahada kullandığımız yöntemi anlatıyor.

Performans bütçesi nedir

Performans bütçesi, bir sayfa veya şablonun aşmaması gereken ölçülebilir sınırların yazılı listesidir. Yazılı değilse bütçe değildir. Üç türde tanımlanabilir:

Bütçe türü Örnek ölçüt Güçlü yanı
Miktar Sıkıştırılmış JS boyutu, üçüncü taraf istek sayısı Kolay ölçülür, geliştiricinin doğrudan kontrolünde
Zamanlama Total Blocking Time, LCP Kullanıcı deneyimine daha yakın
Kural Lighthouse denetimlerinden geçme Belirli hataları (ör. render engelleyen kaynak) yakalar

JavaScript için bayt sınırı tek başına yetmez. Aynı boyuttaki iki betikten biri bir kez çalışıp biterken diğeri sürekli zamanlayıcılar ve dinleyiciler kurabilir. Bu yüzden boyut bütçesini bir zamanlama ölçütüyle (laboratuvarda TBT, sahada INP) birlikte tanımlayın. Sayısal değer, mevcut durum ölçüldükten ve hedef cihaz sınıfı belirlendikten sonra şablon bazında yazılır: ana sayfa, hizmet sayfası, blog yazısı ve form sayfası farklı ihtiyaçlara sahiptir.

Betik envanteri çıkarmak

Neyin yüklendiğini bilmeden bütçe yönetilmez. İlk adım, her şablon için yüklenen tüm betiklerin envanterini çıkarmaktır. Envanterde teknik bilgilerin yanında iş sahibi ve gerekçe de yer almalı. Sahibi bulunamayan betik kaldırma adayıdır; denetimlerde bu listenin hiç de kısa çıkmadığını görürüz.

Betik Sahip / amaç Yüklendiği sayfalar Yükleme biçimi
Analitik Pazarlama / trafik ölçümü Tümü async, onaya bağlı
Canlı sohbet Satış / ön talep Tümü Senkron (gözden geçirilecek)
Harita İletişim sayfası Tümü (hata) Sayfaya özel olmalı
Isı haritası Sahibi belirsiz Tümü Kaldırma adayı

Envanter için DevTools Network panelinde JS filtresini seçin ve sütunlara “Domain” ekleyerek isteği yapan alan adlarını görün. -domain:ornek.com gibi negatif filtre kendi alan adınızı gizler, yalnız üçüncü tarafları bırakır. Bir betiğin başka betikleri yüklediğini (zincirleme) görmek için “Initiator” sütununa bakın; Tag Manager üzerinden yüklenen etiketler burada konteyner betiğine bağlı görünür.

Üçüncü taraf betiklerin maliyetini ölçmek

Bir betiğin maliyeti indirme boyutundan ibaret değildir: ayrıştırma, derleme, çalıştırma, eklediği DOM öğeleri ve kurduğu dinleyiciler de faturaya yazılır. Dört pratik yöntemi birlikte kullanın:

  1. Lighthouse’un üçüncü taraf kodu bulgusu (eski sürümlerde third-party-summary, güncel sürümlerde “3rd parties” içgörüsü): Üçüncü taraf sağlayıcıları aktarım boyutu ve ana iş parçacığında harcanan süreyle listeler.
  2. Coverage paneli: DevTools’ta Coverage panelini açıp sayfayı yeniden yükleyin; her dosya için indirilen ama kayıt süresince hiç çalıştırılmayan bayt oranı gösterilir. Bu oran yalnız kayıt sırasında yapılan etkileşimleri yansıtır; menü veya form gibi sonradan kullanılan kod da “kullanılmayan” görünebilir. Kullanılmayan oranı yüksek büyük dosyalar ya sayfaya özel yüklenmeli ya da bölünmelidir.
  3. İstek engelleme ile karşılaştırma: Network panelinde bir isteğe sağ tıklayıp alan adını engelleyin ve sayfayı yeniden ölçün. İki ölçüm arasındaki fark, o betiğin sayfaya gerçek maliyetidir.
  4. Performance paneli: CPU yavaşlatmayla kayıt alıp Bottom-Up görünümünü “Group by domain” ile gruplayın; ana iş parçacığı süresinin hangi alan adlarına gittiği görünür.

Üçüncü yöntem tartışmayı bitirir. Rakam masaya gelince betiğin sahibi de gerekçesini yeniden düşünür.

Yükleme stratejileri: async, defer, facade

Bir betiği tamamen kaldıramıyorsanız ne zaman ve nasıl yüklendiğini değiştirerek maliyetini azaltın.

async ve defer

Öznitelik içermeyen bir <script src> etiketi HTML ayrıştırmasını durdurur. async betik paralel indirilir ve indirildiği an çalışır; sıralama garantisi yoktur. defer betikler paralel indirilir, HTML ayrıştırması bittikten sonra yazıldıkları sırayla çalışır. type="module" betikler varsayılan olarak defer davranışındadır. Sahada sık gördüğümüz hata, birbirine bağımlı iki betikten birine async verilmesidir: çoğu zaman çalışır, bazen sıra bozulur ve hata yalnız yavaş bağlantıda ortaya çıkar. WordPress 6.3 ve sonrasında tema ve eklenti betikleri için yükleme stratejisi doğrudan kayıt sırasında belirtilebilir:

wp_enqueue_script(
    'kurumsal-ui',
    get_template_directory_uri() . '/assets/js/ui.js',
    array(),
    '2.4.0',
    array(
        'strategy'  => 'defer',
        'in_footer' => true,
    )
);

Etkileşimde yükleme (facade)

Facade, ağır bir bileşenin yerine görsel olarak benzeyen hafif bir yer tutucu koyup gerçek betiği yalnız kullanıcı etkileşime geçtiğinde yükleme tekniğidir. Kurumsal sitelerde en çok işe yaradığı yerler:

  • Video gömmeleri: Video oynatıcı yerine önizleme görseli ve oynat düğmesi; tıklamada iframe eklenir.
  • Canlı sohbet: Sağ altta statik bir düğme; tıklamada veya kullanıcı belirli bir süre sayfada kaldıktan sonra sohbet betiği yüklenir.
  • Harita: İletişim sayfasında statik harita görseli ve “Haritayı aç” bağlantısı.
const sohbetDugmesi = document.querySelector('#sohbet-baslat');
sohbetDugmesi.addEventListener('click', () => {
  const s = document.createElement('script');
  s.src = 'https://sohbet.ornek-saglayici.com/widget.js';
  s.async = true;
  s.onload = () => window.SohbetWidget?.open();
  document.head.appendChild(s);
}, { once: true });

Facade’in bedeli var: ilk tıklamada bileşenin açılması gecikir. Bu gecikmeyi kullanıcıya bir yükleniyor göstergesiyle bildirin ve sağlayıcının API’sinin programatik açmayı desteklediğini doğrulayın (yukarıdaki open() çağrısı sağlayıcıya göre değişir). Desteklemiyorsa kullanıcı iki kez tıklamak zorunda kalır.

Tag Manager disiplini

Google Tag Manager gibi etiket yöneticileri betik eklemeyi geliştirme sürecinin dışına taşır. Disiplin yoksa bütçe en hızlı burada delinir. Asgari kurallar:

  • Her etiketin adında veya notunda sahibi ve amacı yazılı olsun; çeyrek dönemlik gözden geçirmede sahipsiz etiketler duraklatılsın.
  • “Tüm sayfalar” tetikleyicisi yalnız gerçekten tüm sayfalarda gereken etiketlere verilsin; kampanya pikselleri ilgili landing page’lerle sınırlansın.
  • Özel HTML etiketleri kod incelemesinden geçsin; bunlar sayfaya doğrudan betik ekleyen, denetimi en zor etiket türüdür.
  • Tıklama ve form tetikleyicileri gereğinden geniş tanımlanmasın; her tıklamada çalışan dinleyiciler INP’yi etkiler (ayrıntı için INP iyileştirme rehberi).
  • Konteyner yayınlarına yetki sınırlı olsun ve her yayına açıklama yazılsın; böylece performans gerilemesi bir yayınla eşleştirilebilir.
  • Pazarlama ve analitik etiketleri kullanıcı onayına bağlı yüklensin. Onay öncesi yüklenmeyen etiket hem KVKK açısından doğru hem de ilk yükte maliyetsizdir; uygulama ayrıntısı için çerez onayına göre etiket yükleme rehberine bakın.

Bütçeyi CI’da denetlemek

Yazılı bir bütçe otomatik denetlenmezse birkaç ay içinde aşılır. Lighthouse CI belirlenen URL’leri birden fazla kez ölçer, sonuçları eşik değerlerle karşılaştırır ve eşik aşılırsa derlemeyi başarısız sayar. Örnek bir lighthouserc.json:

{
  "ci": {
    "collect": {
      "url": [
        "https://staging.ornek.com/",
        "https://staging.ornek.com/hizmetler/ornek-hizmet/"
      ],
      "numberOfRuns": 3
    },
    "assert": {
      "assertions": {
        "resource-summary:script:size": ["error", { "maxNumericValue": 300000 }],
        "resource-summary:third-party:count": ["warn", { "maxNumericValue": 15 }],
        "total-blocking-time": ["warn", { "maxNumericValue": 300 }]
      }
    },
    "upload": {
      "target": "filesystem",
      "outputDir": "./lhci-rapor"
    }
  }
}
npm install -g @lhci/cli
lhci autorun

Bu örnekteki eşikler yalnız sözdizimini göstermek için; kendi değerlerinizi mevcut ölçümünüzden türetin. resource-summary boyutları bayt, total-blocking-time milisaniye cinsindendir. Denetim kimlikleri Lighthouse sürümleri arasında değişebildiği için kullandığınız sürümün rapor JSON’unda bu kimliklerin bulunduğunu doğrulayın. Laboratuvar ölçümleri çalıştırmadan çalıştırmaya oynar. Birden fazla çalıştırma yapın, zamanlama ölçütlerini önce “warn” seviyesinde tutun, gürültüyü gözlemledikten sonra “error” seviyesine yükseltin. İlk günden “error” koyarsanız ekip, rastgele kırmızıya düşen bir hattı kısa sürede görmezden gelmeye başlar. Lighthouse CI’ı yayın hattına ekleme adımları için GitHub Actions ile CI/CD rehberine başvurabilirsiniz.

Üçüncü taraf betikler sizin yayınınız olmadan değişebilir. Bu yüzden CI denetimini üretim ortamına karşı periyodik (ör. günlük) bir ölçümle ve sahada INP izlemesiyle tamamlayın. Bütçe aşıldığında kural basittir: yeni betik ancak bütçede yer açılırsa (başka bir betik kaldırılarak veya facade’e alınarak) eklenir. İstisna yok.

Ölçüm ihtiyaçlarını performans maliyetiyle dengeleyen bir etiket mimarisi için web analitik ve dönüşüm ölçümü, bütçenin şablon bazında belirlenmesi ve izlenmesi için web performansı ve Core Web Vitals hizmet sayfalarımızı inceleyebilirsiniz. Lighthouse CI yapılandırma seçeneklerinin tamamı Lighthouse CI proje dokümantasyonunda yer alır.

Sık sorulan sorular

Performans bütçesi için hangi sayı doğru?

Evrensel bir sayı yoktur. Önce sayfa şablonları bazında bugünkü JavaScript boyutunu ve uzun görev süresini ölçün, sonra hedef cihaz sınıfında Core Web Vitals eşiklerini tutturan seviyeyi bütçe olarak sabitleyin. Asıl mesele sayının yazılı olması ve her yeni betiğin bu sayıya göre değerlendirilmesidir.

async ve defer arasındaki fark nedir?

İkisi de betik indirilirken HTML ayrıştırmasını durdurmaz. async betik indirildiği anda çalışır ve sıra garantisi yoktur; defer betikler HTML ayrıştırması bittikten sonra, belgede yazıldıkları sırayla ve DOMContentLoaded olayından önce çalışır. Birbirine bağımlı betiklerde defer, bağımsız ölçüm betiklerinde async kullanın.

Tag Manager kullanmak sayfayı yavaşlatır mı?

Konteyner betiğinin kendisi bir maliyettir, ama asıl yük içine eklenen etiketlerden gelir. Sahipsiz özel HTML etiketleri, tüm sayfalarda tetiklenen pazarlama pikselleri ve tıklama dinleyicileri hem yükleme süresini hem INP’yi etkiler. Etiketlerin sahibi, amacı ve tetikleyici kapsamı düzenli gözden geçirilirse Tag Manager yönetilebilir kalır.

Lighthouse CI üretim sitesine karşı mı çalıştırılmalı?

Bütçe denetiminin amacı aşımı yayından önce yakalamaktır; bu yüzden staging ortamına veya CI içinde ayağa kaldırılan bir önizleme ortamına karşı çalıştırın. Üretime karşı periyodik çalıştırma ise üçüncü taraf betiklerin sizin yayınınız olmadan değişmesini fark etmek için ek kontroldür.

Teknik özet
Teknoloji
JavaScript, async/defer, Google Tag Manager, Chrome DevTools Coverage, Lighthouse CI
Konu
Sayfadaki JavaScript yükünün ölçülmesi ve bütçeyle yönetilmesi
Seviye
Orta
Ön koşullar
  • Sitenin şablon ve etiket yönetimine erişim
  • Chrome DevTools temel kullanımı
  • CI/CD hattında komut çalıştırma yetkisi (bütçe denetimi için)
Eretek uzman desteği

Bu konu sizin ortamınızda nasıl çalışır, birlikte bakalım.

Mevcut yapınızı inceliyor, darboğazı tespit ediyor ve uygulanabilir bir iş planı öneriyoruz.