کدهای مدرن را به مرورگرهای مدرن برای بارگذاری سریعتر صفحه ارائه دهید

حسین جیرده
Houssein Djirdeh

ساخت وب‌سایت‌هایی که در همه مرورگرهای اصلی به خوبی کار کنند، یکی از اصول اصلی یک اکوسیستم وب باز است. با این حال، این به معنای کار اضافی برای اطمینان از پشتیبانی تمام کدی است که می‌نویسید در هر مرورگری که قصد دارید هدف قرار دهید، پشتیبانی می‌شود. اگر می‌خواهید از ویژگی‌های جدید زبان جاوا اسکریپت استفاده کنید، باید این ویژگی‌ها را به فرمت‌های سازگار با نسخه‌های قبلی برای مرورگرهایی که از آنها پشتیبانی نمی‌کنند، تبدیل کنید.

بابل (Babel) پرکاربردترین ابزار برای کامپایل کدی است که حاوی سینتکس جدیدتر به کدی است که مرورگرها و محیط‌های مختلف (مانند Node) می‌توانند آن را درک کنند. این راهنما فرض می‌کند که شما از بابل استفاده می‌کنید، بنابراین اگر قبلاً آن را در برنامه خود وارد نکرده‌اید، باید دستورالعمل‌های راه‌اندازی را دنبال کنید. اگر از وب‌پک به عنوان بسته‌بندی‌کننده ماژول در برنامه خود استفاده می‌کنید، در Build Systems webpack انتخاب کنید.

برای استفاده از Babel جهت transpile کردن فقط مواردی که برای کاربران شما مورد نیاز است، باید:

  1. مشخص کنید که می‌خواهید کدام مرورگرها را هدف قرار دهید.
  2. @babel/preset-env ‎ با مرورگرهای هدف مناسب استفاده کنید.
  3. از <script type="module"> برای جلوگیری از ارسال کد transpile شده به مرورگرهایی که به آن نیازی ندارند، استفاده کنید.

مشخص کنید کدام مرورگرها را می‌خواهید هدف قرار دهید

قبل از اینکه شروع به تغییر نحوه‌ی ترجمه‌ی کد برنامه‌تان کنید، باید مشخص کنید کدام مرورگرها به برنامه‌تان دسترسی دارند. مرورگرهایی را که کاربران شما از آن‌ها استفاده می‌کنند و مرورگرهایی را که قصد دارید هدف قرار دهید، تجزیه و تحلیل کنید تا تصمیمی آگاهانه بگیرید.

از @babel/preset-env استفاده کنید

کد Transpile شده معمولاً منجر به فایلی می‌شود که از نظر اندازه بزرگتر از شکل اصلی خود است. با به حداقل رساندن میزان کامپایلی که انجام می‌دهید، می‌توانید اندازه بسته‌های خود را کاهش دهید تا عملکرد یک صفحه وب را بهبود بخشید.

به جای اینکه افزونه‌های خاصی را برای کامپایل انتخابی ویژگی‌های زبانی خاصی که استفاده می‌کنید، در نظر بگیرید، Babel تعدادی تنظیمات از پیش تعیین‌شده ارائه می‌دهد که افزونه‌ها را با هم ترکیب می‌کند. از @babel/preset-env استفاده کنید تا فقط تبدیل‌ها و چندپرکننده‌های مورد نیاز برای مرورگرهایی که قصد دارید هدف قرار دهید را در نظر بگیرید.

@babel/preset-env را در آرایه‌ی presets در فایل پیکربندی Babel خود، .babelrc ، قرار دهید:

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

با اضافه کردن یک کوئری مناسب به فیلد browsers ، از فیلد targets برای مشخص کردن نسخه‌های مرورگری که می‌خواهید شامل شوند، استفاده کنید. @babel/preset-env با browserslist، یک پیکربندی متن‌باز که بین ابزارهای مختلف برای هدف‌گیری مرورگرها به اشتراک گذاشته شده است، ادغام می‌شود. لیست کاملی از کوئری‌های سازگار در مستندات browserslist موجود است. گزینه دیگر استفاده از یک فایل .browserslistrc برای فهرست کردن محیط‌هایی است که می‌خواهید هدف‌گیری کنید.

مقدار ">0.25%" به Babel می‌گوید که فقط تبدیل‌های لازم برای پشتیبانی از مرورگرهایی که بیش از 0.25% از استفاده جهانی را تشکیل می‌دهند، لحاظ کند. این تضمین می‌کند که بسته شما حاوی کد ترجمه شده غیرضروری برای مرورگرهایی که توسط درصد بسیار کمی از کاربران استفاده می‌شوند، نباشد.

در بیشتر موارد، این رویکرد بهتر از استفاده از پیکربندی زیر است:

  "targets": "last 2 versions"

