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

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

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

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

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

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

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

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

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

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

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

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

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

تُطلب من Babel من خلال القيمة ">0.25%" تضمين عمليات التحويل اللازمة فقط لتتوافق مع المتصفّحات التي تشكّل أكثر من% 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. أمّا المتصفحات التي لا تتوافق مع الوحدات، فهي تفعل العكس.

إذا كنت تستخدم webpack، يمكنك ضبط استهدافات مختلفة في عمليات الضبط لإصدارَين منفصلَين من تطبيقك:

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

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