محرك Turbolog

كيفية ترميز الإطارات بأطوال التتابع في استدعاء console.log واحد، مع CellBuffer وتفاصيل Chromium واختبارات الأداء.

يحوّل Turbolog كل عملية تثبيت تغييرات في React إلى استدعاء واحد للدالة console.log، أو لا يستدعيها إذا لم تتغير أي خلية.

الأهداف

  1. استدعاء واحد لكل إطار متغير.
  2. صفر استدعاءات عند الخمول. يعود الإطار غير المتغير قبل بناء سلسلة نصية.
  3. عدد قليل من وسائط التنسيق. ⁦149 span⁩ من نوع %c لخلايا لوحة معلومات كثيفة بأبعاد 100×32 وعددها 3,200 خلية.

خط المعالجة

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

CellBuffer

يُخزّن الإطار في مصفوفات مسطحة محددة النوع للأحرف والألوان والسمات، تُخصّص مرة واحدة.

بوابة التغييرات

تُحسب بصمة تجزئة لكل صف. إذا لم يتغير شيء، يعود برنامج التشغيل مبكرًا:

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

تبديل الإطارات

يُلحق Turbolog الإطارات ولا يمسح وحدة التحكم إلا عند الإطار الأول، وبعد invalidate()، وعند الخمول بعد تراكم 100 إطار، وعند 300 إطار. تزيل DevTools الرسائل الممسوحة فورًا، لكنها ترسم الرسائل الجديدة بفاصل لا يقل عن 50 ms، لذا يؤدي المسح عند كل إطار إلى وميض وحدة تحكم فارغة. تتبدل الإطارات الملحقة ضمن عملية رسم واحدة، ويحجب span ستاري بعرض صفري الإطار السابق عن الأنظار. مرّر لأعلى لرؤية الإطارات السابقة.

تُضبط وتيرة الإطارات على نحو 15 إطارًا في الثانية. تعيد الإطارات الأسرع ضبط مؤقت التقييد في DevTools وتُسقط.

ترميز طول التتابع

تندمج الخلايا المتطابقة في span واحد من نوع %c. تمتد عناصر span عبر فواصل الأسطر، وتُخزّن سلاسل CSS النصية بنسخ موحّدة مشتركة.

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

تفاصيل Chromium

  • يُهرّب الرمز الحرفي % بصيغة %%.
  • تُضاف علامة ⁦word joiner⁩ إلى عناوين URL ونصوص path:line كي لا تعيد 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 ms149
تعديل صف واحد0.011 ms149
الخمول0.000 ms0

تشغّل صفحة الحالة خط المعالجة نفسه في متصفحك. شغّل text.stats() في DevTools أثناء تشغيل عرض توضيحي من Playground.

تحرير هذه الصفحة على GitHub