← Blog

Turbolog: parlamayı giderme

Her kareden önce konsolu temizlemek, DevTools çizimlerinin %70–81’inde konsolu görünür biçimde boş bırakıyordu. Kareleri sona eklemek bu oranı %1’e indirdi; bunun tamamı ilk karede gerçekleşti.

Adam

Her Text.js karesi bir console.log çağrısıdır. 0.4 sürümüne kadar her kareden önce bir de console.clear() çağrısı vardı. Yük altında konsol, kareler arasında kısa süreliğine boş görünüyordu.

Yanıp sönmeyi ölçme

Bunu ölçmek için bench/devtools aracını geliştirdik. Chrome for Testing’i başlatır, gerçek DevTools arayüzünü bir sayfa olarak açar ve ölçüm için izler:

  • DevTools arayüzündeki her requestAnimationFrame çağrısında, konsolun görünüm alanında 32 satırlık tam bir kare olup olmadığını kontrol eder. Böyle bir kare içermeyen çizimler boş çizim sayılır.
  • Sonucu piksel düzeyinde doğrulamak için daha sonra Page.startScreencast karelerinin kodunu çözer.
  • Her kare, 0 numaralı satırda FRAME:<id> · T:<epochMs> taşır; böylece arayüz hangi kareyi gösterdiğini ve ne kadar geciktiğini belirleyebilir.

Her kareden önce console.clear() çağrıldığında, 15 fps hızındaki 100×32 boyutlu bir gösterge paneli DevTools çizimlerinin %70,6 kadarında boştu. 60 fps hızında bu oran %81,1 idi.

Nedeni

DevTools’un ConsoleView bileşeni iki çağrıyı farklı işler:

  1. console.clear(), görünüm alanını eşzamanlı olarak geçersiz kılan consoleCleared() çağrısını yapar. Her mesaj aynı görev içinde kaybolur.
  2. console.log(), yalnızca 50 ms zaman aşımına sahip bir Throttler olan viewportThrottler üzerinden yenileme planlayan addConsoleMessage() çağrısını yapar.

Böylece her kare eski kareyi hemen kaldırır, yenisini ise daha sonra çizer. 15 fps hızında her 66 ms’nin yaklaşık 50 ms’sinde hiçbir şey görünmez.

Kareleri sona ekleme

0.4 sürümünden beri Turbolog kareleri sona ekliyor. DevTools konsolun en altında kalır, böylece yeni kare tek bir çizim içinde eskisinin yerini alır. Başta yer alan, margin-top:100vh stiline sahip sıfır genişlikli bir span (perde), önceki kareleri görünümün dışına iter ve kendi satırını sonlandırır; böylece DevTools kaynak bağlantısı 0 numaralı satırı hiçbir zaman daraltmaz.

Konsolun yine de eninde sonunda boşaltılması gerekir. Temizleme yalnızca ilk karede, invalidate() sonrasında, 100 kare biriktiğinde boşta ve kesin üst sınır olan 300 kareye ulaşıldığında gerçekleşir.

Hızı sınırlayıcıya uyarlama

DevTools’un çizebileceğinden daha hızlı kare göndermek hiçbir şeyi hızlandırmaz. Sınırlayıcı beklerken gelen bir günlük kaydı onu yeniden başlatır, bu yüzden kareler atlanır: 60 fps hızında DevTools, gönderilen 295 karenin 67 tanesini çizdi. Turbolog kareler arasında en az 66 ms bırakır, yani yaklaşık 15 fps hızında çalışır ve aralık izin verdiğinde ayrık girdileri eşzamanlı olarak render etmeye devam eder.

Faz kilidini kırma

Temizleme işlemleri, sonraki her kareye yaklaşık 50 ms gecikme de ekliyordu. Temizlemeden sonra DevTools sentetik bir Console was cleared satırı ekler. Bu satır sınırlayıcının anında işlem yuvasını alır ve sonraki kareyi 50 ms’lik zamanlayıcıya iter; sabit 66 ms aralıklarla gelen sonraki her kare bu zamanlayıcıya kilitli kalır.

Render motoru artık her temizlemeden sonra bir kez 110 ms bekliyor. Bundan sonra her kare, önceki yenilemenin tamamlanmasından 50 ms’den fazla süre sonra gelir ve DevTools’un anında işleme yolunu kullanır. Ortanca görüntüleme gecikmesi 63 ms’den 10,4 ms’ye düştü.

Sonuçlar

bun bench/devtools/run.ts --strategy=native,clear --fps=15,60 --seconds=5, 100×32 boyutlu gösterge paneli, gerçek DevTools arayüzü:

SürücüFPSBoş çizimlerÇizilen / gönderilenGecikme p50
Her karede temizleme15%70,670 / 7560,4 ms
Sona ekleme (1.0)15%1,074 / 7510,4 ms
Her karede temizleme60%81,145 / 3009,8 ms
Sona ekleme, hız ayarsız60%0,867 / 29531,2 ms

Kalan %1, konsolu bilerek temizleyen ilk karedir. Bu karenin boş çizimlerinde boş bir konsol yerine Console was cleared satırı vardır.

Span başına daha az özellik

DevTools’un kaynak kodu bir maliyet daha ortaya koydu. Bir %c stilinin her uzun yazımlı özelliğini her satır sarmalayıcısına kopyalar; bu yüzden font: ve margin: kısa yazımları span başına yaklaşık 33 özelliğe genişliyordu. Span’ler artık onaltılık renklerle, her biri yaklaşık 7 tane olmak üzere yalnızca uzun yazımlı özellikleri kullanıyor.

Sona ekleme modu Text.js 0.4 ile yayımlandı ve faz kilidi düzeltmesi 1.0 ile geliyor. İkisi de uygulama kodunda değişiklik gerektirmiyor.