ميزانية الإطار: من أين تأتي الأرقام؟
عند 60 إطارًا في الثانية يملك الإطار 16.6 ملّي ثانية، وعند 120 إطارًا يملك 8.33 فقط. هذه الميزانية تشمل استقبال التحديثات، وتحديث الذاكرة، والتحليل، وبناء الأشكال، والرسم. تجاوزها بملّي ثانية واحدة يعني إطارًا مفقودًا يراه المستخدم كتقطيع.
frame budget @ 120 Hz = 8.33 ms ingest + ring write ~0.15 ms O(1) per bar, no copy LOD select ~0.10 ms pick pyramid level analysis (patterns) ~0.60 ms visible window only geometry build ~0.90 ms 3 instances per candle GPU draw ~1.20 ms 1 drawArraysInstanced call ────────────────────────────── headroom ~5.4 ms
نداء رسم واحد لكل إطار
الطريقة التقليدية ترسم كل شمعة بأوامر منفصلة، فتتحوّل التكلفة إلى آلاف انتقالات بين المعالج والمعالج الرسومي. يستخدم المحرك instanced rendering: شكل أساسي واحد يُعاد استخدامه، وبيانات كل شمعة تُرفع في مخزن واحد، ثم تُرسم كل الشموع بنداء drawArraysInstanced واحد — ثلاثة أشكال لكل شمعة (الجسم وظلّان).
ذاكرة TimeRing العمودية
تُخزَّن السلسلة في مصفوفات منفصلة لكل حقل: الزمن، الافتتاح، الأعلى، الأدنى، الإغلاق، الحجم. هذا الترتيب العمودي يجعل قراءة حقل واحد عبر آلاف الشموع متتالية في الذاكرة، فيستفيد المعالج من الذاكرة المؤقتة بدل التنقّل العشوائي بين كائنات. الكتابة حلقية بزمن ثابت O(1) دون إعادة تخصيص أو نسخ.
هرم التفاصيل الذي لا يفقد القمم
عند تصغير العرض لا فائدة من رسم شمعة لكل نقطة بيانات، لأن عرض الشمعة يصبح أقل من بكسل. يبني المحرك مستويات مجمّعة مسبقًا (كل 2، 4، 8 … شموع) ويختار المستوى المناسب لعرض الشمعة الحالي. القاعدة الحاكمة أن كل مستوى يحتفظ بأعلى قمة وأدنى قاع داخل المجموعة، فلا يختفي مستوى سعري مهم بسبب التجميع.
L0: every bar (N) L1: 2-bar buckets (N/2) high = max(h), low = min(l) L2: 4-bar buckets (N/4) L3: 8-bar buckets (N/8) ... select level so that candle width >= 2 px
ماذا يحدث على الأجهزة التي لا تدعم WebGL2؟
يتحقّق المحرك من توفّر السياق الرسومي عند الإقلاع. إن لم يتوفّر WebGL2 ينتقل تلقائيًا إلى مسار Canvas 2D بنفس البيانات ونفس المنطق، ويظهر المسار المستخدم في شريط الإحصاءات داخل اللوحة. لا تفقد أي وظيفة تحليلية، إنما يقلّ عدد الأشكال القابل للرسم بسلاسة.
