تُرجمت هذه الصفحة آليًا وقد تحتوي على أخطاء. اقرأ الأصل الإنجليزي

التوثيق

تقرير الأداء

كلفة تطبيقات NSH مقيسة بالأرقام. لمعرفة كيف يحافظ NSH على سرعتها وكيف تقيس أداء تطبيقك، راجع الأداء.

#القياسات المرجعية

من القياسات المرجعية الخاصة بـ NSH (على Apple silicon ما لم يُذكر خلاف ذلك):

السيناريوالأرقام
تطبيق عدّاد، بلا واجهة (headless) (debug)أول إطار ~0.5–0.65 ms (58 عملية / 49 عنصر تركيب)؛ نقرة واحدة ~0.15 ms
تطبيق عدّاد، Mac Catalyst (release)أول إطار ~1.05–1.15 ms (منها نحو 0.7 ms لتخطيط 10 نصوص بواسطة CoreText لأول مرة)؛ نقرة واحدة ~0.12 ms
قائمة صور المعرض، بلا واجهة (headless) (debug)أول إطار 653 عملية / 224 عقدة، ~2.7 ms
تمرير قائمة الصور، Catalyst (release)إعادة ربط صف واحد أثناء التمرير البطيء ~0.4 ms؛ شاشة كاملة من ~32 صفًا عند تمرير سريع 0.9–1.6 ms
تمرير قائمة الصور، محاكي Android (arm64، release)إعادة ربط صف واحد ~0.3–0.4 ms (JS ~60 µs)
بدء تشغيل المحرك (release)~75–155 µs؛ الواجهات العامة (fetch، URL، …) لا تكلّف شيئًا حتى أول استخدام، ثم ~90 µs
إعادة التحميل الفوري (Hot reload)~120 ms من حفظ الملف حتى تشغيل النسخة الجديدة؛ وتطبيق التحديث 0.2–0.5 ms

#Linux (GTK 4)

قيست على حاسوب مكتبي يعمل بنظام Linux (x86_64، 24 خيطًا، معالج رسوميات NVIDIA)، بنسخ release، والمعرض في نافذة 1896 × 1030 على شاشة 120 Hz، وكل قراءة أُخذت تلقائيًا بواسطة examples/gallery/tools/perf.py (nsh test --target linux --fps، سطر واحد كل ثانية؛ المعالج CPU يخص العملية بأكملها، كنسبة مئوية من نواة واحدة). Frame p95 هو زمن الخيط الرئيسي لكل إطار مرسوم عند المئين 95: وإذا كان أقل من 8.3 ms فإن الإطار يتسع داخل تحديث الشاشة بمعدل 120 Hz.

#العروض المتحركة

العرضFPSFrame p95CPU
Stocks: 22 خطًا مصغّرًا حيًّا، ومخطط خلال اليوم، ودفتر أوامر، وشريط صفقات117–1205–6 ms25–29% (1200 × 800)، 28–32% (1896 × 1030)
Stocks، والنافذة تملأ شاشة 4K بمعدل 144 Hz وبمقياس 1.6×143–1454.1–4.4 ms26–29%
Canvas: مقياس، وساعة، ومصفوفة نقاط1202.6–4.4 ms5–10%
Animations: ثلاث حلقات أصلية، وسوابض (springs)، وتسلسلات1202.0 ms12–13%

#كل صفحة

كل صفحة من صفحات المعرض، عند فتحها وأثناء تمرير الاختبار لها، في نافذة 1200 × 800 على شاشة 144 Hz (الجهاز نفسه). يرسم NSH إطارًا فقط عندما يتغير شيء على الشاشة، لذا فإن FPS هنا هو المعدل أثناء حدوث حركة: إطار واحد لكل فترة وسيطة بين الإطارات المرسومة (perf.py الخاص بـ moving)؛ وعند 144 للشاشة، يأتي كل إطار من إطارات الحركة أو التمرير بعد تحديث واحد من الإطار السابق. أكثر من تحديث واحد هي نسبة الإطارات التي استغرقت أكثر من تحديث واحد (6.9 ms). يُشغَّل GIF وWebP في Images بمعدلات إطاراتها الخاصة (نحو 50 FPS هنا)، وكذلك الفيديو. صفحات Physics وOverlays وMenus قصيرة: ففي 1200 × 800 يصل التمرير إلى نهايتها خلال بضعة إطارات، لذلك تُقاس في نافذة 900 × 500 حيث يتوفر لها متسع للتمرير.

