FPS في التطبيقات المحمولة: الجوهر والحساب والتحسين

المؤلف: IT Sectr نُشر: 2026-04-01 وقت القراءة: 11 دق

FPS (Frames Per Second) هو مقياس يوضح عدد الإطارات الفردية التي يعرضها نظام الرسومات في الثانية الواحدة. في تطوير التطبيقات المحمولة، يعد FPS مؤشرًا قياسيًا لأداء واجهة المستخدم: كلما زاد FPS، كانت الرسوم المتحركة أكثر سلاسة والواجهة أكثر استجابة. وفقًا Google Android Performance, 2025، فإن القيمة المستهدفة FPS للتطبيقات المحمولة هي 60 إطارًا في الثانية — وهي العتبة التي تدرك عندها العين البشرية الحركة بأنها مستمرة وسلسة.

الملخص

  • FPS — عدد الإطارات في الثانية، المقياس الرئيسي لسلاسة واجهة المستخدم.
  • القيمة المستهدفة — 60 FPS، وقت الإطار — 16.6 مللي ثانية.
  • للشاشات عالية معدل التحديث، يلزم 120 FPS (8.3 مللي ثانية لكل إطار).
  • انخفاض FPS عن 30 يمكن ملاحظته بالعين المجردة على شكل توقف وتأخير.
  • مراقبة FPS في الإنتاج تساعد في اكتشاف تراجعات الأداء.

ما هو FPS

FPS (Frames Per Second) هو وحدة قياس معدل الإطارات المستخدمة في رسومات الحاسوب والفيديو وواجهات الأجهزة المحمولة. كل إطار هو صورة ثابتة تُعرض على الشاشة لفترة قصيرة من الزمن. مع التغيير السريع للإطارات، يدركها الدماغ على أنها حركة مستمرة — يُسمى هذا التأثير استمرار الرؤية. بالنسبة للتطبيقات المحمولة، يعد FPS مقياسًا حاسمًا لأن أي إطار مفقود يحول الرسوم المتحركة السلسة إلى توقف ملحوظ. يجب أن يعرض التطبيق كل إطار بدقة ضمن الميزانية الزمنية: 16.6 مللي ثانية لـ 60 FPS، و11.1 مللي ثانية لـ 90 FPS، و8.3 مللي ثانية لـ 120 FPS.

يُقاس FPS ليس فقط لواجهة المستخدم ولكن أيضًا للألعاب والفيديو والكاميرا. في الألعاب، يعتمد FPS على تعقيد المشهد وجودة النسيج وقوة وحدة معالجة الرسومات. في الفيديو، يكون FPS ثابتًا (24، 30، 60 إطارًا/ثانية) ويتم تحديده حسب المحتوى. في التطبيقات المحمولة، يعتمد FPS على كفاءة كود واجهة المستخدم: تعقيد التخطيط وعدد العناصر وتكرار إعادة الرسم وعمل جامع القمامة (GC). وفقًا لـ Apple WWDC 2022، يمكن أن ينخفض متوسط FPS في التطبيق بنسبة 10–15% بسبب التحديث غير الفعال للمجموعات (reloadData بدلاً من insert/delete/dequeueReusableCell). يعد قياس FPS في الوقت الفعلي ممارسة قياسية لمهندسي ضمان الجودة والمطورين الذين يعملون على تحسين الأداء.

كيف يتم حساب FPS

يعتمد حساب FPS في التطبيق المحمول على قياس الوقت بين الإطارات المتتالية. أبسط صيغة: FPS = 1000 / deltaTimeMs، حيث deltaTimeMs هو الفاصل الزمني بين اكتمال الإطار السابق واكتمال الإطار الحالي. إذا تم عرض الإطار الحالي في 20 مللي ثانية، فإن FPS = 1000 / 20 = 50. ومع ذلك، في الممارسة العملية، نادرًا ما يكون FPS مستقرًا حتى خلال ثانية واحدة: يتضمن الملف الشخصي النموذجي إطارات من 12 إلى 16 مللي ثانية تتخللها إطارات مفقودة (jank) أو بطيئة (40–60 مللي ثانية). لذلك، يُقاس FPS كمتوسط متحرك على مدى 1–5 ثوانٍ أو كنسب مئوية لتوزيع وقت الإطارات.

في Android، يُحسب FPS عبر Choreographer، الذي يتلقى رد اتصال من VSync (نبضة مزامنة الشاشة). كل رد اتصال يتوافق مع إطار واحد. إذا لم يصل رد الاتصال — يتم تخطي الإطار. يتيح Choreographer قياس العدد الدقيق للإطارات في الثانية وعدد الإطارات المفقودة. في iOS، يعمل CADisplayLink بشكل مشابه — يتم استدعاؤه في كل مرة تكون فيها الشاشة جاهزة لعرض إطار جديد. تحتوي الخاصية timestamp على الوقت الدقيق للإطار الأخير، و targetTimestamp — الوقت المتوقع للإطار التالي. الفرق بينهما هو الميزانية الزمنية للإطار الحالي.

