Bộ máy Turbolog

Cách mã hóa độ dài loạt cho frame thành một lệnh gọi console.log, cùng CellBuffer, chi tiết về Chromium và đo hiệu năng.

Turbolog chuyển mỗi commit của React thành một lần gọi console.log, hoặc không gọi lần nào nếu không có ô nào thay đổi.

Mục tiêu

  1. Một lần gọi cho mỗi frame thay đổi.
  2. Không gọi khi nhàn rỗi. Frame không thay đổi sẽ trả về trước khi tạo chuỗi.
  3. Ít đối số định kiểu. 149 span %c cho 3.200 ô của một bảng tổng quan dày đặc 100×32.

Quy trình xử lý

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

CellBuffer

Frame nằm trong các mảng định kiểu phẳng dành cho ký tự, màu sắc và thuộc tính, cấp phát một lần.

Cổng kiểm tra thay đổi

Mỗi dòng đều được băm. Nếu không có gì thay đổi, driver trả về sớm:

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

Hoán đổi frame

Turbolog nối thêm frame và chỉ xóa console ở frame đầu tiên, sau invalidate(), khi nhàn rỗi sau khi đã xếp chồng 100 frame, và khi đạt 300 frame. DevTools loại bỏ ngay các thông báo đã xóa nhưng giới hạn nhịp vẽ thông báo mới ở 50 ms, nên xóa ở mỗi frame sẽ làm console trống nhấp nháy. Các frame nối thêm hoán đổi trong một lần vẽ, và một span màn che có chiều rộng bằng không giữ frame trước ngoài tầm nhìn. Cuộn lên để xem các frame trước.

Frame chạy với nhịp khoảng 15 fps. Các frame nhanh hơn đặt lại bộ giới hạn nhịp của DevTools và bị loại bỏ.

Mã hóa độ dài loạt

Các ô giống nhau gộp thành một span %c. Span tiếp tục qua ký tự xuống dòng, và các chuỗi CSS được lưu dùng chung.

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

Chi tiết về Chromium

  • Ký tự % nguyên dạng được thoát thành %%.
  • URL và văn bản path:line có thêm word joiner để DevTools không định kiểu lại chúng.
  • Span chỉ dùng CSS dạng đầy đủ. DevTools sao chép từng thuộc tính đã mở rộng vào mỗi dòng.
  • Span được điều chỉnh để các nền lát kín, không có khoảng trống.

Firefox và Safari

Chromium bố trí mỗi dòng của một span %c như một khối nội tuyến. Firefox và Safari giữ span ở dạng nội tuyến, nên bỏ qua lề dọc và ngắt các dòng dài. CssConsoleDriver nhận diện trình duyệt bằng cách kiểm tra tính năng CSS và, với hai console đó, đặt chiều cao dòng là 14 px không có lề, tắt ngắt dòng bằng text-wrap-mode: nowrap và đẩy các frame trước ra ngoài tầm nhìn bằng màn che line-height: 100vh. Điều chỉnh kích thước cho vừa console sẽ chừa chỗ cho cột liên kết nguồn của Firefox. Safari đặt Menlo đầu tiên trong danh sách phông chữ, vì các trang của nó không thể dùng SF Mono do người dùng cài đặt mà Web Inspector có thể dùng để vẽ. Truyền browser vào createConsoleRoot để tự chọn console.

Đo hiệu năng

packages/core/test/perf.test.ts trên một bảng tổng quan dày đặc 100×32, trung bình của 1.000 frame (Apple M5 Pro, Bun 1.4.4):

FrameThời gianSpan %c
Vẽ lại toàn bộ (layout, vẽ, mã hóa)0,163 ms149
Sửa một dòng0,011 ms149
Nhàn rỗi0,000 ms0

Trang Trạng thái chạy cùng quy trình xử lý trong trình duyệt của bạn. Chạy text.stats() trong DevTools khi một bản demo từ Playground đang chạy.

Sửa trang này trên GitHub