ازاي تحلل أداء تطبيقات رياكت (React Performance) وتكتشف المشاكل باستخدام React Profiler
أهلاً بيك يا صديقي المبرمج في مقال جديد من سلسلة الشروحات التقنية. أكيد في يوم من الأيام وأنت شغال على مشروع تطوير الويب (Web Development) بلغة جافا سكربت (JavaScript) باستخدام مكتبة رياكت (React)، لاحظت إن التطبيق بتاعك بيبدأ يهنج أو يحصل فيه بطء غريب، خصوصاً لما البيانات تكتر أو المستخدم يبدأ يتفاعل مع الصفحة بشكل سريع. بتبدأ تسأل نفسك: هو إيه اللي بيحصل؟ ليه الصفحة بتتعمل ليها إعادة تصيير (Re-rendering) في كل حتة بدون داعي؟
الوجع ده كلنا عشناه، ومفيش مبرمج رياكت (React Developer) مميز إلا وقابل المشكلة دي. الخبر الجميل إن رياكت وفرت لنا أداة سحرية ببلاش ومن جوه الصندوق اسمها React Profiler. الأداة دي هتشيل الغمامة من على عيونك وهتخليك تشوف بالثانية والمللي ثانية إيه هي المكونات البطيئة (Slow Components) اللي بتعطل التطبيق بتاعك.
Table of contents [Show]
- 1 إيه هو React Profiler وليه بنحتاجه في تحسين الأداء (Performance Optimization)؟
- 2 خطوات تشغيل وتثبيت أدوات المطورين (React Developer Tools)
- 3 قراءة تقارير الأداء واكتشاف المكونات البطيئة (Flamegraph و Ranked Charts)
- 4 مثال عملي على مشكلة إعادة التصيير (Re-rendering) وكيفية حلها
- 5 خاتمة ونصيحة من أخ
إيه هو React Profiler وليه بنحتاجه في تحسين الأداء (Performance Optimization)؟
باختصار شديد، الـ React Profiler هو أداة قياس أداء بتيجي جوه أداة المطورين الشهيرة React Developer Tools. فايدتها الأساسية إنها بتسجل كل عملية تصيير (Render) بتحصل جوه التطبيق بتاعك، وبتقولك بالظبط كل مكون (Component) خد وقت قد إيه عشان يتصيّر، وليه أصلاً حصل ليه إعادة تصيير (Re-rendering).
لما بنعمل بناء لتطبيقات كبيرة، أحياناً تغيير بسيط في حالة (State) في الأب (Parent Component) بيخلي كل الأبناء (Child Components) يعملوا إعادة تصيير حتى لو مفيش أي حاجة اتغيرت في البيانات بتاعتهم. هنا بيجي دور الـ Profiler عشان يكشف لك الأماكن دي ويخليك تطبق تقنيات التحسين زي React.memo و useCallback و useMemo في مكانها الصح مش بشكل عشوائي.
خطوات تشغيل وتثبيت أدوات المطورين (React Developer Tools)
عشان نبدأ رحلة التحليل، لازم نتاكد إنك مثبت إضافة React Developer Tools على المتصفح بتاعك (سواء جوجل كروم أو فايرفوكس). بعد ما تثبتها، افتح مشروعك واضغط F12، هتلاقي تاب جديدة ظهرت معاك باسم Profiler.
جوة التاب دي، هتلاقي زرار تسجيل دائري بلون أحمر. الخطوات ببساطة كالتالي:
- اضغط على زرار التسجيل (Record).
- روح على تطبيقك واعمل الأكشن اللي بيعمل بطء (مثلاً اضغط على زرار معين أو اكتب في إبتوت).
- ارجع تاني لتاب الـ Profiler واضغط على وقف التسجيل (Stop).
- هيبدأ يظهر قدامك تقرير مفصل بكل عمليات التصيير اللي حصلت خلال الفترة دي.
قراءة تقارير الأداء واكتشاف المكونات البطيئة (Flamegraph و Ranked Charts)
لما التسجيل بيخلص، بتشوف قدامك شاشة مليانة تفاصيل. أهم جزئين لازم تركز عليهم هما:
- رسمة اللهب (Flamegraph): بتمثل شجرة المكونات (Component Tree) بتاعتك وقت التسجيل. كل مستطيل بيمثل مكون، واللون بيعبر عن سرعته. الألوان الصفراء والبرتقالية والحمراء بتعني إن المكون ده خد وقت طويل في التصيير، بينما الألوان الباردة (الأزرق والأخضر) بتعني إن أداة سريع.
- الترتيب حسب الأداء (Ranked Chart): بيجيب لك المكونات مترتبة من الأبطأ للأسرع بشكل تنازلي. دي أسرع طريقة تكتشف بيها المكونات اللي بتهنج التطبيق بتاعك (Slow Components).
مثال عملي على مشكلة إعادة التصيير (Re-rendering) وكيفية حلها
تخيل عندنا مكون بيعرض قائمة كبيرة، وكل ما ندوس على زرار العداد، القائمة كلها بتتعمل ليها إعادة تصيير بدون سبب. الكود بيكون بالشكل ده:
import React, { useState } from 'react';
function HeavyList({ items }) {
console.log('HeavyList rendered!');
return (
<ul>
{items.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
);
}
function App() {
const [count, setCount] = useState(0);
const items = [{ id: 1, name: 'مصر' }, { id: 2, name: 'السعودية' }];
return (
<div>
<button onClick={() => setCount(count + 1)}>العداد: {count}</button>
<HeavyList items={items} />
</div>
);
}
export default App;
لو بصيت في الـ React Profiler هنا، هتكتشف إن كل ما تدوس على زرار العداد، مكون HeavyList بيعمل Re-render رغم إن الـ items مفيهاش أي تغيير! الحل البسيط هنا هو استخدام React.memo عشان نحمي المكون من التصيير غير الضروري:
import React, { useState } from 'react';
const HeavyList = React.memo(function HeavyList({ items }) {
console.log('HeavyList rendered!');
return (
<ul>
{items.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
);
});
بالتعديل البسيط ده، الـ Profiler هيوريك إن مكون HeavyList بقى بيعدي من عملية التصيير طالما البروبس (Props) بتاعته متغيّرتش، وده هيحسن الأداء بشكل ملحوظ جداً (Performance Boost).
خاتمة ونصيحة من أخ
يا صديقي، تحسين الأداء مش ممارسات عشوائية بنعملها وخلاص، الأداء بيتحسن بالقياس والتحليل الصح. استخدم دائماً React Profiler عشان تشوف المشكلة فين بالضبط قبل ما تبدأ تعدل في الكود. متجريش وراء التحسين المبكر (Premature Optimization)، بل استعمل أدوات القياس، اكتشف الـ Bottlenecks، وصلحها بثقة. بالتوفيق ليك في رحلتك البرمجية، ودايماً خليك مستكشف ومطور بيحب التفاصيل!