مراقبة FPS عبر CADisplayLink

يوضح كود Swift مراقبة بسيطة لـ FPS عبر CADisplayLink. يزداد العداد frameCount مع كل استدعاء، ويتم حساب FPS الفعلي مرة كل ثانية.

swift
class FpsCounter {

    private var displayLink: CADisplayLink?
    private var frameCount = 0
    private var lastTime = TimeInterval(0)

    func start() {
        displayLink = CADisplayLink(
            target: self,
            selector: #selector(countFrame)
        )
        displayLink?.add(to: .current,
            forMode: .common)
    }

    @objc
    private func countFrame() {
        frameCount += 1
        let now = Date().timeIntervalSince1970

        if now - lastTime >= 1.0 {
            print("FPS: \(frameCount)")
            frameCount = 0
            lastTime = now
        }
    }
}

لماذا 60 FPS هو المعيار

معيار 60 FPS (أو 60 هرتز) ترسخ في الصناعة لعدة أسباب. الأول فسيولوجي: العين البشرية لا تميز الإطارات الفردية عند الترددات الأعلى من 50–60 هرتز، وتدركها كحركة سلسة. يُسمى هذا الحد Critical Flicker Fusion (CFF). الثاني تاريخي: أنابيب الأشعة المهبطية المبكرة (CRT) كانت تعمل بتردد 60 هرتز في الولايات المتحدة (NTSC) و 50 هرتز في أوروبا (PAL). ورثت شاشات LCD الحديثة هذا التردد. الثالث هندسي: لرسوم واجهة المستخدم المتحركة، يوفر 60 FPS زمن استجابة للمس دون الملي ثانية، وهو أمر بالغ الأهمية لإدخال النص والتمرير والسحب.

لمطوري التطبيقات المحمولة، 60 FPS ليس مجرد توصية بل ميزانية صارمة تبلغ 16.6 مللي ثانية لكل إطار. تُقسم هذه الميزانية بين جميع مراحل العرض: الإدخال (1–2 مللي ثانية)، والرسوم المتحركة (2–3 مللي ثانية)، والتخطيط (3–5 مللي ثانية)، والرسم (3–5 مللي ثانية)، والتبديل (1–2 مللي ثانية). إذا تجاوزت أي مرحلة ميزانيتها الفرعية، فقد لا يتناسب الإطار مع 16.6 مللي ثانية. توصي Google Android Performance بالبقاء ضمن 12–14 مللي ثانية لتحضير الإطار، مع ترك 2–4 مللي ثانية كمخزون احتياطي لمقاطعات النظام (GC، الخيوط الخلفية). وفقًا لـ Firebase Performance، التطبيقات ذات متوسط FPS أقل من 52 و P99 FPS أقل من 30 تتلقى شكاوى أداء أكثر بنسبة 35% في مراجعات Google Play.

FPS ووقت الإطار: العلاقة

FPS و وقت الإطار هما وجهان لنفس المقياس، ومن المهم عدم الخلط بينهما. FPS هو السرعة، وقت الإطار هو زمن الاستجابة. عند 60 FPS، يستغرق كل إطار 16.6 مللي ثانية. عند 30 FPS — 33.3 مللي ثانية. لكن FPS هو مقياس غير خطي: انخفاض من 60 إلى 30 FPS يعني تضاعف وقت الإطار، بينما انخفاض من 30 إلى 20 يعني زيادة بمقدار 1.5 مرة. لذلك، تُظهر أدوات التنميط وقت الإطار بدلاً من FPS — وهذا يسمح برؤية الإطارات المشكلة بدلاً من التردد المتوسط. على سبيل المثال، متوسط 55 FPS قد يخفي حقيقة أن 5% من الإطارات لها وقت إطار يتراوح بين 50–100 مللي ثانية — هذه الإطارات تسبب Jank ولكنها لا تؤثر بشكل كبير على متوسط FPS.

عند تحليل الأداء، يُوصى بالنظر ليس إلى متوسط FPS بل إلى الرسم البياني لوقت الإطار. في Android Studio Profiler و iOS Instruments، يُعرض وقت الإطار كمقياس حيث المنطقة الخضراء حتى 16.6 مللي ثانية (60 FPS)، والأصفر 16.6–33.3 مللي ثانية (30–60 FPS)، والأحمر أكثر من 33.3 مللي ثانية (أقل من 30 FPS). كل عمود أحمر هو تأخير ملحوظ للمستخدم. قاعدة عملية: P95 Frame Time (95% من الإطارات تتناسب مع X مللي ثانية) هو مقياس أكثر موثوقية من متوسط FPS. إذا تجاوز P95 Frame Time 32 مللي ثانية (30 FPS)، يُنظر إلى التطبيق على أنه بطيء حتى مع متوسط FPS = 50.

