تحسين بدء تشغيل JavaScript

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

الشبكة

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

عندما يطلب المتصفّح موردًا، يجب جلب هذا المورد ثم إلغاء ضغطه. في حالة الموارد مثل JavaScript، يجب تحليلها وتجميعها قبل التنفيذ.

قد يشكّل ذلك مشكلة، لأنّ نوع الاتصال الفعلي بالشبكة الذي يستخدمه المستخدم قد لا يكون في الواقع شبكة الجيل الثالث أو شبكة الجيل الرابع أو شبكة Wi-Fi. يمكنك الاتصال بشبكة Wi-Fi في مقهى ولكنك متصل بنقطة اتصال خلوية بسرعات 2G.

يمكنك تقليل تكلفة نقل JavaScript عبر الشبكة من خلال:

  • إرسال الرمز الذي يحتاجه المستخدم فقط:
  • إزالة البيانات غير الضرورية
  • الضغط
    • استخدِم على الأقل gzip لضغط الموارد المستنِدة إلى النص.
    • ننصحك باستخدام Brotli ~q11. يتفوّق Brotli على gzip في نسبة الضغط. وقد ساعدت هذه الخوارزمية شركة CertSimple في توفير %17 من حجم وحدات بايت JavaScript المضغوطة، كما ساعدت شركة LinkedIn في توفير %4 من أوقات التحميل.
  • إزالة الرموز غير المستخدَمة
  • تخزين الرمز مؤقتًا لتقليل رحلات الشبكة
    • استخدِم التخزين المؤقت لبروتوكول HTTP لضمان تخزين المتصفّحات للردود مؤقتًا بشكل فعّال. حدِّد العمر الأمثل للنصوص البرمجية (max-age) وقدِّم الرموز المميزة للتحقق (ETag) لتجنُّب نقل وحدات البايت التي لم يتم تغييرها.
    • يمكن أن يؤدي التخزين المؤقت لمشغّل الخدمات إلى جعل شبكة تطبيقك مرنة ومنحك إمكانية الوصول السريع إلى ميزات مثل ذاكرة التخزين المؤقت للرموز البرمجية في V8.
    • استخدِم التخزين المؤقت الطويل الأجل لتجنُّب إعادة جلب الموارد التي لم تتغيّر. في حال استخدام Webpack، يُرجى الاطّلاع على تجزئة اسم الملف.

التحليل/التجميع

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

ALT_TEXT_HERE

تعرض علامتا التبويب "من الأسفل إلى الأعلى" (Bottom-Up) و"شجرة الاستدعاء" (Call Tree) أوقات التحليل/التجميع الدقيقة:

ALT_TEXT_HERE
لوحة "الأداء" في "أدوات مطوّري البرامج في Chrome" > من الأسفل إلى الأعلى. عند تفعيل ميزة "إحصاءات طلبات وقت التشغيل" في محرّك V8، يمكننا الاطّلاع على الوقت المستغرَق في مراحل مثل "التحليل" و"الترجمة".

ولكن، ما أهمية ذلك؟

ALT_TEXT_HERE

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

"بايت ببايت، تُعدّ معالجة JavaScript أكثر تكلفة للمتصفّح من معالجة صورة أو خط ويب بالحجم نفسه" - توم ديل

مقارنةً بلغة JavaScript، هناك العديد من التكاليف المرتبطة بمعالجة الصور ذات الحجم المماثل (لا يزال يتعين فك ترميزها!) ولكن في المتوسط على الأجهزة الجوّالة، من المرجح أن تؤثر لغة JS سلبًا في تفاعلية الصفحة.

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

عندما نتحدث عن بطء التحليل والتجميع، يكون السياق مهمًا، فنحن نتحدث هنا عن الهواتف الجوّالة المتوسطة. قد يمتلك المستخدمون العاديون هواتف ذات وحدات معالجة مركزية ووحدات معالجة رسومات بطيئة، ولا تحتوي على ذاكرة تخزين مؤقت L2/L3، وقد تكون مقيدة بالذاكرة.

