הצגת קוד מודרני בדפדפנים מודרניים לטעינת דפים מהירה יותר

בניית אתרים שפועלים היטב בכל הדפדפנים המובילים היא עיקרון הליבה של סביבת אינטרנט פתוחה. עם זאת, המשמעות היא שתצטרכו להשקיע עבודה נוספת כדי לוודא שכל הקוד שאתם כותבים נתמך בכל דפדפן שאתם מתכננים לטרגט. כדי להשתמש בתכונות החדשות של שפת JavaScript, צריך להמיר את התכונות האלה לפורמטים תואמים לאחור לדפדפנים שעדיין לא תומכים בהם.

Babel הוא הכלי הנפוץ ביותר להרכבת קוד שמכיל תחביר חדש יותר לקוד, שדפדפנים וסביבות שונים יכולים להבין. במדריך הזה יוצאים מנקודת הנחה שאתם משתמשים ב-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%"
     }
   ]
 ]
}

כדי לציין אילו גרסאות דפדפן רוצים לכלול, מוסיפים שאילתת מתאימה לשדה 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 מקבצת כמה תכונות של תחביר JavaScript לאוספים ומפעילה או משביתה אותן בהתאם לדפדפני היעד שצוינו. השיטה הזו עובדת כמו שצריך, אבל אוסף שלם של תכונות תחביר עובר טרנספורמציה כשדפדפן מטורגט מכיל באג עם תכונה אחת בלבד. לרוב, התוצאה היא קוד שהועבר יותר טרנספורמציות ממה שנחוץ.

האפשרות לתיקוני באגים ב-@babel/preset-env, שפותחה במקור כהגדרה קבועה מראש נפרדת, פותרת את הבעיה על ידי המרת תחביר מודרני שנקטע בדפדפנים מסוימים, לתחביר המקביל הקרוב ביותר שאינו שבור בדפדפנים האלה. התוצאה היא קוד מודרני כמעט זהה, עם כמה שינויים קטנים בתחביר שמבטיחים תאימות בכל דפדפני היעד. כדי להשתמש באופטימיזציה הזו, צריך לוודא ש-@babel/preset-env מותקן בגרסה 7.10 ואילך, ולאחר מכן להגדיר את המאפיין 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
            }
         }
      ]
   ]
}

כבר יש תמיכה בסביבות שתומכות במודולים של JavaScript בהרבה מהתכונות החדשות יותר של ECMAScript שעבר עיבוד באמצעות Babel. כך תוכלו לפשט את תהליך וידוא שייעשה שימוש רק בקוד שעבר שינוי בדפדפנים שבאמת צריכים אותו.

דפדפנים שתומכים במודולים מתעלמים מסקריפטים עם המאפיין nomodule. לעומת זאת, דפדפנים שלא תומכים במודולים מתעלמים מרכיבי סקריפט עם הערך type="module". פירוש הדבר הוא שאפשר לכלול מודול וגם חלופה מתומצתת.

באופן אידיאלי, שני הסקריפטים של הגרסאות של האפליקציה כלולים כך:

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

בדפדפנים שתומכים במודולים, מתבצע אחזור והפעלה של main.mjs והתעלמות מ-compiled.js. בדפדפנים שלא תומכים במודולים, ההתנהגות היא הפוכה.

אם אתם משתמשים ב-webpack, אפשר להגדיר יעדים שונים בהגדרות האישיות לשתי גרסאות נפרדות של האפליקציה:

  • גרסה רק לדפדפנים שתומכים במודולים.
  • גרסה שכוללת סקריפט שנאסף, שפועל בכל דפדפן מדור קודם. גודל הקובץ גדול יותר, כי התרגום צריך לתמוך במגוון רחב יותר של דפדפנים.

תודה לקונור קלרק ולג'ייסון מילר (Jason Miller).