عرض الرمز الحديث في المتصفِّحات الحديثة لتحميل الصفحات بشكلٍ أسرع

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

Babel هي الأداة الأكثر استخدامًا لتجميع الرمز البرمجي الذي يحتوي على بنية أحدث إلى رمز يمكن للمتصفّحات والبيئات المختلفة (مثل Node) فهمه. يفترض هذا الدليل أنك تستخدم Babel، لذلك يجب عليك اتباع تعليمات الإعداد لتضمينه في التطبيق إذا لم تكن قد استخدمته من قبل. اختَر webpack في Build Systems إذا كنت تستخدم حزمة الويب كحزمة وحدات في تطبيقك.

لاستخدام Babel فقط لنقل ما هو مطلوب للمستخدمين، يجب:

  1. حدِّد المتصفّحات التي تريد استهدافها.
  2. استخدِم @babel/preset-env مع استهدافات المتصفّح المناسبة.
  3. استخدِم <script type="module"> لإيقاف إرسال الرمز الذي تم تحويله إلى متصفِّحات لا تحتاج إليه.

تحديد المتصفّحات التي تريد استهدافها

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

استخدِم @babel/preset-env.

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

بدلاً من تضمين مكونات إضافية محددة لتجميع ميزات لغة معينة بشكل انتقائي، يوفر Babel عددًا من الإعدادات المسبقة التي تجمع المكونات الإضافية معًا. استخدِم @babel/preset-env لتضمين عمليات التحويل ورموز polyfill المطلوبة في المتصفّحات التي تريد استهدافها فقط.

أدرِج @babel/preset-env ضمن مصفوفة presets في ملف إعدادات Babel، .babelrc:

{
 "presets": [
   [
     "@babel/preset-env",
     {
       "targets": ">0.25%"
     }
   ]
 ]
}

استخدِم حقل targets لتحديد إصدارات المتصفّح التي تريد تضمينها عن طريق إضافة طلب بحث مناسب إلى حقل browsers. تتكامل @babel/preset-env مع قائمة المتصفحات، وهي إعدادات مفتوحة المصدر تتم مشاركتها بين أدوات مختلفة لاستهداف المتصفحات. تتوفر قائمة كاملة بطلبات البحث المتوافقة في مستندات قائمة المتصفحات. ويمكنك أيضًا استخدام ملف .browserslistrc لإدراج البيئات التي تريد استهدافها.

وتطلب القيمة ">0.25%" من Babel تضمين التحويلات اللازمة فقط للتوافق مع المتصفحات التي تشكّل أكثر من 0.25% من الاستخدام العام. يضمن ذلك عدم احتواء الحزمة على رمز غير ضروري تم نقله في المتصفحات التي يستخدمها عدد قليل جدًا من المستخدمين.

وفي معظم الحالات، يُعدّ هذا الأسلوب أفضل من استخدام الإعدادات التالية:

  "targets": "last 2 versions"

تنقل القيمة "last 2 versions" الرمز لآخر إصدارين من كل متصفح، ما يعني أنه يتم توفير الدعم للمتصفّحات التي تم إيقافها نهائيًا مثل Internet Explorer. قد يؤدي ذلك إلى زيادة حجم الحزمة بشكل غير ضروري إذا لم تكن تتوقع أن يتم استخدام هذه المتصفحات للوصول إلى التطبيق.

في النهاية، يجب اختيار مجموعة طلبات البحث المناسبة لاستهداف المتصفّحات التي تناسب احتياجاتك فقط.

تفعيل إصلاحات الأخطاء الحديثة

تجمِّع @babel/preset-env ميزات متعددة لبنية JavaScript في مجموعات ويتم تفعيلها/إيقافها استنادًا إلى المتصفّحات المستهدَفة المحدّدة. على الرغم من أن هذا يعمل بشكل جيد، إلا أنه يتم تحويل مجموعة كاملة من ميزات بناء الجملة عندما يحتوي المتصفح المستهدف على خطأ في ميزة واحدة فقط. وغالبًا ما ينتج عن ذلك تعليمات برمجية محوّلة أكثر مما هو ضروري.

يعمل خيار إصلاحات الأخطاء في @babel/preset-env، والذي تم تطويره في الأصل على إعداد مسبق منفصل، على حلّ هذه المشكلة من خلال تحويل البنية الحديثة المعطلة في بعض المتصفّحات إلى أقرب بنية مكافئة غير معطّلة في هذه المتصفّحات. والنتيجة هي كود حديث متطابق تقريبًا مع بعض التعديلات الصغيرة في بناء الجملة والتي تضمن التوافق في جميع المتصفحات المستهدفة. لاستخدام ميزة التحسين هذه، تأكَّد من تثبيت الإصدار 7.10 من نظام التشغيل @babel/preset-env أو إصدار أحدث، ثم اضبط السمة bugfixes على true:

{
 "presets": [
   [
     "@babel/preset-env",
     {
       "bugfixes": true
     }
   ]
 ]
}

في Babel 8، سيتم تفعيل خيار bugfixes تلقائيًا.

استخدام <script type="module">

تُعد وحدات JavaScript أو وحدات ES ميزة جديدة نسبيًا متوافقة مع جميع المتصفحات الرئيسية. يمكنك استخدام الوحدات لإنشاء نصوص برمجية يمكن استيرادها وتصديرها من وحدات أخرى، ولكن يمكنك أيضًا استخدامها مع @babel/preset-env لاستهداف المتصفحات المتوافقة معها فقط.

وبدلاً من طلب البحث عن إصدارات معيّنة من المتصفّح أو حصة السوق، ننصحك بتحديد "esmodules" : true ضمن حقل targets في ملف .babelrc.

{
   "presets":[
      [
         "@babel/preset-env",
         {
            "targets":{
               "esmodules": true
            }
         }
      ]
   ]
}

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

تتجاهل المتصفّحات التي تتيح الوحدات النصوص البرمجية التي تحتوي على السمة nomodule. في المقابل، تتجاهل المتصفّحات التي لا تتيح الوحدات النمطية لعناصر النص البرمجي التي تتضمّن type="module". وهذا يعني أنه يمكنك تضمين وحدة وكذلك عنصر احتياطي مجمع.

من الناحية المثالية، يتم تضمين النصين البرمجيين لإصدار التطبيق على النحو التالي:

  <script type="module" src="main.mjs"></script>
  <script nomodule src="compiled.js" defer></script>

المتصفّحات التي تتيح الوحدات تجلب main.mjs وتنفّذها وتتجاهل compiled.js. العكس هو الصحيح في المتصفحات التي لا تتيح استخدام الوحدات.

في حال استخدام حزمة الويب، يمكنك تحديد أهداف مختلفة في الإعدادات لإصدارَين منفصلَين من تطبيقك:

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

نشكر "كونور كلارك" و"جيسون ميلر" على مراجعاتهما.