Mesin Turbolog

Cara frame dikodekan dengan run-length encoding menjadi satu panggilan console.log, beserta CellBuffer, detail Chromium, dan tolok ukur.

Turbolog mengubah setiap commit React menjadi satu panggilan console.log, atau tanpa panggilan jika tidak ada sel yang berubah.

Tujuan

  1. Satu panggilan per frame yang berubah.
  2. Nol panggilan saat tidak aktif. Frame yang tidak berubah langsung kembali sebelum membangun string.
  3. Sedikit argumen gaya. 149 span %c untuk 3.200 sel pada dasbor padat 100×32.

Alur pemrosesan

React ─▶ Yoga ─▶ CellBuffer ─▶ row-hash gate ─▶ RLE ─▶ console.log

CellBuffer

Frame disimpan dalam typed array datar untuk karakter, warna, dan atribut, yang dialokasikan satu kali.

Gerbang perubahan

Setiap baris dihitung hash-nya. Jika tidak ada perubahan, driver langsung kembali:

if (frame === null) return SKIPPED; // 0 console callsconsole.log(frame.format, ...frame.args);

Pergantian frame

Turbolog menambahkan frame di akhir dan membersihkan konsol hanya pada frame pertama, setelah invalidate(), saat tidak aktif setelah 100 frame menumpuk, dan pada 300 frame. DevTools langsung menghapus pesan yang dibersihkan, tetapi menggambar pesan baru dengan pembatasan interval 50 ms, sehingga membersihkan setiap frame membuat konsol kosong berkedip. Frame yang ditambahkan di akhir berganti dalam satu proses penggambaran, dan span tirai selebar nol menyembunyikan frame sebelumnya. Gulir ke atas untuk melihat frame terdahulu.

Laju frame diatur sekitar 15 fps. Frame yang lebih cepat mengatur ulang pembatasan DevTools dan dibuang.

Pengodean run-length

Sel yang cocok bergabung menjadi satu span %c. Span berlanjut melintasi baris baru, dan string CSS diintern.

console.log("%c▼ Text.js%c ready", "color:#ededed;font-weight:700", "color:#45a557");

Detail Chromium

  • Literal % di-escape sebagai %%.
  • URL dan teks path:line diberi word joiner agar DevTools tidak mengubah gayanya.
  • Span hanya menggunakan CSS longhand. DevTools menyalin setiap properti yang diperluas ke setiap baris.
  • Span disesuaikan agar latar belakang tersusun tanpa celah.

Firefox dan Safari

Chromium menata setiap baris span %c sebagai blok inline. Firefox dan Safari mempertahankan span sebagai inline, sehingga keduanya mengabaikan margin vertikal dan membungkus baris panjang. CssConsoleDriver mendeteksi browser melalui pemeriksaan fitur CSS dan, untuk kedua konsol tersebut, menetapkan tinggi baris 14 px tanpa margin, menonaktifkan pembungkusan dengan text-wrap-mode: nowrap, serta menyembunyikan frame terdahulu dengan tirai line-height: 100vh. Penyesuaian ukuran konsol menyisakan ruang untuk kolom tautan sumber Firefox. Safari menempatkan Menlo di urutan pertama dalam tumpukan font, karena halamannya tidak dapat menggunakan SF Mono yang dipasang pengguna meskipun Web Inspector mungkin menggunakannya untuk menggambar. Teruskan browser ke createConsoleRoot untuk memilih konsol sendiri.

Tolok ukur

packages/core/test/perf.test.ts pada dasbor padat 100×32, rata-rata dari 1.000 frame (Apple M5 Pro, Bun 1.4.4):

FrameWaktuSpan %c
Penggambaran ulang penuh (layout, penggambaran, pengodean)0,163 ms149
Pengeditan satu baris0,011 ms149
Tidak aktif0,000 ms0

Halaman Status menjalankan alur pemrosesan yang sama di browser Anda. Jalankan text.stats() di DevTools saat demo dari Playground sedang berjalan.

Edit halaman ini di GitHub