الصفحةمصدر الإطاراتFPSFrame p95أكثر من تحديث واحدCPU
Stocksبيانات حية، حلقات أصلية1444.1 ms0%26%
Stocks، تمريربيانات حية، تمرير1444.1 ms0%25%
Photos، تمريرتمرير1442.8 ms2%9%
Lists، تمريرتمرير1431.7 ms0%7%
Scrolling، تمريرتمرير1441.6 ms1%4%
Navigation، تمريرتمرير1431.7 ms0%2%
Form، تمريرتمرير1441.3 ms0%4%
Resizable، تمريرتمرير1430.6 ms0%1%
Dock، تمريرتمرير1420.5 ms1%1%
Gesturesسوابض (springs)، حلقة نابضة1441.6 ms0%1–5%
Physics، تمريرتمرير (نافذة 900 × 500)1441.6 ms1%1%
Animationsحلقات أصلية1442.6 ms0–1%5%
Canvas، تمريرتمرير، حلقات أصلية1444.2 ms0%1–4%
Styles، تمريرتمرير1442.3 ms2%3%
Tailwindأدوات animate-* المساعدة (utilities)1441.7 ms0%3–8%
Text، تمريرتمرير1441.9 ms0%4%
Text View، تمريرتمرير1411.8 ms2%7%
Images، تمريرتمرير، إطارات GIF وWebP1432.9 ms2%8%
Components، تمريرتمرير1441.4 ms0%3%
Overlays، تمريرتمرير (نافذة 900 × 500)1441.7 ms0%2%
Menus، تمريرتمرير (نافذة 900 × 500)1441.9 ms0%2%
Controlsانتقالات1440.9 ms0%1–4%
Web and videoإطارات الفيديو، الصفحة135–1421.0 ms0%7–8%

#الذاكرة

في حالة السكون، بعد 3 ثوانٍ من البدء (مشغّلات release، نافذة 480 × 640). Private هي الذاكرة التي تملكها العملية وحدها (USS)؛ أما resident فتضيف صفحات المكتبات المشتركة (GTK، وتعريف GPU)، التي يشاركها كل تطبيق GTK على الجهاز:

التطبيقالمُصيِّر (Renderer)Private (USS)Resident (RSS)
تطبيق Rust (nsh init --template rust)GL (ngl)~49 MB~142 MB
تطبيق RustCairo (GSK_RENDERER=cairo)~28 MB~95 MB
عدّاد TSX (examples/counter)GL~79 MB~166 MB
نافذة GTK 4 بتسمية واحدة، للمقارنةVulkan / Cairo~62 / ~40 MB~132 / ~109 MB

إعادة زيارة صفحة لا تضيف ذاكرة؛ أما أول زيارة لصفحة فتزيد حجم العملية بمقدار ما تخزّنه عمدًا في الذاكرة المؤقتة (صور مفكوكة الترميز، بحد أقصى 128 MB) وبالمكتبات التي تُحمَّل عند أول استخدام (WebKitGTK لعروض الويب).

#حجم التطبيق

تطبيق hello world أنشأه nsh init بكل قالب، وتطبيقان يستخدمهما الناس، كما يبنيهما nsh package --target linux لمعمارية x86_64. المشغّل (runner) هو الملف التنفيذي الوحيد للتطبيق؛ والأرشيف هو .tar.gz الذي يُوزَّع به. تُبنى تطبيقات hello world مع تحسين وقت الربط (link-time optimization) وتُجرَّد من الرموز (CARGO_PROFILE_RELEASE_LTO=fat، CARGO_PROFILE_RELEASE_CODEGEN_UNITS=1، CARGO_PROFILE_RELEASE_STRIP=true):

التطبيقلغة الكتابةالمشغّلالأرشيف
Hello world (--template rust)Rust16.5 MB7.5 MB
Hello world (--template ts)TSX، على QuickJS25.7 MB11.6 MB
Hello world (--template mixed)TSX وحزمة Rust (crate)25.8 MB11.7 MB
sysmon 0.1.3Rust20.9 MB بعد التجريد9.7 MB
Omasend 0.2.0Rust22.3 MB9.8 MB