لا تتطابق إمكانات الشبكة وإمكانات الجهاز دائمًا. فالمستخدم الذي لديه اتصال رائع عبر الألياف الضوئية لا يملك بالضرورة أفضل وحدة معالجة مركزية لتحليل وتقييم JavaScript المرسلة إلى جهازه. وينطبق هذا أيضًا على العكس… اتصال شبكة سيئ، ولكن وحدة معالجة مركزية فائقة السرعة. — "كريستوفر باكستر"، LinkedIn

في ما يلي، يمكننا الاطّلاع على تكلفة تحليل ملف JavaScript (بسيط) غير مضغوط بحجم 1 ميغابايت تقريبًا على أجهزة منخفضة وعالية المواصفات. هناك فرق يتراوح بين الضعفين و5 أضعاف في الوقت المستغرَق لتحليل/تجميع الرموز البرمجية بين أسرع الهواتف في السوق والهواتف العادية.

ALT_TEXT_HERE
يُبرز هذا الرسم البياني أوقات التحليل لحزمة JavaScript بحجم 1 ميغابايت (حوالي 250 كيلوبايت بتنسيق gzipped) على أجهزة الكمبيوتر المكتبي والأجهزة الجوّالة من فئات مختلفة. عند النظر في تكلفة التحليل، يجب مراعاة الأرقام غير المضغوطة، على سبيل المثال، يتم فك ضغط ملف JS المضغوط بحجم 250 كيلوبايت تقريبًا إلى رمز بحجم 1 ميغابايت تقريبًا.

ماذا عن موقع إلكتروني حقيقي، مثل CNN.com؟

على هاتف iPhone 8 المتطوّر، يستغرق تحليل/تجميع ملفات JS في CNN حوالي 4 ثوانٍ مقارنةً بحوالي 13 ثانية على هاتف متوسط (Moto G4). يمكن أن يؤثر ذلك بشكل كبير على مدى سرعة تفاعل المستخدم بشكل كامل مع هذا الموقع.

ALT_TEXT_HERE
نرى أعلاه أوقات التحليل التي تقارن أداء شريحة A11 Bionic من Apple مع Snapdragon 617 في أجهزة Android المتوسطة.

يبرز ذلك أهمية الاختبار على أجهزة متوسطة الإمكانيات (مثل Moto G4) بدلاً من الهاتف الذي قد يكون في جيبك. ومع ذلك، السياق مهم: يجب تحسين المحتوى ليناسب الجهاز وظروف الشبكة لدى المستخدمين.

ALT_TEXT_HERE
يمكن أن توفّر "إحصاءات Google" إحصاءات حول فئات الأجهزة الجوّالة التي يستخدمها المستخدمون الحقيقيون للوصول إلى موقعك الإلكتروني. ويمكن أن يوفّر ذلك فرصًا لفهم القيود الحقيقية لوحدة المعالجة المركزية (CPU) أو وحدة معالجة الرسومات (GPU) التي تعمل بها.

هل نرسل الكثير من JavaScript؟ ربما :)

باستخدام HTTP Archive (أهم المواقع الإلكترونية التي يبلغ عددها 500 ألف تقريبًا) لتحليل حالة JavaScript على الأجهزة الجوّالة، يمكننا أن نرى أنّ %50 من المواقع الإلكترونية تستغرق أكثر من 14 ثانية لتصبح تفاعلية. تستغرق هذه المواقع ما يصل إلى 4 ثوانٍ في تحليل لغة JavaScript وتجميعها.

ALT_TEXT_HERE

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

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

وقت التنفيذ

لا يقتصر الأمر على التحليل والتجميع اللذين يمكن أن يكون لهما تكلفة. تنفيذ JavaScript (تشغيل الرمز بعد تحليله/تجميعه) هو إحدى العمليات التي يجب إجراؤها على سلسلة التعليمات الرئيسية. يمكن أن تؤدي أوقات التنفيذ الطويلة أيضًا إلى تأخير تفاعل المستخدم مع موقعك الإلكتروني.

ALT_TEXT_HERE

إذا استغرق تنفيذ النص البرمجي أكثر من 50 ملي ثانية، يتأخر وقت التفاعل بمقدار الوقت الكامل الذي يستغرقه تنزيل ملف JS وتجميعه وتنفيذه. - أليكس راسل

لمعالجة هذه المشكلة، من الأفضل تقسيم JavaScript إلى أجزاء صغيرة لتجنُّب قفل سلسلة التعليمات الرئيسية. استكشِف ما إذا كان بإمكانك تقليل مقدار العمل الذي يتم إنجازه أثناء التنفيذ.

