غالبًا ما تؤدي لغة JavaScript إلى تشغيل تغييرات مرئية. في بعض الأحيان يكون ذلك مباشرًا من خلال عمليات معالجة الأنماط، وأحيانًا تكون العمليات الحسابية التي تؤدي إلى تغييرات مرئية، مثل البحث عن البيانات أو فرزها. إنّ تشغيل JavaScript في وقت غير صحيح أو طويل الأمد هو سبب شائع لحدوث مشاكل في الأداء. يجب أن تتطلع إلى تقليل تأثيره حيثما أمكن.
غالبًا ما تؤدي لغة JavaScript إلى تشغيل تغييرات مرئية. في بعض الأحيان يكون ذلك من خلال التلاعب بالأسلوب، وفي بعض الأحيان تكون العمليات الحسابية تؤدي إلى تغييرات مرئية، مثل البحث عن البيانات أو فرزها. الوقت سيئ أو أنّ تشغيل JavaScript لفترة طويلة هو سبب شائع لحدوث مشاكل في الأداء. يجب أن تتطلع إلى تقليل تأثيره حيثما أمكن.
يمكن أن يكون تحليل أداء JavaScript شيئًا فنيًا، لأنّ لغة JavaScript التي تكتبها لا شيء مثل التعليمات البرمجية التي يتم تنفيذها بالفعل. تستخدم المتصفّحات الحديثة برامج التجميع أثناء التشغيل وبجميع الطرق من التحسينات والحيل لمحاولة إعطائك أسرع تنفيذ ممكن، وهذا تؤدي إلى تغيير ديناميكيات الرمز البرمجي بشكل كبير.
مع ذلك، هناك بعض الإجراءات التي يمكنك اتخاذها للمساعدة في تنفيذ تطبيقاتك. JavaScript جيدًا.
ملخّص
- تجنَّب ضبط المهلة المحددة أو مَعلمة setInterval للتحديثات المرئية. أن يستخدم دائمًا requestAnimationFrame بدلاً منها.
- نقل JavaScript الطويل الأمد من سلسلة التعليمات الرئيسية إلى Web Workers
- استخدام المهام الصغيرة لإجراء تغييرات DOM على عدة إطارات.
- استخدِم "المخطّط الزمني" و"أداة تحليل JavaScript" في "أدوات مطوري البرامج في Chrome" لتقييم تأثير JavaScript.
استخدام "requestAnimationFrame
" للتغييرات المرئية
عندما تحدث التغييرات المرئية على الشاشة، فأنت تريد القيام بعملك في الوقت المناسب
في المتصفح، في بداية الإطار مباشرةً. إنّ الطريقة الوحيدة التي يمكنك من خلالها ضمان أن يكون محتوى JavaScript
سيتم تشغيله في بداية الإطار هو استخدام requestAnimationFrame
.
/**
* If run as a requestAnimationFrame callback, this
* will be run at the start of the frame.
*/
function updateScreen(time) {
// Make visual updates here.
}
requestAnimationFrame(updateScreen);
قد تستخدم أُطر العمل أو النماذج setTimeout
أو setInterval
لإجراء تغييرات مرئية، مثل الصور المتحركة.
لكن المشكلة في ذلك تكمن في أنّه سيتم تنفيذ عملية الاستدعاء عند نقطة معيّنة ضمن الإطار، وقد يكون ذلك صحيحًا.
في النهاية، وقد يؤدي ذلك غالبًا إلى التسبب في تفويت إطار ما، مما ينتج عنه إيقاف مؤقت.
![المهلة المحددة التي تؤدي إلى تفويت إطار المتصفح.](https://web.dev/static/articles/optimize-javascript-execution/image/settimeout-causing-brows-6424030c04e02.jpg?authuser=7&hl=ar)
وفي الواقع، اعتاد jQuery استخدام setTimeout
لسلوك animate
. تم تغييرها لاستخدام
requestAnimationFrame
في الإصدار 3.
إذا كنت تستخدم إصدارًا قديمًا من jQuery، يمكنك
تصحيحها لاستخدام requestAnimationFrame
،
وهو أمر يُنصح به بشدة.
تقليل التعقيد أو استخدام Web Workers
وتعمل لغة JavaScript على سلسلة المحادثات الرئيسية في المتصفح، مباشرةً إلى جانب العمليات الحسابية للأنماط والتنسيق وحالات عديدة، الطلاء. إذا تم تشغيل JavaScript لفترة طويلة، ستحظر هذه المهام الأخرى، مما قد يؤدي إلى إغفال الإطارات.
يجب أن تركّز على وقت تشغيل JavaScript ومدة تشغيلها. على سبيل المثال، إذا كنت في مثل التمرير، فمن المفترض أن تتطلع إلى إبقاء جافا سكريبت على المنطقة التي تتراوح بين 3 و4 ملّي ثانية: أي وقت أطول من ذلك وأنت تخاطر باستغراق الكثير من الوقت. في حال عدم النشاط يمكنك تحمل أن تكون أكثر استرخاءً بشأن الوقت المستغرق.
وفي العديد من الحالات، يمكنك نقل أي عمل حاسوبي البحت إلى Web Workers، إذا كان، على سبيل المثال، لا يتطلب الوصول إلى نموذج كائن المستند (DOM). لمعالجة البيانات أو اجتيازها، مثل الفرز أو البحث، غالبًا ما تكون مناسبة لهذا النموذج، مثل التحميل وإنشاء النماذج.
var dataSortWorker = new Worker("sort-worker.js");
dataSortWorker.postMesssage(dataToSort);
// The main thread is now free to continue working on other things...
dataSortWorker.addEventListener('message', function(evt) {
var sortedData = evt.data;
// Update data on screen...
});
هذا النموذج لا يتناسب مع جميع الأعمال: لا يملك عاملو الويب إمكانية الوصول إلى نموذج كائن المستند (DOM). عندما يكون عملك في سلسلة التعليمات الرئيسية، ننصحك باستخدام نهج التجميع، حيث يمكنك تقسيم المهمة الأكبر إلى مهام مصغَّرة، لا يستغرق كل منها وقتًا أطول من بضعة ثوانٍ، وتنفيذها داخل معالِجات requestAnimationFrame
في كل إطار.
هناك عواقب لتجربة المستخدم وواجهة المستخدم لهذا النهج، وستحتاج إلى التأكد من أن المستخدم يعرف أن مهمة تتم معالجتها، إما عن طريق استخدام مؤشر التقدم أو مؤشر النشاط. على أي حال، ستؤدي هذه الطريقة إلى بقاء سلسلة التعليمات الرئيسية لتطبيقك مجانية، ما يساعد في الحفاظ على استجابة التطبيق وتفاعلات المستخدم.
معرفة "ضريبة الإطارات" في JavaScript
عند تقييم إطار عمل أو مكتبة أو تعليمة برمجية خاصة بك، من المهم تقييم تكلفة تشغيل رمز JavaScript على أساس كل إطار على حدة هذا هو له أهمية خاصة عند عمل الرسوم المتحركة بالغة الأهمية مثل الانتقال أو التمرير.
تعد لوحة الأداء في Chrome DevTools أفضل طريقة لقياس تكلفة JavaScript. وعادةً ما تحصل على سجلات منخفضة المستوى مثل ما يلي:
![تسجيل أداء ضمن "أدوات مطوري البرامج في Chrome"](https://web.dev/static/articles/optimize-javascript-execution/image/a-performance-recording-ed012f2de06f6.png?authuser=7&hl=ar)
يوفر القسم الرئيسي مخططًا تفصيليًا لاستدعاءات JavaScript حتى نتمكن من تحليل الدوال التي تم استدعاؤها بالضبط والمدة التي استغرقتها كل منها.
استنادًا إلى هذه المعلومات، يمكنك تقييم تأثير أداء جافا سكريبت على تطبيقك، والبدء في العثور على أي نقاط اتصال وإصلاحها حيث الدوال تستغرق وقتًا طويلاً جدًا لتنفيذها. كما ذكرنا سابقًا، يجب أن تسعى لإزالة لغة JavaScript التي تم إنشاؤها منذ فترة طويلة، أو نقلها إذا لم يكن ذلك ممكنًا إلى عامل الويب لتحرير سلسلة التعليمات الرئيسية لمتابعة مهام أخرى.
راجِع مقالة بدء تحليل أداء وقت التشغيل للتعرّف على كيفية استخدام هذه الميزة. لوحة الأداء.
تجنُّب التحسين الدقيق لرموز JavaScript
قد يكون من الرائع معرفة أنّ المتصفّح يمكنه تنفيذ نسخة واحدة من أي عنصر بشكل أسرع 100 مرة من
شيء آخر، مثل أن طلب offsetTop
لعنصر ما تكون أسرع من الحوسبة
getBoundingClientRect()
، ولكن من الصحيح دائمًا أنك ستستدعي دوال مثل
هذه عدد قليل من المرات لكل إطار، لذلك عادةً ما يكون التركيز على هذا الجانب من
أداء JavaScript. ستقوم عادةً بحفظ كسور من المللي ثانية فقط.
إذا كنت تصنع لعبة أو تطبيقًا مكلفًا من الناحية الحسابية، فأنت على الأرجح استثناء مع هذه الإرشادات، حيث إنك عادةً ما ستُدرج الكثير من العمليات الحاسوبية في إطار واحد، فإن كل شيء يساعد في ذلك.
باختصار، يجب أن تكون حذرًا جدًا من التحسينات الصغيرة لأنها لا ترتبط عادةً نوع التطبيق الذي تقوم بإنشائه.