تحتوي مشغّلات TSX على بيئة QuickJS التشغيلية والوحدات الأصلية والمُصيِّر؛ أما شيفرة التطبيق نفسه فهي حزمته (bundle) الموجودة بجانب المشغّل، وحجمها أقل من 1 KB في تطبيق hello world.

ما الذي يصنع هذه الأرقام:

  • المُصيِّر: مع تعريف NVIDIA يرسم NSH بمُصيِّر GL الخاص بـ GSK، وتكلفة إطاراته جزء يسير من تكلفة مُصيِّر Vulkan هناك (عرض Animations: ~1 ms من الرسم لكل إطار بدلًا من ~9.5 ms). ولا يزال GSK_RENDERER هو من يختار.
  • تحويل Canvas إلى نقاط (rasters): يُحوَّل كل canvas إلى نقاط مرة واحدة في بلاطات بحجم 256 px محفوظة على GPU. وتعيد القيمة المتحركة رسم المنطقة التي تغطيها العمليات التي تقرؤها فقط، فوق البكسلات المحفوظة للجزء الثابت من الرسم؛ وأي canvas خارج مجال الرؤية ينتظر حتى يُمرَّر إلى العرض.
  • مسارات تُحفظ جانبًا مرة واحدة: fillRect وfillText بعد مسار طويل يتركانه في مكانه حتى يُستخدم مجددًا (خط من 400 نقطة ثم 240 شريطًا: 0.63 ms).

#macOS (AppKit)

قيست على MacBook Pro (Apple M3، 24 GB) على شاشته المدمجة ProMotion بمعدل 120 Hz، بنسخ release، والمعرض في نافذة 1200 × 800، وكل قراءة أُخذت تلقائيًا بواسطة examples/gallery/tools/perf.py (nsh test --target macos --fps، سطر واحد كل ثانية؛ المعالج CPU يخص العملية بأكملها، كنسبة مئوية من نواة واحدة، وGPU حصتها من معالج الرسوميات). المراحل هي أزمنة الخيط الرئيسي لكل إطار: tick (الحركات الأصلية لرابط العرض display link) وcanvas (إعادة تشغيل الرسومات).

#العروض المتحركة

العرضFPSFrame p95CPUGPU
Stocks: 22 خطًا مصغّرًا حيًّا، ومخطط خلال اليوم، ودفتر أوامر، وشريط صفقات1202.7–3.7 ms33–36%18–22%
Canvas: مقياس، وساعة، ومصفوفة نقاط119–1200.6–0.7 ms4–7%0%
Animations: ثلاث حلقات أصلية، وسوابض (springs)، وتسلسلات119–1200.3–1.6 ms5–8%0%

في Stocks يبلغ زمن الخيط الرئيسي للإطار نحو 1.6 ms للـ ticks، منها ~0.45 ms لإعادة تشغيل الأجزاء المتحركة من canvases؛ أما بقية كل canvas فيرسمه Core Animation على خيوطه الخاصة.

#كل صفحة

كل صفحة من صفحات المعرض، عند فتحها وأثناء تمرير الاختبار لها، في نافذة 1200 × 800 نفسها. وكما في Linux، فإن FPS هو المعدل أثناء حدوث حركة (إطار واحد لكل فترة وسيطة بين الإطارات المرسومة)؛ وعند 120 للشاشة، يأتي كل إطار من إطارات الحركة أو التمرير بعد تحديث واحد من الإطار السابق. أكثر من تحديث واحد هي نسبة الإطارات التي استغرقت أكثر من تحديث واحد (8.3 ms). الصفحة الساكنة لا ترسم أي إطار وتستهلك 2–5% من CPU. يُشغَّل GIF وWebP في Images عبر Core Animation، والفيديو عبر AVFoundation، بمعدلات إطاراتها الخاصة.

