murattunalı.
Okuma

Performans

Bir :has() seçicisi TBT’nin %70’iydi: 369 → 108 ms.

Ana sayfanın engelleme süresi bir turda altı kat arttı; suçlu yeni sahneler ya da animasyon kütüphanesi değil, o sayfada hiç eşleşmeyen on CSS kuralıydı.

Murat Tunalı YAYIN TARİHİ: OKUMA: 3′ MEASURED Performans

Hipotez

Tarayıcı izini betik, stil ve yerleşim diye ayırdığımızda yükün nerede olduğu görünür hâle geldi: stil hesabı toplamı 423 milisaniyeden 1.392 milisaniyeye çıkmıştı. Belge gerçekten büyümüştü (671 elemandan 1.733 elemana), ama asıl mesele büyüme değildi: her kare belgenin TAMAMINI yeniden hesaplatıyordu. Hipotez buydu — köke bağlı bir seçici var ve her küçük değişiklikte tüm ağacı geçersiz kılıyor.

Yöntem

İki ağaç yan yana koşuldu: dört gün önceki canlı yapı geçici bir çalışma kopyasında, güncel ağaç yanında, ikisi de aynı mobil profilde (412 × 823, piksel oranı 1,75, işlemci dört kat yavaşlatılmış). Sonra stil dosyası istek yakalayıcıyla uçuşta dönüştürüldü — diskte tek bayt değişmeden kural aileleri teker teker çıkarıldı ve her seferinde engelleme süresinin medyanı okundu. Tarayıcının kendi geçersizleme izi de açıldı; o iz hangi elemanın hangi seçiciden etkilendiğini satır satır yazıyor.

Tarih ve ortam

  1. tarih → 2026-09-21 · yerel A/B · iki ağaç yan yana
  2. profil → 412 × 823 · DPR 1,75 · CPU dört kat yavaş
  3. ölçü → TBT medyanı · stil hesabı toplamı · eleman sayısı
  4. iz → devtools.timeline.invalidationTracking

Sonuç: bisect

Kuralları aileler hâlinde çıkarmak suçluyu tek başına bıraktı. Tüm :has() seçicileri kaldırıldığında engelleme süresi 369 milisaniyeden 104 milisaniyeye iniyordu; yalnız öznesi html ya da body olanlar kaldırıldığında 115 milisaniyeye. Tek tek denendiğinde yükün neredeyse tamamı tek bir aileye toplandı.

  1. olduğu gibi → TBT 369 ms
  2. tüm :has() çıkarılmış → 104 ms
  3. yalnız html/body özneli → 115 ms
  4. :has(.menu … → 431 ms
  5. :has(main.oda) … → 430 ms
  6. :has(.sayfa__ … → 112 ms
Bir seçicinin maliyeti eşleştiği yerde değil, aradığı yerde.

Suçlu: hiç eşleşmeyen on kural

Kalan aday, temel stil dosyasının on kuralıydı ve hepsi aynı kalıptaydı: öznesi html olan bir :has(), ardından geniş bir sağ taraf. Bu kuralların ana sayfada eşleşmediğini de ölçtük — hiçbiri o sayfada bir şey boyamıyordu. Yine de her tween, her motor kurulumu belgenin tamamını geçersiz kılıyordu. Çünkü tarayıcı «bu değişiklik kökteki :has() sonucunu değiştirmiş olabilir mi» sorusuna ancak alt ağacı yeniden hesaplayarak cevap verebiliyor. Geçersizleme izi bunu adıyla söylüyordu: html ve body üzerinde «:has() tarafından etkilenen» 350 ve 347 kayıt, yanında «geçersizleme kümesi alt ağacı geçersiz kılar» notu.

Çözüm: soruyu derlemeye taşımak

Sorulan soru aynı kaldı, soran taraf değişti. Bir sayfanın hangi konağı taşıdığı yükleme sonrası değişmeyen bir yapıdır — yani derleme zamanında zaten bilinir. Üretici son HTML’e bakıyor ve kökün üstüne bir im basıyor, stil de artık o imi soruyor. Özgüllük birebir aynı kaldı, yani hiçbir kuralın sırası kaymadı; hesaplanan stil farkı on iki rotada, iki genişlikte, on beş binden fazla eleman üzerinde sıfır çıktı.

  1. yerel TBT → 369 → 97–108 ms (5 koşum)
  2. stil hesabı → 1.415 → 783 ms
  3. hesaplanan stil farkı → 0 (12 rota × 2 genişlik)
  4. canlı TBT medyanı → 293 → 83 / 86 ms

Nöbetçi

Bulgu bir kapıya bağlandı, çünkü yorumla yazılmış bir karar bir sonraki turda sessizce bozulur. Kapı üç şey soruyor: im ile konak diskte iki yönlü eşleşiyor mu, üretilmiş stil dosyasında o kalıp kaldı mı, ve iki rotanın yüklenmesinde kökün alt ağacı kaç kez geçersiz kılınıyor. Kapının düşebildiği, kusur geri konarak doğrulandı: eski kurallar geri yazıldığında sayaç ikiden kırk dokuza çıkıyor. Düşemeyen bir nöbetçi yeşil değildir, yalnız sessizdir.

Sınırlar

Buradaki sayılar bu makinenin ve bu belgenin sayıları; başka bir sayfada oran başka çıkar. Çıkarılacak kural «:has() yavaştır» da değil — o seçici yerinde kullanıldığında ucuzdur. Kural şu: öznesi html ya da body olan bir :has(), eşleşmediği sayfada bile her değişiklikte belgenin tamamını geçersiz kılar. Yükleme sonrası değişmeyen bir yapıyı çalışma zamanında seçiciyle sormak yerine derlemede işaretlemek gerekiyor.

Murat Tunalı

Kurucu. 20 yıl kurumsal IT altyapısı + web geliştirme.

Sonraki yazı →

KAYNAKLAR

ŞEMA: BLOGPOSTING + PERSON + BREADCRUMBLIST — YAZAR, TARİH VE OKUMA SÜRESİ ALANLARI ŞEMAYI BESLER