التكاليف الأخرى

يمكن أن تؤثر لغة JavaScript في أداء الصفحة بطرق أخرى:

  • الذاكرة: قد تظهر الصفحات بشكل متقطّع أو تتوقف مؤقتًا بشكل متكرر بسبب GC (جمع المهملات). عندما يستعيد المتصفّح الذاكرة، يتم إيقاف تنفيذ JS مؤقتًا، لذا فإنّ المتصفّح الذي يجمع البيانات غير الصالحة بشكل متكرر يمكن أن يوقف التنفيذ مؤقتًا بمعدل أكبر مما نرغب فيه. تجنَّب تسرُّب الذاكرة والتوقُّفات المتكرّرة لجمع المهملات للحفاظ على الصفحات خالية من التقطُّع.
  • أثناء وقت التشغيل، يمكن أن يحظر رمز JavaScript الطويل سلسلة التعليمات الرئيسية، ما يؤدي إلى عدم استجابة الصفحات. يمكن أن يؤدي تقسيم العمل إلى أجزاء أصغر (باستخدام requestAnimationFrame() أو requestIdleCallback() للجدولة) إلى تقليل مشاكل الاستجابة، ما يساعد في تحسين مدى استجابة الصفحة لتفاعلات المستخدم (INP).

أنماط لخفض تكلفة عرض JavaScript

عند محاولة تقليل أوقات التحليل/الترجمة ونقل الشبكة لـ JavaScript، هناك أنماط يمكن أن تساعدك، مثل التقسيم المستند إلى المسار أو PRPL.

PRPL

‫PRPL (الدفع والعرض والتخزين المؤقت المسبق والتحميل الكسول) هو نمط يحسّن التفاعل من خلال تقسيم الرموز البرمجية والتخزين المؤقت بشكل مكثّف:

ALT_TEXT_HERE

لنلقِ نظرة على التأثير الذي يمكن أن يحدثه.

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

ALT_TEXT_HERE

يستخدم موقع Wego نمط PRPL، ويحافظ على وقت تحليل منخفض لمساراته، ما يتيح له التفاعل بسرعة كبيرة. وقد اعتمدت العديد من المواقع الإلكترونية الأخرى المذكورة أعلاه ميزانيات قائمة على الأداء وتقسيم الرموز البرمجية لمحاولة خفض تكاليف JS.

التمهيد التدريجي

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

يُرجى توخي الحذر، لأنّ هذا الإجراء له تكاليفه الخاصة. أولاً، يتم إرسال استجابة HTML أكبر بشكل عام، ما قد يؤدي إلى تأخير التفاعل، وثانيًا، قد يواجه المستخدم تجربة غير مألوفة حيث لا يمكنه التفاعل مع نصف المحتوى حتى ينتهي JavaScript من المعالجة.

قد يكون "التشغيل التدريجي" (Progressive Bootstrapping) نهجًا أفضل. أرسِل صفحة تتضمّن الحد الأدنى من الوظائف (تتكوّن فقط من HTML/JS/CSS اللازمة للمسار الحالي). ومع وصول المزيد من الموارد، يمكن للتطبيق تحميل المزيد من الميزات وإتاحتها.

ALT_TEXT_HERE
Progressive Bootstrapping بقلم "بول لويس"

إنّ تحميل الرموز البرمجية بما يتناسب مع المحتوى المعروض هو الحل الأمثل. ويُعدّ PRPL و"التشغيل التدريجي" من الأنماط التي يمكن أن تساعد في تحقيق ذلك.

الاستنتاجات

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

حقّقت الفِرق نجاحًا من خلال اعتماد ميزانيات صارمة قائمة على الأداء للحفاظ على انخفاض أوقات نقل JavaScript وتحليلها/تجميعها. يمكنك الاطّلاع على مقالة "هل يمكنك تحمّل التكلفة؟: Real-world Web Performance Budgets" للحصول على إرشادات حول الميزانيات للأجهزة الجوّالة.

ALT_TEXT_HERE
من المفيد التفكير في مقدار "المساحة" التي تتركها لنا قراراتنا المعمارية في JavaScript لتنفيذ منطق التطبيق.

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

مزيد من المعلومات