مقدار "last 2 versions" کد شما را برای دو نسخه آخر هر مرورگر transpile می‌کند، به این معنی که از مرورگرهای منسوخ شده مانند Internet Explorer پشتیبانی می‌شود. اگر انتظار ندارید که از این مرورگرها برای دسترسی به برنامه شما استفاده شود، این می‌تواند بی‌جهت اندازه بسته شما را افزایش دهد.

در نهایت، شما باید ترکیب مناسبی از کوئری‌ها را انتخاب کنید تا فقط مرورگرهایی که با نیازهای شما مطابقت دارند را هدف قرار دهید.

رفع اشکالات مدرن را فعال کنید

@babel/preset-env چندین ویژگی نحوی جاوا اسکریپت را در مجموعه‌هایی گروه‌بندی می‌کند، آنها را بر اساس مرورگرهای هدف مشخص شده فعال و غیرفعال می‌کند. اگرچه این روش به خوبی کار می‌کند، اما وقتی مرورگر هدف حاوی اشکالی با تنها یک ویژگی باشد، کل مجموعه ویژگی‌های نحوی تغییر شکل می‌یابد. این اغلب منجر به کد تغییر شکل یافته بیشتری نسبت به مقدار لازم می‌شود.

گزینه رفع اشکالات در @babel/preset-env که در ابتدا به عنوان یک پیش‌تنظیم جداگانه توسعه داده شده بود، این مشکل را با تبدیل سینتکس مدرنی که در برخی مرورگرها خراب است به نزدیک‌ترین سینتکس معادل که در آن مرورگرها خراب نیست، حل می‌کند. نتیجه، کد مدرن تقریباً یکسانی با چند تغییر کوچک در سینتکس است که سازگاری در همه مرورگرهای هدف را تضمین می‌کند. برای استفاده از این بهینه‌سازی، مطمئن شوید که @babel/preset-env 7.10 یا بالاتر را نصب کرده‌اید، سپس ویژگی bugfixes را روی true تنظیم کنید:

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

در Babel 8، گزینه bugfixes به طور پیش‌فرض فعال خواهد بود.

از <script type="module"> استفاده کنید

ماژول‌های جاوا اسکریپت یا ماژول‌های ES، یک ویژگی نسبتاً جدید هستند که در همه مرورگرهای اصلی پشتیبانی می‌شوند. می‌توانید از ماژول‌ها برای ایجاد اسکریپت‌هایی استفاده کنید که می‌توانند از ماژول‌های دیگر وارد و صادر شوند، اما می‌توانید از آنها با @babel/preset-env نیز استفاده کنید تا فقط مرورگرهایی را هدف قرار دهید که از آنها پشتیبانی می‌کنند.

به جای جستجوی نسخه‌های خاص مرورگر یا سهم بازار، مشخص کردن "esmodules" : true در فیلد targets فایل .babelrc خود در نظر بگیرید.

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

بسیاری از ویژگی‌های جدیدتر ECMAScript که با Babel کامپایل شده‌اند، در محیط‌هایی که از ماژول‌های جاوا اسکریپت پشتیبانی می‌کنند، پشتیبانی می‌شوند. بنابراین با انجام این کار، فرآیند اطمینان از اینکه فقط کد ترجمه شده برای مرورگرهایی که واقعاً به آن نیاز دارند استفاده می‌شود، ساده می‌شود.

مرورگرهایی که از ماژول‌ها پشتیبانی می‌کنند، اسکریپت‌هایی که دارای ویژگی nomodule هستند را نادیده می‌گیرند. برعکس، مرورگرهایی که از ماژول‌ها پشتیبانی نمی‌کنند، عناصر اسکریپت با type="module" را نادیده می‌گیرند. این بدان معناست که می‌توانید علاوه بر یک ماژول کامپایل شده، یک fallback نیز اضافه کنید.

در حالت ایده‌آل، دو اسکریپت نسخه یک برنامه به این صورت درج می‌شوند:

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

مرورگرهایی که از ماژول‌ها پشتیبانی می‌کنند، main.mjs را دریافت و اجرا می‌کنند و compiled.js نادیده می‌گیرند. مرورگرهایی که از ماژول پشتیبانی نمی‌کنند، برعکس عمل می‌کنند.

اگر از وب‌پک استفاده می‌کنید، می‌توانید اهداف متفاوتی را در پیکربندی‌های خود برای دو نسخه جداگانه از برنامه خود تعیین کنید:

  • نسخه‌ای فقط برای مرورگرهایی که از ماژول‌ها پشتیبانی می‌کنند.
  • نسخه‌ای که شامل یک اسکریپت کامپایل‌شده است که در هر مرورگر قدیمی کار می‌کند. این نسخه حجم فایل بیشتری دارد، زیرا transpilation باید از طیف وسیع‌تری از مرورگرها پشتیبانی کند.

با تشکر از کانر کلارک و جیسون میلر برای نقدهایشان.