تعرَّف على كيفية استخدام Chrome و"أدوات مطوري البرامج في Chrome" للعثور على مشاكل الذاكرة التي تؤثر في أداء الصفحة، بما في ذلك تسرُّب الذاكرة وتضخُّم الذاكرة وعمليات جمع المهملات المتكررة.
ملخّص
- يمكنك معرفة حجم الذاكرة التي تستخدمها صفحتك من خلال "مدير مهام Chrome".
- يمكنك الاطّلاع على استخدام الذاكرة بمرور الوقت من خلال تسجيلات "المخطّط الزمني".
- تحديد أشجار نموذج العناصر في المستند المنفصلة (وهي سبب شائع لتسرُّب الذاكرة) باستخدام لقطات لعناصر متعدّدة
- يمكنك معرفة وقت تخصيص ذاكرة جديدة في كومة JS باستخدام تسجيلات "المخطط الزمني للتخصيص".
- تحديد العناصر المنفصلة التي يحتفظ بها مرجع JavaScript
نظرة عامة
وفقًا لنموذج الأداء RAIL، يجب أن يكون تركيز جهودك في تحسين الأداء منصبًا على المستخدمين.
تُعدّ مشاكل الذاكرة مهمة لأنّ المستخدمين غالبًا ما يلاحظونها. يمكن للمستخدمين إدراك مشاكل الذاكرة بالطرق التالية:
- ينخفض أداء الصفحة تدريجيًا بمرور الوقت. قد يكون هذا من أعراض تسرّب الذاكرة. يحدث تسرّب الذاكرة عندما يتسبّب خطأ في الصفحة في استخدام الصفحة لمزيد من الذاكرة بمرور الوقت.
- أداء الصفحة سيئ باستمرار. قد يكون هذا أحد أعراض تضخّم الذاكرة. ويحدث تضخّم الذاكرة عندما تستخدم الصفحة ذاكرة أكبر من اللازم لتحقيق السرعة المثلى للصفحة.
- يتأخر أداء الصفحة أو يبدو أنّه يتوقف مؤقتًا بشكل متكرر. قد يكون هذا من أعراض عمليات جمع المهملات المتكررة. "جمع المهملات" هو عندما يستعيد المتصفّح الذاكرة. ويحدّد المتصفّح وقت حدوث ذلك. أثناء عمليات جمع البيانات، يتم إيقاف تنفيذ جميع النصوص البرمجية مؤقتًا. لذلك، إذا كان المتصفّح يجمع الكثير من البيانات المهملة، سيتم إيقاف تنفيذ النص البرمجي مؤقتًا كثيرًا.
تضخّم الذاكرة: ما هو الحدّ الأقصى المسموح به؟
من السهل تحديد تسرّب الذاكرة. إذا كان الموقع الإلكتروني يستخدم المزيد والمزيد من الذاكرة بشكل تدريجي، فهذا يعني أنّ هناك تسرُّبًا. ولكن من الصعب تحديد تضخّم الذاكرة. ما الذي يُعدّ "استخدامًا كبيرًا للذاكرة"؟
لا توجد أرقام دقيقة هنا، لأن الأجهزة والمتصفحات المختلفة لها إمكانات مختلفة. فالصفحة نفسها التي تعمل بسلاسة على هاتف ذكي متطوّر قد تتعطّل على هاتف ذكي منخفض المواصفات.
يكمن السر هنا في استخدام نموذج RAIL والتركيز على المستخدمين. اكتشف الأجهزة الشائعة بين المستخدمين، ثم اختبر صفحتك على تلك الأجهزة. إذا كانت التجربة سيئة باستمرار، قد تكون الصفحة تتجاوز إمكانات الذاكرة في هذه الأجهزة.
مراقبة استخدام الذاكرة في الوقت الفعلي باستخدام "إدارة مهام Chrome"
استخدِم "مدير مهام Chrome" كنقطة بداية للتحقيق في مشكلة الذاكرة. "إدارة المهام" هي أداة مراقبة في الوقت الفعلي تخبرك بمقدار الذاكرة التي تستخدمها الصفحة.
اضغط على Shift+Esc أو انتقِل إلى قائمة Chrome الرئيسية واختَر أدوات إضافية > مدير المهام لفتح "مدير المهام".