الصفحةمصدر الإطاراتFPSFrame p95أكثر من تحديث واحدCPU
Stocksبيانات حية، حلقات أصلية1203.2 ms0%35%
Stocks، تمريربيانات حية، تمرير1203.5 ms0%36%
AI Chat، تمريرتمرير1202.4 ms1%5%
Photos، تمريرتمرير1201.4 ms0%10%
Lists، تمريرتمرير1201.6 ms0%8%
Scrolling، تمريرتمرير1202.7 ms0%6%
Navigation، تمريرتمرير1200.2 ms0%4%
Form، تمريرتمرير1200.6 ms0%5%
Resizable، تمريرتمرير1200.3 ms0%4%
Dock، تمريرتمرير1200.3 ms1%5%
Gesturesسوابض (springs)، حلقة نابضة1200.4 ms0%4%
Physics، تمريرتمرير1200.3 ms0%4%
Animationsحلقات أصلية1200.3 ms0%5%
Canvas، تمريرتمرير، حلقات أصلية1201.2 ms0%7%
Styles، تمريرتمرير، تحويل متمايل1201.0 ms0%6%
Tailwindأدوات animate-* المساعدة (utilities)1200.5 ms0%4%
Text، تمريرتمرير1200.3 ms0%5%
Text View، تمريرتمرير1200.7 ms0%5%
Images، تمريرتمرير1200.4 ms0%5%
Components، تمريرتمرير1200.3 ms0%5%
Overlays، تمريرتمرير1200.3 ms0%4%
Menus، تمريرتمرير1200.3 ms0%5%
Controlsانتقالات1200.3 ms0%4%
Web and video، تمريرتمرير1200.2 ms0%6%
SystemrequestAnimationFrame، مؤقّتات1200.2 ms0%3%
Standard APIs، تمريرتمرير1200.3 ms0%5%
Storage، تمريرتمرير1200.3 ms0%5%

#الذاكرة

في حالة السكون، بعد 3 ثوانٍ من البدء (مشغّلات release). Footprint هي الذاكرة التي يحاسب بها macOS العملية (ما يعرضه Activity Monitor)؛ أما resident فتضيف صفحات المكتبات المشتركة للنظام:

التطبيقالنافذةFootprintResident (RSS)
تطبيق Rust (nsh init --template rust)1200 × 800~19 MB~86 MB
عدّاد TSX (examples/counter)1200 × 800~20 MB~89 MB
نافذة AppKit بتسمية واحدة، للمقارنة480 × 640~17 MB~80 MB

خلال جولة المعرض تشغل العملية ما بين 84 و230 MB حتى صفحة Canvas، ثم ~350–360 MB ابتداءً من صفحة Text View، وذلك مع ما تخزّنه عمدًا في الذاكرة المؤقتة (صور مفكوكة الترميز، بحد أقصى 128 MB؛ ومستندات صفحة Text View) ومع الأطر (frameworks) التي تُحمَّل عند أول استخدام (WebKit لعروض الويب)؛ أما نقاط raster الخاصة بصفحة Canvas، التي تصل إلى ~310 MB عند ظهور الـ canvases الثلاثة على الشاشة، فتزول عند إغلاق الصفحة.

#حجم التطبيق

تطبيقات hello world التي ينشئها nsh init بكل قالب، كما يبنيها nsh package --target macos لمعالجات Apple silicon (arm64)، مع تحسين وقت الربط (link-time optimization) وإزالة الرموز كما في Linux، إضافةً إلى التطبيقين المذكورين أعلاه كما يُشحنان لمعالجات Apple silicon. الملف التنفيذي هو المشغّل (runner) داخل .app؛ والملف المضغوط هو .app بعد ضغطه (ditto -c -k):

التطبيقلغة الكتابةالملف التنفيذيمضغوط .app
Hello world (--template rust)Rust12.4 MB6.0 MB
Hello world (--template ts)TSX على QuickJS19.8 MB9.5 MB
Hello world (--template mixed)TSX وحزمة Rust (crate)19.8 MB9.5 MB
sysmon 0.1.3Rust21.6 MB8.4 MB (.tar.gz الخاص بإصداره)
Omasend 0.2.0Rust18.4 MB9.7 MB (.tar.gz الخاص بإصداره)

