موتور Turbolog
نحوهٔ کدگذاری طول اجرای فریمها در یک فراخوانی console.log، بههمراه CellBuffer، جزئیات Chromium و بنچمارکها.
Turbolog هر کامیت React را به یک فراخوانی console.log تبدیل میکند، یا اگر هیچ سلولی تغییر نکرده باشد، هیچ فراخوانیای انجام نمیدهد.
هدفها
- یک فراخوانی بهازای هر فریم تغییریافته.
- صفر فراخوانی در حالت بیکار. فریم بدون تغییر پیش از ساختن رشته بازمیگردد.
- آرگومانهای سبکدهی کم. 149 span از نوع
%cبرای 3,200 سلول یک داشبورد متراکم100×32.
خط پردازش
React ─▶ Yoga ─▶ CellBuffer ─▶ row-hash gate ─▶ RLE ─▶ console.logCellBuffer
فریم در آرایههای نوعدار تخت برای نویسهها، رنگها و ویژگیها نگهداری میشود که حافظهٔ آنها یک بار تخصیص مییابد.
دروازهٔ تشخیص تغییر
هر ردیف هش میشود. اگر چیزی تغییر نکرده باشد، درایور زودتر بازمیگردد:
if (frame === null) return SKIPPED; // 0 console callsconsole.log(frame.format, ...frame.args);تعویض فریم
Turbolog فریمها را به انتها اضافه میکند و کنسول را فقط در اولین فریم، پس از فراخوانی invalidate()، هنگام بیکاری پس از انباشته شدن 100 فریم و در فریم 300 پاک میکند. DevTools پیامهای پاکشده را بلافاصله حذف میکند، اما پیامهای جدید را با محدودیت زمانی 50 ms ترسیم میکند؛ بنابراین پاک کردن کنسول در هر فریم باعث میشود کنسول خالی لحظهای دیده شود. فریمهای افزودهشده در یک نوبت ترسیم جایگزین میشوند و یک span پردهای با عرض صفر، فریم قبلی را از دید خارج نگه میدارد. برای دیدن فریمهای قبلی به بالا پیمایش کنید.
آهنگ نمایش فریمها حدود 15 fps است. فریمهای سریعتر محدودیت زمانی DevTools را از نو تنظیم میکنند و کنار گذاشته میشوند.
کدگذاری طول اجرا
سلولهای یکسان در یک span از نوع %c ادغام میشوند. spanها از نویسههای خط جدید عبور میکنند و رشتههای CSS بهصورت اشتراکی ذخیره میشوند.
console.log("%c▼ Text.js%c ready", "color:#ededed;font-weight:700", "color:#45a557");جزئیات Chromium
- نویسهٔ
%بهشکل%%گریز داده میشود. - به URLها و متن
path:lineیک word joiner اضافه میشود تا DevTools سبک آنها را تغییر ندهد. - spanها فقط از ویژگیهای غیراختصاری CSS استفاده میکنند. DevTools هر ویژگی بسطیافته را روی هر خط کپی میکند.
- spanها طوری تنظیم میشوند که پسزمینهها بدون شکاف کنار هم قرار بگیرند.
Firefox و Safari
Chromium هر خط از یک span از نوع %c را بهشکل یک بلوک درونخطی چیدمان میکند. Firefox و Safari ساختار درونخطی spanها را حفظ میکنند، بنابراین حاشیههای عمودی را نادیده میگیرند و ردیفهای بلند را میشکنند. CssConsoleDriver مرورگر را با بررسی قابلیتهای CSS تشخیص میدهد و برای این دو کنسول، ارتفاع خط را بدون حاشیه روی 14 px تنظیم میکند، با text-wrap-mode: nowrap شکستن خطوط را غیرفعال میکند و با یک پردهٔ line-height: 100vh فریمهای قبلی را از دید خارج میکند. اندازهگیری متناسب با کنسول، برای ستون پیوند منبع در Firefox جا باقی میگذارد. Safari قلم Menlo را در ابتدای فهرست قلمها قرار میدهد، زیرا صفحههای آن نمیتوانند از قلم SF Mono نصبشده بهدست کاربر استفاده کنند که Web Inspector ممکن است با آن ترسیم کند. برای انتخاب کنسول بهدست خودتان، آرگومان browser را به createConsoleRoot بدهید.
بنچمارکها
فایل packages/core/test/perf.test.ts روی یک داشبورد متراکم 100×32، میانگین 1,000 فریم (Apple M5 Pro، Bun 1.4.4):
| فریم | زمان | spanهای %c |
|---|---|---|
| بازترسیم کامل (چیدمان، ترسیم، کدگذاری) | 0.163 ms | 149 |
| ویرایش یک ردیف | 0.011 ms | 149 |
| بیکار | 0.000 ms | 0 |
صفحهٔ وضعیت همین خط پردازش را در مرورگر شما اجرا میکند. هنگام اجرای یک نمونه از Playground، دستور text.stats() را در DevTools اجرا کنید.