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
- Satu panggilan per frame yang berubah.
- Nol panggilan saat tidak aktif. Frame yang tidak berubah langsung kembali sebelum membangun string.
- Sedikit argumen gaya. 149 span
%cuntuk 3.200 sel pada dasbor padat100×32.
Alur pemrosesan
React ─▶ Yoga ─▶ CellBuffer ─▶ row-hash gate ─▶ RLE ─▶ console.logCellBuffer
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:linediberi 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):
| Frame | Waktu | Span %c |
|---|---|---|
| Penggambaran ulang penuh (layout, penggambaran, pengodean) | 0,163 ms | 149 |
| Pengeditan satu baris | 0,011 ms | 149 |
| Tidak aktif | 0,000 ms | 0 |
Halaman Status menjalankan alur pemrosesan yang sama di browser Anda. Jalankan text.stats() di DevTools saat demo dari Playground sedang berjalan.