انقر بزر الماوس الأيمن على عنوان جدول "إدارة المهام" وفعِّل ذاكرة JavaScript.

يقدّم هذان العمودان معلومات مختلفة حول كيفية استخدام صفحتك للذاكرة:
- يمثّل عمود استهلاك الذاكرة ذاكرة نظام التشغيل. يتم تخزين عُقد DOM في ذاكرة نظام التشغيل. إذا كانت هذه القيمة تزداد، فهذا يعني أنّه يتم إنشاء عُقد DOM.
يمثّل عمود ذاكرة JavaScript كومة الذاكرة المؤقتة لـ JavaScript. يحتوي هذا العمود على قيمتَين. القيمة التي تهمّك هي الرقم المباشر (الرقم بين قوسين). يمثّل الرقم المباشر مقدار الذاكرة التي تستخدمها العناصر التي يمكن الوصول إليها في صفحتك. إذا كان هذا الرقم في تزايد، فهذا يعني أنّه يتم إنشاء عناصر جديدة أو أنّ العناصر الحالية تتزايد.

عرض تسريبات الذاكرة باستخدام تسجيلات الأداء
يمكنك أيضًا استخدام لوحة الأداء كنقطة بداية أخرى في تحقيقك. تساعدك لوحة "الأداء" في الاطّلاع على استخدام الصفحة للذاكرة بمرور الوقت.
- افتح لوحة الأداء في "أدوات مطوّري البرامج".
- ضَع علامة في مربّع الاختيار الذاكرة.
- إنشاء تسجيل
لتوضيح تسجيلات الذاكرة في الأداء، يمكنك الاطّلاع على الرمز البرمجي التالي:
var x = [];
function grow() {
for (var i = 0; i < 10000; i++) {
document.body.appendChild(document.createElement('div'));
}
x.push(new Array(1000000).join('x'));
}
document.getElementById('grow').addEventListener('click', grow);
في كل مرة يتم فيها الضغط على الزر المُشار إليه في الرمز، يتم إلحاق عشرة آلاف عقدة div
بمحتوى المستند، ويتم دفع سلسلة من مليون حرف x إلى مصفوفة x.
يؤدي تشغيل هذا الرمز إلى إنشاء تسجيل في "المخطط الزمني" مثل لقطة الشاشة التالية:

أولاً، شرح لواجهة المستخدم. يمثّل الرسم البياني HEAP في لوحة نظرة عامة (أسفل NET) الذاكرة الديناميكية لـ JS. أسفل لوحة نظرة عامة، تظهر لوحة العدّاد. يمكنك هنا الاطّلاع على استخدام الذاكرة مقسّمًا حسب كومة الذاكرة المؤقتة لـ JS (مثل الرسم البياني كومة الذاكرة المؤقتة في لوحة النظرة العامة) والمستندات وعُقد DOM والمتتبِّعين وذاكرة وحدة معالجة الرسومات. يؤدي إيقاف مربّع اختيار إلى إخفائه من الرسم البياني.
والآن، إليك تحليل للرمز البرمجي مقارنةً بلقطة الشاشة. إذا نظرت إلى عدّاد العُقد (الرسم البياني الأخضر)، يمكنك ملاحظة أنّه يتطابق تمامًا مع الرمز. يزداد عدد العُقد في
خطوات منفصلة. يمكنك افتراض أنّ كل زيادة في عدد العُقد هي طلب إلى grow(). الرسم البياني لكومة JS (الرسم البياني الأزرق) ليس واضحًا. وفقًا لأفضل الممارسات، فإنّ الانخفاض الأول هو في الواقع عملية جمع مهملات قسرية (يتم إجراؤها من خلال الضغط على زر جمع المهملات). ومع تقدّم التسجيل، يمكنك ملاحظة ارتفاع حجم كومة الذاكرة المؤقتة لجافا سكريبت. هذا أمر طبيعي ومتوقع: ينشئ رمز JavaScript عُقد DOM عند كل نقرة على الزر ويقوم بالكثير من العمل عند إنشاء سلسلة من مليون حرف. النقطة الأساسية هنا هي أنّ كومة الذاكرة المؤقتة في JS تنتهي بمستوى أعلى من المستوى الذي بدأت به ("البداية" هنا هي النقطة التي تلي عملية جمع البيانات المُهمَلة الإلزامية). في العالم الحقيقي، إذا رأيت هذا النمط من زيادة حجم كومة JS أو حجم العقدة، فقد يعني ذلك تسربًا في الذاكرة.
اكتشاف حالات تسرُّب الذاكرة في شجرة نموذج العناصر في المستند (DOM) المنفصلة باستخدام لقطات لعناصر متعدّدة
لا يمكن جمع المهملات من عقدة DOM إلا في حال عدم وجود مراجع لها من شجرة نموذج العناصر في المستند (DOM) الخاصة بالصفحة أو من رمز JavaScript. تُعتبر العقدة "منفصلة" عندما تتم إزالتها من شجرة نموذج العناصر في المستند (DOM) ولكن لا تزال بعض رموز JavaScript تشير إليها. تُعدّ عُقد DOM المنفصلة سببًا شائعًا لتسرُّب الذاكرة. يوضّح لك هذا القسم كيفية استخدام مسجّلات لقطات العناصر المتعدّدة في "أدوات مطوري البرامج" لتحديد العُقد المنفصلة.
في ما يلي مثال بسيط على عُقد DOM المنفصلة.
var detachedTree;
function create() {
var ul = document.createElement('ul');
for (var i = 0; i < 10; i++) {
var li = document.createElement('li');
ul.appendChild(li);
}
detachedTree = ul;
}
document.getElementById('create').addEventListener('click', create);
يؤدي النقر على الزر المُشار إليه في الرمز إلى إنشاء عقدة ul تتضمّن عشر عُقد تابعة من النوع li. تتم الإشارة إلى هذه العُقد
من خلال الرمز البرمجي، ولكنّها غير متوفّرة في شجرة نموذج العناصر في المستند، لذا يتم فصلها.
تُعدّ لقطات العناصر المتعدّدة إحدى الطرق لتحديد العُقد المنفصلة. كما يشير الاسم، تعرض لك لقطات لعناصر متعدّدة كيفية توزيع الذاكرة بين عناصر JS وعُقد DOM في صفحتك في وقت اللقطة.
لإنشاء لقطة، افتح "أدوات مطوري البرامج في Chrome" وانتقِل إلى لوحة الذاكرة، ثم انقر على زر الاختيار لقطة لعناصر متعدّدة، ثم انقر على الزر أخذ لقطة.

قد تستغرق اللقطة بعض الوقت للمعالجة والتحميل. بعد الانتهاء، اختَرها من اللوحة اليمنى (المسماة لقطات لعناصر متعدّدة).
اكتب Detached في مربّع الإدخال فلتر الفئة للبحث عن أشجار نموذج العناصر في المستند المنفصلة.

انقر على علامات الإقحام لتوسيع شجرة منفصلة والتحقيق فيها.

انقر على عقدة للتحقيق فيها بشكل أكبر. في لوحة العناصر، يمكنك الاطّلاع على مزيد من المعلومات حول الرمز الذي يشير إليها. على سبيل المثال، في لقطة الشاشة التالية، يمكنك ملاحظة
أنّ المتغيّر detachedTree يشير إلى العقدة. لإصلاح تسرّب الذاكرة هذا، عليك
دراسة الرمز الذي يستخدم detachedTree والتأكّد من أنّه يزيل مرجعه إلى العقدة
عندما لا تكون هناك حاجة إليه.

