يريد المتصفح تجميع حسابات الأنماط وأعمال التخطيط. تظهر مشاكل الأداء عندما يواصل كود التطبيق مقاطعة تلك الخطة بالتناوب بين الكتابات إلى DOM وقراءات التخطيط في حلقات ضيقة.
تسمى تلك النمط عادةً اهتزاز التخطيط.
نمط الخطأ
هذا هو الشكل المكلف:
for (const item of items) {
item.style.width = "200px";
const rect = item.getBoundingClientRect();
item.style.height = `${rect.width}px`;
}
قد يجبر كل استدعاء لـ getBoundingClientRect() المتصفح على تنفيذ العمل المعلق للتخطيط قبل أن يتمكن من التجاوب. إذا كان هذا يجري أثناء التمرير أو تغيير الحجم أو الرسوم المتحركة، ستصبح واجهة المستخدم متقطعة بسرعة.
نمط أفضل
اجمع القراءات أولاً. اجمع الكتابات ثانياً:
const widths = items.map((item) => item.getBoundingClientRect().width);
items.forEach((item, index) => {
item.style.width = "200px";
item.style.height = `${widths[index]}px`;
});
هذا ليس الإصلاح الوحيد الممكن، لكنه يظهر القاعدة الأساسية: تجنب إكراه المتصفح على إعادة حساب التخطيط بشكل متكرر داخل الكود الحساس للإطارات.
متى تكون هذه المسألة مهمة
عادةً ما تشعر بها في:
- معالجات التمرير
- حلقات الرسوم المتحركة
- التفاعلات بالسحب والإفلات
- القوائم الكبيرة مع التلاعب المباشر في DOM
المتصفح سريع عندما تترك له حرية تجميع العمل. يصبح مكلفاً عندما تجبره على الإجابة عن أسئلة الهندسة مباشرة بعد كل كتابة.
إذا كان يجب تشغيل الكود أثناء الرسوم المتحركة أو التفاعل، فإن requestAnimationFrame هو غالباً المكان المناسب لجدولة أعمال DOM المجمع بحيث تحدث القراءات والكتبات في حدود إطار أكثر توقعاً.
المزيد من القراءة