تحويل وقت الإطار إلى FPS

دالة في Kotlin لتحويل مصفوفة أوقات الإطارات إلى FPS مع النسب المئوية. تُرجع ليس فقط متوسط FPS ولكن أيضًا P50 و P90 و P99 للتحليل التفصيلي.

kotlin
data class FpsReport(
    val average: Float,
    val p50: Float,
    val p90: Float,
    val p99: Float
)

fun List<Long>.toFpsReport(): FpsReport {
    val fpsValues = this.map { ms ->
        if (ms > 0) 1000f / ms else 0f
    }.sorted()

    return FpsReport(
        average = fpsValues.average().toFloat(),
        p50 = fpsValues[fpsValues.size / 2],
        p90 = fpsValues[(fpsValues.size * 90 / 100)],
        p99 = fpsValues[(fpsValues.size * 99 / 100)]
    )
}

ارتفاع FPS والشاشات الجديدة

الأجهزة المحمولة الحديثة ذات الشاشات 90 و 120 و 144 هرتز تفرض متطلبات جديدة على FPS. إذا كان التطبيق ينتج 60 FPS على شاشة 120 هرتز، يرى المستخدم توقفًا دقيقًا لأن كل دورة تحديث ثانية للشاشة تتلقى نفس الإطار. للحفاظ على 120 FPS، تتقلص الميزانية لكل إطار من 16.6 إلى 8.3 مللي ثانية — مما يتطلب كود عرض أكثر كفاءة بمقدار الضعف. وفقًا لمطوري Android (Google I/O 2023)، لتحقيق 120 FPS مستقرة، من الضروري: تجنب التخصيصات في دورة الرسم، وتقليل عدد العناصر في التسلسل الهرمي (أقل من 80)، والاستغناء عن drawables الثقيلة لصالح VectorDrawable، واستخدام surfaceView للرسومات المعقدة.

الوضع مشابه في iOS: iPhone Pro مع ProMotion (120 هرتز) يتطلب ضعف عدد الإطارات، لكن الوقت لكل إطار ينخفض إلى النصف. تشير Apple إلى أنه ليست كل الرسوم المتحركة يجب أن تعمل على 120 FPS — Core Animation يخفض تلقائيًا معدل الإطارات للعناصر الثابتة أو المتغيرة ببطء. ومع ذلك، يجب أن ينتج التمرير ورسوم الإيماءات والانتقالات 120 FPS للحصول على إحساس ‛حريري“. المشاكل الرئيسية عند الانتقال من 60 إلى 120 FPS: زيادة استهلاك الطاقة (بنسبة 25–40% لوحدة معالجة الرسومات)، وتسخين الجهاز، والاختناق الحراري — عندما ينخفض معدل الإطارات بسبب ارتفاع الحرارة. يُوصى بتنفيذ آلية احتياطية: إذا تجاوز وقت الإطار 8.3 مللي ثانية باستمرار، قم بخفض معدل الإطارات المستهدف برمجيًا إلى 60 FPS بدلاً من انتظار الاختناق النظامي.

مبدل 60/120 FPS

كود Java لنظام Android يحدد ما إذا كان الجهاز يمكنه دعم 120 FPS ويبدل وضع العرض. يُستخدم Display.getMode لتحديد معدلات التحديث المدعومة.

java
class FpsModeSwitcher {

    static boolean canDo120Fps(Activity activity) {
        Display display = activity.getWindowManager()
            .getDefaultDisplay();
        for (Display.Mode mode : display.getSupportedModes()) {
            if (mode.getRefreshRate() >= 120f) {
                return true;
            }
        }
        return false;
    }
}

تحسين FPS في التطبيقات

يتطلب تحسين FPS نهجًا منهجيًا، بدءًا من التنميط وانتهاءً بإعادة هيكلة المناطق المشكلة. الخطوة الأولى هي قياس FPS الحالي باستخدام أداة التنميط. الخطوة الثانية هي العثور على الإطارات التي تتجاوز الميزانية. في Android، يمكن القيام بذلك عبر GPU Profiling أو Perfetto. في iOS — Instruments مع قالب Core Animation. الخطوة الثالثة هي إزالة الأسباب: تقليل overdraw، وتقليل عمق تداخل العناصر، واستبدال مرحلة التخطيط بـ ConstraintLayout، وإضافة ViewHolder Recycling، ونقل العمليات الحسابية الثقيلة إلى خيط خلفي.

