تساعد ميزانيات الأداء في الحفاظ على سرعة تطبيقات الويب بتحديد حدود واضحة لزمن التحميل، حجم JavaScript، وCore Web Vitals، إضافة إلى تدقيقات سريعة وقواعد الإصلاح أولًا.

ميزانية الأداء هي مجموعة حدود تتفقون عليها قبل البناء. يمكن أن تكون حدًا زمنيًا (كم تبدو الصفحة سريعة)، حدًا حجميًا (كم من الشيفرة تُشحن)، أو حدًا بسيطًا (الطلبات، الصور، السكربتات الطرفية). إذا تجاوزتم الحد، يُعامل كمتطلب مكسور، وليس كـ "شيء جميل لإصلاحه لاحقًا".
السرعة عادةً تتدهور لأن الشحن تراكمِي. كل ويدجيت جديد يُضيف JavaScript وCSS وخطوط وصور واستدعاءات API والمزيد من العمل للمتصفح. حتى التغييرات الصغيرة تتراكم حتى يصبح التطبيق ثقيلاً، خصوصًا على هواتف متوسطة المواصفات وشبكات أبطأ حيث يوجد معظم المستخدمين الحقيقيين.
الآراء لا تحميكم هنا. شخص يقول "إنه سريع على اللابتوب لدي"، وآخر يقول "بطيء"، والفريق يناقش. الميزانية تنهي النقاش بتحويل الأداء إلى قيد منتج يمكن قياسه وفرضه.
هذا يتوافق مع تفكير Addy Osmani: عامل الأداء كقيود تصميم وقواعد أمان. لا تحاول البقاء آمنًا أو تأمل أن يظهر التخطيط جيدًا. تحدد معايير، تراقبها باستمرار، وتمنع التغييرات التي تكسرها.
الميزانيات تحل عدة مشاكل عملية مرة واحدة. تجعل المقايضات صريحة (إضافة ميزة تعني دفع ثمنها في مكان آخر)، تلتقط الانتكاسات مبكرًا (حين تكون الإصلاحات أرخص)، وتعطي الجميع نفس تعريف "السريع بما يكفي". كما تقلل من الذعر القبل الإطلاق.
إليك السيناريو الذي تُبنى الميزانيات من أجله: تضيف مكتبة رسوم بيانية غنية لعرض لوحة واحدة. تُشحن للجميع، تكبر الحزمة الرئيسية، وتؤخر ظهور الشاشة الأولى ذات المغزى. بدون ميزانية، يمر هذا لأن الميزة "تعمل". مع ميزانية، على الفريق أن يختار: تحميل الرسوم كسولًا، استبدال المكتبة، أو تبسيط العرض.
هذا يزداد أهمية عندما تكون الفرق قادرة على توليد وتكرار التطبيقات بسرعة، بما في ذلك عبر سير عمل التوليد بالمحادثة مثل Koder.ai. السرعة رائعة، لكنها تجعل من السهل أيضًا شحن تبعيات إضافية وزخارف واجهة بدون ملاحظة. الميزانيات تمنع التكرار السريع من التحول إلى منتجات بطيئة.
يفشل عمل الأداء حين تقيس كل شيء ولا تملك شيئًا. اختر مسار صفحة واحد يهم المستخدمين الحقيقيين، واعتبره مرساة لميزانياتك.
نقطة بداية جيدة هي رحلة رئيسية حيث تؤثر السرعة على التحويل أو العمل اليومي، مثل "الصفحة الرئيسية إلى التسجيل"، "التحميل الأول للوحة بعد تسجيل الدخول"، أو "الدفع وتأكيد الطلب". اختر شيئًا ممثلًا ومتكررًا، وليس حالة حدية.
تطبيقك لا يعمل على لابتوبك فقط. الميزانية التي تبدو جيدة على جهاز سريع قد تكون بطيئة على هاتف متوسط.
قرّر فئة جهاز واحدة وملف تعريف شبكة واحد لتبدأ بهما. اجعلها بسيطة واكتبها كجملة يكررها الجميع.
مثال: هاتف أندرويد متوسط من آخر سنتين إلى ثلاث سنوات، على 4G أثناء التنقل (ليس Wi‑Fi المكتب)، قياس تحميل بارد ثم تنقّل رئيسي واحد، في نفس المنطقة حيث يوجد معظم المستخدمين.
المقصود ليس اختيار أسوأ حالة. المقصود اختيار حالة شائعة يمكنك تحسينها فعليًا.
الأرقام ذات قيمة فقط إذا كانت قابلة للمقارنة. إذا كان تشغيل واحد "Chrome مع إضافات على ماك" والآخر "محمّل مع إعدادات المحمول"، خطك البياني يصبح ضوضاء.
اختر بيئة أساسية والتزم بها لفحوصات الميزانية: نفس إصدار المتصفح، نفس إعدادات التقييد (throttling)، نفس مسار الاختبار، ونفس حالة الكاش (بارد أو دافئ). إذا استخدمت أجهزة فعلية، استخدم نفس طراز الجهاز.
الآن عرّف ماذا يعني "سريع بما يكفي" من حيث السلوك، وليس عروض مثالية. مثال: "يبدأ المستخدمون بقراءة المحتوى بسرعة" أو "تشعر اللوحة بالاستجابة بعد تسجيل الدخول". ترجم ذلك إلى مقياس أو اثنين لهذه الرحلة، ثم ضع حوله ميزانيات.
تعمل الميزانيات بشكل أفضل عندما تغطي ما يشعر به المستخدمون وما يمكن للفرق التحكم به. مجموعة جيدة تمزج مقاييس التجربة (جزء "هل بدا سريعًا؟") مع حدود الموارد ووحدة المعالجة (جزء "لماذا أصبح بطيئًا؟").
تتابع هذه كيف تتصرف الصفحة للمستخدمين الحقيقيين. الأكثر فائدة منها ترتبط مباشرة بـ Core Web Vitals:
ميزانيات التوقيت هي نجمتك القطبية لأنها تطابق إحباط المستخدم. لكنها لا تخبرك دائمًا ماذا تصلح، لذا تحتاج أيضًا أنواع الميزانيات التالية.
أسهل في فرضها في وقت البناء والمراجعات لأنها ملموسة.
حدود الوزن تقيد أمورًا مثل إجمالي JavaScript، إجمالي CSS، وزن الصور، وأوزان الخطوط. حدود الطلبات تقيد إجمالي عدد الطلبات والسكربتات الطرفية، مما يقلّل عبء الشبكة والعمل المفاجئ من العلامات والويدجتات والمتتبعات. حدود وقت التشغيل تحد من المهام الطويلة، وقت خيط الواجهة الرئيسي، ووقت الترطيب (خاصة في React)، والتي غالبًا ما تفسر لماذا تبدو الصفحة "بطيئة" على الهواتف متوسطة المواصفات.
مثال عملي في React: قد يبدو حجم الحزمة جيدًا، لكن إضافة كاروسيل جديد تضيف عملية عرض مكثفة على جهة العميل. الصفحة تُحمّل، ومع ذلك تبدو الفلاتر لزجة لأن الترطيب يحجب الخيط الرئيسي. حدود وقت التشغيل مثل "لا توجد مهام طويلة تجاوز X ملّي ثانية أثناء بدء التشغيل" أو "الترطيب يكتمل خلال Y ثوانٍ على جهاز متوسط" يمكنها التقاط هذا حتى عندما لا تكشف حدود الوزن عن المشكلة.
الأقوى أن تعامل هذه الأنواع كنظام واحد: ميزانيات التجربة تحدد النجاح، وميزانيات الحجم والطلبات ووقت التشغيل تحافظ على صدق الإصدارات وتجعل من السهل الإجابة على "ما الذي تغيّر؟".
إذا وضعت الكثير من الحدود، يتوقف الناس عن الانتباه. اختر 3 إلى 5 ميزانيات تتوافق مع ما يشعر به المستخدمون وأيضًا ما يمكنك قياسه في كل طلب سحب أو إصدار.
مجموعة بداية عملية (اضبط الأرقام لاحقًا):
عتبتان تبقيان الأمور معقولة. "تحذير" يخبرك أنك تنجرف. "فشل" يمنع الإصدار أو يتطلب موافقة صريحة. هذا يجعل الحد حقيقيًا دون خلق إنذارات دائمة.
دوّن الميزانية في مكان مشترك حتى لا يجادل أحد خلال إصدار مزدحم. اجعلها قصيرة ومحددة: أي صفحات أو تدفقات مغطاة، أين تُجرى القياسات (تدقيق محلي، CI، إصدار مْحاكى)، أي جهاز وشبكة تستخدم، وكيف تُعرّف المقاييس بالضبط (حقل مقابل مختبر، gzip مقابل خام، مستوى المسار مقابل التطبيق كله).
ابدأ بخط أساس يمكنك تكراره. اختر صفحة أو صفحتين مهمتين واختبرها على نفس ملف الجهاز والشبكة في كل مرة. شغّل الاختبار ثلاث مرات على الأقل وسجّل الوسيط حتى لا يحدد تشغيل غريب اتجاهك.
استخدم جدول أساس بسيط يشمل مقياس مستخدم ومقياس بناء. مثال: LCP وINP للصفحة، بالإضافة إلى إجمالي حجم JavaScript وإجمالي بايتات الصور للنسخة المبنية. هذا يجعل الميزانيات حقيقية لأنك ترى ما شُحن، وليس فقط ما خمّنته تجربة المختبر.
اضع ميزانيات أفضل قليلًا من الوضع الحالي، ليس أرقامًا خيالية. قاعدة متينة: تحسّن بنسبة 5 إلى 10 بالمئة من الوسيط الحالي لكل مقياس تهتم به. إذا كان LCP لديك 3.2s على إعداد الخط الأساس، لا تقفز إلى 2.0s فورًا. ابدأ بـ 3.0s، ثم شدّد بعد أن تثبت أنك تستطيع الالتزام.
أضف فحصًا سريعًا إلى كل إصدار قبل أن يراه المستخدمون. اجعله سريعًا بما يكفي حتى لا يتجنبه الناس. نسخة بسيطة: شغّل تدقيق صفحة واحدة على الصفحة المتفق عليها، فأشل البناء إذا تجاوزت JavaScript أو الصور الميزانية، خزّن النتائج لكل كوميت حتى ترى متى تغيّر الأمر، ودائمًا اختبر نفس نمط عنوان URL (لا بيانات عشوائية).
راجع حالات الخرق أسبوعيًا، ليس فقط عند شكاوى المستخدمين. عامل الخرق كخطأ: حدّد التغيير الذي سبّبه، قرّر ما يُصلح الآن وما يؤجل، وشدّد ببطء بعد أن تحافظ على الحدود لعدة إصدارات.
عند تغير نطاق المنتج، قوّم الميزانيات عن قصد. إذا أضفت أداة تحليلات جديدة أو ميزة ثقيلة، اكتب ما نما (حجم، طلبات، وقت تشغيل)، ماذا ستفعل لتعويضها لاحقًا، ومتى يجب أن تعود الميزانية.
الميزانية تساعد فقط إذا كنت تستطيع التحقق منها بسرعة. هدف تدقيق مدته 10 دقائق ليس إثبات رقم مثالي. إنه لإبراز ما تغيّر منذ الإصدار الجيد الأخير وتحديد ما يجب إصلاحه أولًا.
ابدأ بصفحة تمثل استخدامًا حقيقيًا. ثم شغّل نفس الفحوصات السريعة في كل مرة:
عرضان عادةً يعطيانك إجابات خلال دقائق: شلال الشبكة (network waterfall) وزمن الخيط الرئيسي (main-thread timeline).
في شلال الشبكة، ابحث عن طلب يهيمن على المسار الحرج: سكربت ضخم، خط محبوس، أو صورة تبدأ متأخرًا. إذا لم يُطلب مورد LCP مبكرًا، لا تستطيع الصفحة الوصول إلى ميزانية LCP مهما كان الخادم سريعًا.
في الجدول الزمني، ابحث عن المهام الطويلة (50 ms أو أكثر). عنقود من المهام الطويلة حول بدء التشغيل غالبًا يعني JavaScript كثيرًا في التحميل الأول. قطعة ضخمة واحدة عادةً مشكلة تقسيم مسارات أو حزمة مشتركة زادت مع الوقت.
تفشل التدقيقات السريعة حين يختلف كل تشغيل. سجّل بعض الأساسيات حتى تتضح التغيرات: عنوان الصفحة وإصدار البناء، جهاز الاختبار وملف الشبكة، وصف عنصر LCP، الأرقام الأساسية التي تتابعها (مثل LCP، إجمالي بايتات JS، عدد الطلبات)، وملاحظة قصيرة عن المذنب الأكبر.
الاختبار على سطح المكتب جيد للتغذية الراجعة السريعة وفحوص PR. استخدم جهازًا حقيقيًا عندما تكون قريبًا من الميزانية، عندما تبدو الصفحة متقطعة، أو عندما يميل جمهورك إلى المحمول. وحدات المعالجة في المحمول تجعل المهام الطويلة واضحة، وهناك تنهار كثير من الإصدارات التي "تبدو جيدة على اللابتوب".
عندما تفشل الميزانية، أسوأ قرار هو "تحسين كل شيء". استخدم ترتيب تفريغ متكرر حتى يكون لكل إصلاح عائد واضح.
ابدأ بما يلاحظه المستخدمون أكثر، ثم انتقل إلى الضبط الأدق:
أرسل فريق لوحة تحكم جديدة وفجأة أصابهم فشل في حد LCP. بدلاً من التلاعب برؤوس الكاش أولًا، وجدوا أن عنصر LCP صورة مخطط بعرض كامل. غيّروا حجمها، قدّموا صيغة أخف، وحمّلوا فقط ما يهم مبكرًا. بعد ذلك لاحظوا مكتبة رسوم بيانية كبيرة تُحمّل على كل مسار. حمّلوها فقط في صفحة التحليلات وأجّلوا ويدجت دعم طرف ثالث حتى بعد التفاعل الأول. خلال يوم، عادت اللوحة للالتزام بالميزانية، والإصدار التالي كان له إجابات واضحة على "ما الذي تغيّر".
أكبر سبب فشل هو معاملة الميزانيات كمستند لمرة واحدة. تعمل الميزانيات فقط عندما تكون سهلة الفحص، صعبة التجاهل، ومرتبطة بطريقتكم في الشحن.
تقع معظم الفرق في بعض المصائد:
نمط شائع هو ميزة "صغيرة" تجلب مكتبة جديدة. تكبر الحزمة، يتباطأ LCP بثانية على الشبكات البطيئة، ولا يلاحظ أحد حتى تصل تذاكر الدعم. الميزانيات موجودة لجعل هذا التغيير مرئيًا عند المراجعة.
ابدأ بسيطًا واحتفظ بالفحوصات متسقة. اختر 2 إلى 4 ميزانيات ترتبط بتجربة المستخدم وشدّدها تدريجيًا. ثبّت إعداد الاختبار ودوّنه. تابع إشارة مستخدم واحدة حقيقية إن أمكن، واستخدم اختبارات المختبر لشرح "لماذا"، ليس لكسب حجج. عندما تضيف تبعية وزنًا معنوياً، اطلب ملاحظة قصيرة: ما التكلفة، ماذا تستبدل، ولماذا تستحق. والأهم ضع فحص الميزانية على مسار الإصدار الطبيعي.
إذا بدت الميزانيات كاحتكاك دائم، فغالبًا هي غير واقعية لليوم، أو غير مرتبطة بقرارات حقيقية. اصلح هذين الأمرين أولًا.
فريق صغير أطلق لوحة React تحليلات في أسبوع. بدت سريعة في البداية، لكن كل إصدار يوم جمعة جعلها أثقل قليلاً. بعد شهر، بدأ المستخدمون يقولون إن الشاشة الأولى "تتجمد" والفلاتر بطيئة.
توقفوا عن الجدل حول "السريع بما يكفي" ودوّنوا ميزانيات مرتبطة بما يلاحظه المستخدمون:
أظهر الفشل الأول نقطتين. الحزمة الابتدائية زادت مع إضافة رسوم بيانية ومكتبات تواريخ ومجموعة واجهة مستخدم. في نفس الوقت، استبدلوا صورة رأس اللوحة بملف أكبر "فقط مؤقتًا"، مما دفع LCP فوق الحد. تدهور INP لأن كل تغيير فلتر سبب عمليات إعادة عرض مكلفة ومعالجات ثقيلة على الخيط الرئيسي.
أصلحوها بترتيب أعطى مكاسب سريعة ومنع تكرار الانتكاسات:
إعادة LCP تحت الحد عبر تغيير أحجام الصور وضغطها وتحديد أبعادها وتجنب تحميل الخطوط المحجوزة.
تقليل JS الابتدائي بإزالة المكتبات غير المستخدمة، تقسيم المسارات غير الحرجة، والتحميل الكسول للرسوم.
تحسين INP عبر تحبيس مكونات مكلفة، تأخير أحداث الكتابة (debounce)، ونقل العمل الثقيل من المسار الحار.
إضافة فحص ميزانية إلى كل إصدار حتى إذا كسر مقياس ما، ينتظر الإصدار.
بعد إصدارين، انخفض LCP من 3.4s إلى 2.3s، وتحسّن INP من نحو 350ms إلى أقل من 180ms على نفس جهاز الاختبار.
تعمل الميزانية فقط إذا تمكن الناس من اتباعها بنفس الطريقة في كل مرة. اجعلها صغيرة، اكتبها، واجعلها جزءًا من الشحن.
اختر مجموعة مقاييس تناسب تطبيقك، حدّ عتبات "تحذير مقابل فشل"، ووثق كيف تختبر بالضبط (جهاز، متصفح، شبكة، صفحة/تدفق). احفظ تقرير خط أساس من أفضل إصدار حالي وعلّمه بوضوح. قرّر ما يُعتبر استثناءً صالحًا وما لا يُعتبر.
قبل كل إصدار، شغّل نفس التدقيق وقارنه بالخط الأساس. إذا تراجع شيء، سجّله في تتبّع الأخطاء وعامله كخطأ في خطوة الدفع، ليس مهمة لاحقة. إذا شحنت باستثناء، سجّل مالكًا وتاريخ انتهاء (غالبًا 1–2 سباق تطوير). إذا استمر الاستثناء بالتجدد، تحتاج الميزانية إلى نقاش جاد.
انقل الميزانيات إلى التخطيط والتقديرات مبكرًا: "هذه الشاشة تضيف مكتبة رسوم بيانية، لذا علينا إزالة شيء آخر أو تحميلها كسولًا." إذا كنت تبني مع Koder.ai (koder.ai)، يمكنك أيضًا كتابة هذه القيود مقدمًا في وضع التخطيط، ثم التكرار في شرائح أصغر واستخدام لقطات واستعادة عند دفع تغيير لتجاوز الحد. الفكرة ليست الأداة، بل العادة: كل ميزة جديدة يجب أن تدفع عن وزنها، أو لا تُشحن.
ميزانية الأداء هي مجموعة من الحدود الصارمة (زمن، حجم، طلبات، عمل وحدة المعالجة) التي يتفق عليها الفريق قبل عملية البناء.
إذا تعدى تغيير ما الحد، اعتبره متطلبًا مكسورًا: أصلحه، قلّل النطاق، أو اعتمد استثناءً صريحًا مع مالك وتاريخ انتهاء.
لأن الأداء يتدهور بتدرج. كل ميزة تضيف JavaScript وCSS وصور وخطوط واستدعاءات API وعلامات طرف ثالث.
توقف الميزانيات عن هذا التدهور البطيء بفرض المقايضة: إذا أضفت وزنًا أو عملًا، عليك أن تدفعه لاحقًا (تحميل كسول، تقسيم المسارات، تبسيط الواجهة، إزالة تبعية).
اختر رحلة مستخدم حقيقية واحدة وإعداد اختبار ثابت.
بداية جيدة تكون رحلة متكررة ومهمة تجاريًا، مثل:
تجنّب الحالات الحدية في البداية؛ تريد تدفقًا يمكنك قياسه في كل إصدار.
ابدأ بهدف واحد يطابق مستخدميك، مثل:
دوّن ذلك وحافظ على ثباته. تغيير الجهاز أو الشبكة أو حالة التخزين المؤقت يجعل المسار الضوضائي غير مقارن.
استخدم مجموعة صغيرة تغطي ما يشعر به المستخدمون وما يمكن للفِرَق التحكم به:
مقاييس التوقيت تُظهر الألم؛ حدود الحجم ووقت التشغيل تساعدك على العثور بسرعة على المسبب.
مجموعة بداية عملية:
استخدم عتبتين:
هذا يجنّب إنذارات دائمة بينما يجعل الحدود حقيقية عندما تُخَطَّأ.
اتبع هذا بالترتيب:
ليس دائمًا. قد يكون حجم الحزمة جيدًا لكن الصفحة لا تزال بطيئة لأن خيط التنفيذ مشغول.
أسباب شائعة في React:
أضف ميزانية وقت تشغيل (مثلاً حد للمهام الطويلة أثناء بدء التشغيل أو حد لوقت الترطيب) لالتقاط هذه الفئة من المشاكل.
التوليد السريع والتكرار يمكن أن يضيفا تبعيات وديكورات UI والعلامات الطرفية التي تُشَحن للجميع بصمت.
الحل: ضع الميزانيات كجزء من سير العمل:
هذا يمنع التحرك السريع من أن يتحول إلى منتج بطيء.
اختر 3–5 ميزانيات أولًا. اضبط الأرقام لاحقًا بناءً على خط الأساس وتاريخ الإصدارات.
عامل الخرق كخطأ: عرّف الكوميت، أصلح أو قلّص النطاق، ومنع التكرار.