ما الذي يحقق هذه الأرقام:

  • إطارات للتغييرات فقط: يعمل display link أثناء تشغيل حركة أصلية (native animation) ويتوقف معها؛ وتتوقف الحركة مع صفحتها (حذف العرض الخاص بها ينهي إطاراتها المفتاحية، وتتوقف الحلقة في cleanup الخاص بمكوّنها).
  • رسم الـ canvas حيث يكلّف أقل: الـ canvas الذي يُرسم كثيرًا (حركة، بيانات حية) يُرسم على خيوط Core Animation (drawsAsynchronously)، مما يُبقي الخيط الرئيسي حرًا؛ أما الذي يُعاد رسمه بين الحين والآخر فيُرسم فورًا، دون ذاكرة الرسوميات التي يحتفظ بها الرسم غير المتزامن. وتعيد القيمة المتحركة رسم المنطقة التي تغطيها العمليات التي تقرؤها فقط.
  • الاحتفاظ بأجزاء الـ canvas الثابتة: متى بقي الرسم دون تغيير، يُحفظ الجزء الطويل الذي يسبق أول عملية متحركة كطبقة (layer)؛ ويرسم كل إطار هذه الطبقة ويعيد تشغيل الجزء المتحرك المتبقي فقط، فورًا على الخيط الرئيسي (مقياس صفحة Canvas وساعتها ومصفوفة نقاطها: بلا عمل على GPU وبنصف الذاكرة).
  • رسم المحتوى عند تغيّره: تُرسم النصوص والـ canvas في طبقات خاصة بها، وتُرسم من جديد عند تغيّر محتواها أو حجمها، لا عند تحريكها أو تمريرها.

#Windows (Win32, Direct2D)

القياسات على حاسوب مكتبي بنظام Windows 11 (Intel Core i7-13700KF، ذاكرة 32 GB، NVIDIA GeForce RTX 3060 Ti) بشاشة 4K وتردد 144 Hz بتكبير 150%، وبنسخ release، ومعرض الأمثلة (gallery) في نافذة 1200 × 800 (1800 × 1200 بكسل)، وكل قراءة تُؤخذ تلقائيًا بواسطة examples/gallery/tools/perf.py (nsh test --target windows --fps، سطر واحد كل ثانية؛ استهلاك CPU للعملية كاملة، بنسبة مئوية من نواة واحدة). المراحل هي ما يستغرقه الخيط الرئيسي لكل إطار: paint (رسم Direct2D للنافذة) وضمنه canvas (تسجيل الرسومات وإعادة تشغيلها).

#العروض المتحركة

العرضFPSزمن الإطار p95الرسم / canvas لكل إطارCPU
Stocks: 22 مخططًا مصغرًا حيًا، ومخطط خلال اليوم، ودفتر أوامر، وشريط صفقات1443.7–4.3 ms1.4 / 0.13 ms36–43%
Canvas: مقياس، وساعة، ومصفوفة نقاط1441.0–2.0 ms0.8–1.4 / 0.05 ms21–35%
Animations: ثلاث حلقات أصلية، وsprings، وتسلسلات1441.0–3.6 ms0.9–1.9 ms20–41%

ينفّذ Stocks من 16 إلى 17 عملية commit في الثانية، تستغرق كل منها حتى 2.1 ms في JS و1.7 ms في النواة على خيط المحرّك (p95).

#كل صفحة

كل صفحة من صفحات المعرض، عند فتحها وأثناء تمرير الاختبار لها، في نافذة 1200 × 800 نفسها. كما في Linux و macOS، FPS هو المعدّل أثناء وجود حركة (إطار واحد لكل فجوة وسيطة بين الإطارات المرسومة)؛ وعند 144 للشاشة، يأتي كل إطار من حركة أو تمرير بعد تحديث واحد من سابقه. تجاوز تحديثًا واحدًا هي نسبة الإطارات التي استغرقت أكثر من تحديث واحد (6.9 ms). الصفحة الساكنة لا ترسم أي إطار وتستهلك 0–2% من CPU. صور GIF وWebP في صفحة Images تعمل بمعدلات إطاراتها الخاصة (نحو 40 FPS هنا). تُقاس صفحات Physics وOverlays وMenus وStorage في نافذة 900 × 500، حيث تتسع للتمرير.