تشمل التحسينات الخاصة بـ FPS: Frame Pacing — آلية توزع الوقت بالتساوي بين الإطارات لتجنب ‛اندفاعات“ الإطارات السريعة والبطيئة. في Android، Choreographer.FrameCallback بفاصل زمني ثابت يسمح بتنفيذ Frame Pacing. في iOS، CADisplayLink.preferredFrameRateRange يفعل الشيء نفسه. الطريقة الثانية — Triple Buffering: يستخدم النظام ثلاثة مخازن مؤقتة بدلاً من اثنين، مما يسمح لوحدة معالجة الرسومات ببدء عرض الإطار التالي دون انتظار تحرير الإطار السابق. يقوم Android تلقائيًا بتشغيل Triple Buffering عند الحاجة، ولكن في iOS يمكن للمطور طلبه صراحةً عبر CAMetalLayer. الثالث — Texture Caching: تخزين الصور النقطية مؤقتًا في ذاكرة وحدة معالجة الرسومات لتجنب إعادة تحميلها في كل إطار.

Frame Pacing عبر Choreographer

مثال في Kotlin يوضح تنفيذ Frame Pacing بفاصل زمني ثابت 16.6 مللي ثانية. جميع ردود الاتصال تصل بفاصل زمني منتظم، حتى لو تأخر النظام.

kotlin
class PacedFrameRenderer {

    private val targetDelta = 16_666_666L // 16.6 ms (60 FPS)
    private var lastFrameTime = 0L

    private val frameCallback =
        Choreographer.FrameCallback { frameTimeNanos ->
            val delta = frameTimeNanos - lastFrameTime
            if (delta >= targetDelta) {
                onFrame(delta)
                lastFrameTime = frameTimeNanos
            }
            Choreographer.getInstance()
                .postFrameCallback(this)
        }

    private fun onFrame(delta: Long) {
        // عرض الإطار
    }
}

الأسئلة الشائعة

ما هو معدل FPS المريح للمستخدم؟

60 FPS هو مستوى مريح للتطبيقات المحمولة. الفرق بين 60 و 120 FPS ملحوظ فقط على الشاشات عالية معدل التحديث أثناء الرسوم المتحركة السريعة (التمرير، السحب). أقل من 30 FPS — غير مريح.

كيف يرتبط FPS بوقت الإطار؟

FPS = 1000 / FrameTime (ms). إذا كان وقت الإطار = 16.6 مللي ثانية، FPS = 60. إذا كان وقت الإطار = 33.3 مللي ثانية، FPS = 30. يُوصى بمراقبة وقت الإطار بدلاً من FPS، لأنه يظهر الإطارات المشكلة.

لماذا ينخفض FPS أثناء التمرير؟

أثناء التمرير، يستدعي النظام Layout و Draw لكل عنصر جديد في القائمة. إذا كانت العناصر معقدة، أو لم يتم تخزين التخطيط مؤقتًا، أو تم استخدام drawables ثقيلة — يزداد وقت الإطار وينخفض FPS. الحل هو إعادة تدوير ViewHolder والتسلسل الهرمي المسطح.

كيفية قياس FPS في iOS؟

استخدم Instruments مع قالب Core Animation (يظهر FPS في الوقت الفعلي). للقياس البرمجي — CADisplayLink مع عد الإطارات في الثانية. للإنتاج — MetricKit مع مقياس MXAnimatoryMetric.

ما هو Triple Buffering وكيف يؤثر على FPS؟

Triple Buffering يستخدم ثلاثة مخازن مؤقتة بدلاً من اثنين، مما يسمح لوحدة معالجة الرسومات ببدء عرض الإطار التالي قبل اكتمال VSync الحالي. هذا يخفف الأحمال الذروية ويحسن استقرار FPS، لكنه يضيف إطارًا واحدًا من زمن الاستجابة.

الخلاصة

  • FPS هو المقياس الرئيسي لسلاسة الواجهة، القيمة المستهدفة هي 60 إطارًا في الثانية.
  • وقت الإطار هو مؤشر أكثر دقة من FPS، خاصة النسب المئوية P95 و P99.
  • للشاشات 120 هرتز، يلزم 120 FPS بميزانية 8.3 مللي ثانية لكل إطار.
  • الأسباب الرئيسية لانخفاض FPS هي overdraw، والتداخل العميق للعناصر، والتخصيصات في دورة الرسم.
  • Frame Pacing و Triple Buffering يساعدان في تخفيف عدم انتظام وقت الإطارات.
  • تنميط FPS — عبر GPU Profiling (Android)، Instruments Core Animation (iOS)، Firebase Performance.
  • مراقبة P95 Frame Time في الإنتاج أمر بالغ الأهمية لاكتشاف التراجعات قبل شكاوى المستخدمين الجماعية.

سنقوم بتطوير تطبيق جوال جاهز

تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.

مناقشة المشروع

اقرأ أيضًا