تحديد تسرُّبات الذاكرة في كومة الذاكرة المؤقتة لجافا سكريبت باستخدام "المخطّطات الزمنية لتخصيص أجزاء من الذاكرة"
المخطط الزمني للتخصيص هو أداة أخرى يمكن أن تساعدك في تتبُّع تسرُّب الذاكرة في كومة ذاكرة JavaScript.
لتوضيح المخطط الزمني للتخصيص، ضع الرمز التالي في اعتبارك:
var x = [];
function grow() {
x.push(new Array(1000000).join('x'));
}
document.getElementById('grow').addEventListener('click', grow);
في كل مرة يتم فيها الضغط على الزر المُشار إليه في الرمز، تتم إضافة سلسلة من مليون حرف إلى مصفوفة x.
لتسجيل مخطط زمني للتخصيص، افتح "أدوات مطوري البرامج"، وانتقِل إلى لوحة الذاكرة، واختَر زر الاختيار التخصيصات في المخطط الزمني، واضغط على زر تسجيل، ونفِّذ الإجراء الذي تشكّ في أنّه يتسبب في تسرّب الذاكرة، ثم اضغط على زر إيقاف التسجيل عند الانتهاء.
أثناء التسجيل، تحقَّق مما إذا كانت أي أشرطة زرقاء تظهر في المخطط الزمني للتخصيص، كما هو موضّح في لقطة الشاشة التالية.

تمثّل هذه الأشرطة الزرقاء عمليات تخصيص الذاكرة الجديدة. تخصيصات الذاكرة الجديدة هذه هي المرشحة لتسريبات الذاكرة. يمكنك تكبير شريط لفلترة لوحة الدالة الإنشائية لعرض العناصر التي تم تخصيصها خلال الإطار الزمني المحدّد فقط.

وسِّع العنصر وانقر على قيمته للاطّلاع على المزيد من التفاصيل عنه في لوحة العنصر. على سبيل المثال، في لقطة الشاشة أدناه، من خلال الاطّلاع على تفاصيل العنصر الذي تم تخصيصه حديثًا،
يمكنك معرفة أنّه تم تخصيصه للمتغيّر x في نطاق Window.

التحقيق في تخصيص الذاكرة حسب الدالة
استخدِم نوع الملف الشخصي أخذ عينات من عمليات تخصيص الذاكرة في لوحة الذاكرة لعرض عمليات تخصيص الذاكرة حسب دالة JavaScript.

- انقر على زر الاختيار أخذ عينات من التخصيص. إذا كان هناك عامل على الصفحة، يمكنك اختياره كهدف لإنشاء الملف الشخصي من نافذة اختيار مثيل جهاز افتراضي للغة JavaScript.
- اضغط على الزر بدء.
- نفِّذ الإجراءات على الصفحة التي تريد التحقيق فيها.
- انقر على الزر إيقاف عند الانتهاء من جميع الإجراءات.
تعرض لك "أدوات مطوري البرامج" تفاصيل تخصيص الذاكرة حسب الدالة. طريقة العرض التلقائية هي ثقيلة (من الأسفل إلى الأعلى)، والتي تعرض الدوال التي خصّصت أكبر قدر من الذاكرة في الأعلى.

تحديد العناصر التي يحتفظ بها مرجع JS
يعرض لك الملف الشخصي العناصر المنفصلة العناصر المنفصلة التي تظلّ ظاهرة لأنّها مُشار إليها بواسطة رمز JavaScript.
سجِّل ملفًا شخصيًا للعناصر المنفصلة لعرض عُقد HTML وعدد العُقد بدقة.

رصد عمليات جمع البيانات غير الضرورية المتكرّرة
إذا كانت صفحتك تتوقف مؤقتًا بشكل متكرر، قد تكون لديك مشاكل في تجميع المهملات.
يمكنك استخدام "مدير مهام Chrome" أو تسجيلات الذاكرة في "المخطط الزمني" لرصد عمليات جمع المهملات المتكررة. في "مدير المهام"، تمثّل قيم الذاكرة أو ذاكرة JavaScript التي ترتفع وتنخفض بشكل متكرر عمليات جمع البيانات المهملة المتكررة. في تسجيلات المخطط الزمني، تشير الرسوم البيانية لعدد العقد أو كومة JS التي ترتفع وتنخفض بشكل متكرر إلى عمليات جمع المهملات المتكررة.
بعد تحديد المشكلة، يمكنك استخدام تسجيل "المخطط الزمني للتخصيص" لمعرفة مكان تخصيص الذاكرة والدوال التي تتسبب في عمليات التخصيص.