الصفحةمصدر الإطاراتFPSزمن الإطار p95تجاوز تحديث واحدCPU
Stocksبيانات حية، حلقات أصلية1443.9 ms0%36%
Stocks, scrollingبيانات حية، تمرير1444.3 ms0%43%
Photos, scrollingتمرير1432.1 ms0%9%
Lists, scrollingتمرير1442.0 ms1%19%
Scrolling, scrollingتمرير1432.1 ms0%7%
Navigation, scrollingتمرير1440.8 ms0%9%
Form, scrollingتمرير1440.8 ms0%12%
Resizable, scrollingتمرير1430.4 ms0%4%
Dock, scrollingتمرير1440.5 ms1%5%
Gesturessprings، حلقة نابضة1441.8 ms0%36%
Physics, scrollingتمرير (نافذة 900 × 500)1440.8 ms0%4%
Animationsحلقات أصلية1441.0 ms0%28%
Canvas, scrollingتمرير، حلقات أصلية1442.0 ms0%35%
Styles, scrollingتمرير، تحويل متمايل1442.1 ms0%39%
Tailwindأدوات animate-* المساعدة1440.6 ms0%19%
Text, scrollingتمرير1441.6 ms0%8%
Text View, scrollingتمرير1441.1 ms0%10%
Images, scrollingتمرير، إطارات GIF وWebP1434.8 ms2%23%
Components, scrollingتمرير1441.0 ms1%11%
Overlays, scrollingتمرير (نافذة 900 × 500)1440.6 ms0%1%
Menus, scrollingتمرير (نافذة 900 × 500)1440.6 ms0%2%
Controlsانتقالات117–1441.5 ms0%22%
Web and video, scrollingتمرير1441.6 ms0%15%
SystemrequestAnimationFrame، مؤقتات144< 0.1 ms0%1%
Storage, scrollingتمرير (نافذة 900 × 500)1440.5 ms0%1%

#الذاكرة

في حالة السكون، بعد 3 ثوانٍ من البدء (مشغّلات release، نافذة 1200 × 800). Private working set هي الذاكرة التي تستخدمها العملية وحدها (عمود Memory في Task Manager)؛ وprivate bytes ما حجزته منها؛ وworking set تضيف صفحات مكتبات النظام التي تتشاركها مع عمليات أخرى (Direct3D وDirect2D وDirectWrite وبرنامج تشغيل GPU):

التطبيقPrivate working setPrivate bytesWorking set
تطبيق Rust (nsh init --template rust)~14 MB~60 MB~53–71 MB
عدّاد TSX (examples/counter)~15 MB~61 MB~56–71 MB

خلال جولة المعرض يبلغ working set نحو 108–115 MB في Stocks، ونحو 230 MB من صفحة Canvas، ونحو 320–340 MB من صفحة Text View، ونحو 390–405 MB بعد أن تفتح Web and video عنصر WebView2 (الذي تعمل صفحاته في عمليات WebView2 الخاصة به)، مع ما تخزّنه مؤقتًا عن قصد (الصور المفكوكة، بحد أقصى 128 MB؛ ومستندات صفحة Text View).

#حجم التطبيق

تطبيقات hello world التي ينشئها nsh init بكل قالب، كما يبنيها nsh package --target windows لمعمارية x86_64 (مشغّلات Rust مع تحسين وقت الربط وإزالة الرموز، كما في Linux). الملف التنفيذي هو <Name>.exe التطبيق؛ والملف المضغوط هو .zip المكتوب بجانب مجلده:

التطبيقلغة الكتابةالملف التنفيذيالملف المضغوط
Hello world (--template rust)Rust15.0 MB6.7 MB
Hello world (--template ts)TSX على QuickJS28.6 MB12.4 MB
Hello world (--template mixed)TSX وحزمة Rust (crate)26.3 MB11.5 MB

ما الذي يحقق هذه الأرقام:

  • إطارات للتغييرات فقط، تُرسم حيث تغيّرت فقط: يعمل المؤقّت (ticker) المتزامن مع المُركِّب (compositor) أثناء تشغيل حركة أصلية أو انتقال أو دالة رد نداء للإطار. يرسم الإطار مناطق العروض التي تغيّرت (حيث كانت وحيث صارت)، فوق البكسلات التي تحتفظ بها النافذة، ولا يقدّم للمُركِّب إلا هذه المناطق (Stocks: نحو 34 عرضًا في الإطار).
  • يسجّل الـ canvas جزأه المتحرك: يُسجَّل الرسم كقوائم أوامر Direct2D، متجهيًا وحادًا عند أي مقياس. وعندما تتغيّر قيمة متحركة، لا يُعاد تسجيل إلا العمليات ابتداءً من أول عملية تقرأ قيمة متحركة؛ أما ما يسبقها فيُحتفظ به (Stocks: نحو 26 ms من التسجيل في الثانية لـ 22 مخططًا مصغرًا نابضًا والمخطط الرئيسي).
  • يُرسم ما يظهر فقط: تُستثنى من الإطار العروض الأبناء لعرض تمرير أو عرض قص (clipping) التي تقع خارج مجال الرؤية، ولا ترسم العروض التي لا محتوى خاصًا بها أكثر من خلفيتها وحدودها.

#iOS (UIKit)

القياسات في محاكي iOS (iPhone 18 Pro Max، على MacBook Pro المذكور أعلاه)، بنسخ release، وبالجولة نفسها (perf.py --target ios: nsh test --target ios --fps، لمسات إصبع كما يتلقاها UIKit). يعرض المحاكي بتردد 60 Hz؛ وعلى iPhone بشاشة ProMotion تعمل display links في NSH بتردد 120 Hz للشاشة (التطبيقات التي يبنيها nsh package ومضيف التطوير تطلب ذلك عبر CADisableMinimumFrameDurationOnPhone). المراحل هي tick (الحركات الأصلية) وdrain (تطبيق دفعات المحرّك) وscroll (ما يتبع عرض التمرير: القوائم، والخلايا اللاصقة، والقيم المرتبطة).

الصفحةمصدر الإطاراتFPSزمن الإطار p95CPU
Home, scrollingتمرير600.1 ms6%
Stocksبيانات حية، حلقات أصلية600.3 ms22%
Stocks, scrollingبيانات حية، تمرير600.3 ms25%
Photos, scrollingتمرير601.2 ms6%
Lists, scrollingتمرير601.1 ms8%
Scrolling, scrollingتمرير600.1 ms7%
Navigation, scrollingتمرير600.2 ms7%
Form, scrollingتمرير600.3 ms7%
Gesturessprings، حلقة نابضة600.3 ms3%
Animationsحلقات أصلية600.7 ms6%
Canvasحلقات أصلية600.4 ms16%
Stylesتحويل متمايل600.4 ms4%
Tailwind, scrollingتمرير600.2 ms7%
Text, scrollingتمرير600.1 ms7%
Text View, scrollingتمرير600.1 ms6%
Images, scrollingتمرير600.1 ms5%
Components, scrollingتمرير600.2 ms6%
Overlays, scrollingتمرير600.1 ms6%
Menus, scrollingتمرير600.2 ms7%
Controls, scrollingتمرير، انتقالات600.2 ms5%
Web and video, scrollingتمرير600.1 ms8%
SystemrequestAnimationFrame، مؤقتات600.3 ms4%
Standard APIs, scrollingتمرير600.1 ms7%
Storage, scrollingتمرير600.1 ms8%

FPS هو المعدّل أثناء وجود حركة، كما سبق: عند 60 للمحاكي، يأتي كل إطار بعد تحديث واحد من سابقه. كل صفحة لا يتحرك فيها شيء لا ترسم أي إطار وتستهلك 1–2% من CPU في حالة السكون. تشغل العملية 40 MB في الصفحة الرئيسية للمعرض ونحو 180 MB بعد الجولة كاملة (صور مخزّنة مؤقتًا عن قصد، ومستندات صفحة Text View).

على iPhone 17 Pro (ProMotion، 120 Hz)، مع مضيف التطوير وعرض توضيحي واحد على الشاشة، ترسم الصفحات المتحركة في كل تحديث:

الصفحةمصدر الإطاراتFPSزمن الإطار p95تجاوز تحديث واحدCPUالذاكرة
Stocksبيانات حية، حلقات أصلية1200.2–0.3 ms0%46–70%41–43 MB
Canvasحلقات أصلية1200.1 ms0%25–36%37–38 MB
Animationsحلقات أصلية1200.2 ms0%3–11%37 MB

ينفّذ Stocks 20 عملية commit في الثانية (نبضة كل 50 ms)، تستغرق كل منها 1.5 ms في JS و1.4 ms في النواة على خيط المحرّك (p95 هو 2.2 و2.0 ms)، ويكون هذا الخيط مشغولًا بنسبة 4–6% من الوقت.

#قياس تطبيق

لقياس تطبيق بالطريقة نفسها، شغّل اختباراته أو خطواته باستخدام --fps و-v على --target linux أو macos أو windows أو ios:

cargo build --release -p nsh-cli
python3 examples/gallery/tools/perf.py --target macos --only Stocks,Canvas   # the gallery, page by page
echo 'await app.wait(5000)' | nsh -v test App.tsx --target linux --fps        # any app