Search

כיצד לעכב (defer) פריסת Javascript ולשפר את זמן הטעינה?

אני נתקל לא מעט בשאלה כיצד לעכב פריסת Javascript באתרי וורדפרס (Defer Loading of Javascript). הסיבה המרכזית שמעוניינים לבצע זאת היא בכדי לשפר את מהירות האתר שלכם ולגרום לכך שהתוכן יוצג עוד לפני טעינת הסקריפטים.

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

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

במאמר זה אתן שתי דרכים מומלצות בכדי לעכב פריסת javascript באתר הוורדפרס בכדי לשפר את מהירות האתר. כמובן שרבים מתוספי הקאש (זיכרון מטמון) כגון Wp-Rocket וכדומה מאפשרים לבצע זאת ללא התערבות בקוד, כך שאם אתם משתמשים באלו אין צורך שתעשו דבר מבחינה זו.

מדוע יש לעכב פריסת Javascript?

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

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

הרעיון הוא להציג לגולש קודם כל את הטקסט (שברוב המקרים זה התוכן שמעניין אותו) ולעכב את טעינת הסקריפטים עד לאחר שתוכן זה נטען. אם תבדקו את האתר שלכם בכלים כגון Pingdom, GTmetrix or Google Page Speed Insights סביר להניח כי תקבלו אזהרה כגון "Defer loading of javascript״ או משהו בסגנון של ״Remove Render-Blocking JavaScript״. 

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

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

defer-vs-async-map

 

יש להסתכל על הדיאגרמות משמאל לימין!

ברירת מחדל <script>

הדפדפן יבצע פריסה ל html עד שיתקל בסקריפט, בנקודה זו הפריסה תעצר ותתבצע קריאה לסקריפט (הורדה של הסקריפט במקרה והוא חיצוני). לאחר מכן הסקריפט ירוץ ורק אז הדפדפן ימשיך בפריסת ה html.

defer-vs-async

<script async>

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

defer-vs-async

<script defer>

הדפדפן יוריד את הסקריפט תוך כדי שהוא מבצע פריסה ל html ויריץ את הסקריפט רק לאחר שהפריסה הסתיימה. האופציה defer מבטיחה שהסקריפטים באתר שלכם ירוצו בסדר שהם מופיעים ב document.

script-defer

כיצד לעכב פריסת Javascript?

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

1. לעכב את טעינת כל הסקריפטים חוץ מ jQuery

זוהי הדרך שאני ממליץ עליה ומשתמש בה, במידה ותוסיפו את הסקריפט הבא לקובץ functions.php, לכל קריאות ה javascript באתר למעט הקריאה ל jquery.min.js יתווסף defer:

/* defer all js except jquery.min.js */
if ( !is_admin() ) {
    function defer_parsing_of_js ( $url ) {
        if ( FALSE === strpos( $url, '.js' ) ) return $url;
        if ( strpos( $url, 'jquery.min.js' ) ) return $url;

        // return "$url' defer ";
        return "$url' defer onload='";
    }
}
if ( !is_admin() ) {
    add_filter( 'clean_url', 'defer_parsing_of_js', 11, 1 );
}

שימו לב לשם הקובץ של jQuery שהתבנית שלכם טוענת, לפעמים הוא פשוט נקרא jquery.js אז שנו את השורה בהתאם.

הקוד המופיע מעלה יוודא כי כל הסקריפטים יטענו רק לאחר סיום הפריסה של ה html על ידי הדפדפן. אם תתנו מבט בקוד מקור של האתר שלכם, תבחינו כי המילה defer התווספה לכל אחד מהסקריפטים למעט jquery.min.js:

לעכב-פריסת-javascript-באתר-וורדפרס-מהירות
במידה ואתם מעוניינים לבצע טעינה אסינכרונית בדרך זו, שנו את המילה defer ל async בשורה מספר 10.

הצטרפו לרשימת התפוצה!

2. לעכב את טעינת הסקריפטים לפי ה handle

עם שחרור וורדפרס גירסה 4.1 הוצג פילטר חדש המספק דרך פשוטה יחסית להוסיף defer או async לסקריפטים באתר הוורדפרס שלכם. הפילטר הינו script_loader_tag והשימוש בפילטר זה מתבצע על ידי הקוד הבא:

function add_defer_attribute($tag, $handle) {
    if ( 'my-js-handle' !== $handle )
        return $tag;
    return str_replace( ' src', ' defer src', $tag );
}
add_filter('script_loader_tag', 'add_defer_attribute', 10, 2);

אתם נדרשים לשנות את ה handle בשורה 2 אשר (אם ביצעתם enqueue כראוי לסקריפט) יהיה הפרמטר הראשון ברישום של אותו סקריפט:

wp_register_script('my-js-handle', $src, $deps, $ver, $in_footer);

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

ומה אם אתם מעוניינים לעכב את פריסת ה js ביותר מסקריפט אחד?

על מנת לעכב מספר סקריפטים ע״י שימוש בדרך זו אנו צריכים ליצור מערך, לבצע לולאה על אותו מערך ולהוסיף defer לכל אחד מהסקריפטים. הוסיפו את הקוד הבא לקובץ functions.php והוסיפו את ה handles שלכם בשורה 2:

function add_defer_attribute($tag, $handle) {
   $scripts_to_defer = array('my-js-handle', 'another-handle');
   foreach($scripts_to_defer as $defer_script) {
      if ($defer_script !== $handle) return $tag;
      return str_replace(' src', ' defer src', $tag);
   }
   return $tag;
}
add_filter('script_loader_tag', 'add_defer_attribute', 10, 2);

לסיכום

במדריך זה ראינו את שתי הדרכים המומלצות לעכב פריסת javascript באתרי וורדפרס והסברנו על ההבדלים בין async & defer. תהליך פשוט זה ישדרג את מהירות אתר הוורדפרס שלכם בצורה משמעותית.

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

אם יש לכם דרכים נוספות לבצע זאת שתפו איתנו! כך או כך, הערות, תגובות והצעות יתקבלו בברכה 🙂

רועי יוסף
רועי יוסף

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

40 תגובות...
  • Avatar photo רמי 18 יולי 2016, 0:59

    אחלה טיפ!

  • Avatar photo מתן 18 יולי 2016, 10:26

    מעולה, תודה.

  • Avatar photo חתול 18 יולי 2016, 12:52

    ניסיתי אצלי באתר ו־jquery לא נטען כי השם שלו הוא jquery.js ולא jquery.min.js. ערכתי את הקוד בהתאם ואז הוא עובד יופי.
    שווה לכתוב תוסף עם הקוד הזה.

    • Avatar photo רועי יוסף 18 יולי 2016, 12:57

      מצויין 🙂 רצוי שתטען את jQuery לאחר שעבר מיניפיקציה…

  • Avatar photo Rob 21 יולי 2016, 9:05

    יכול להיות מצב שהקוד הראשון דווקא גורם להאטה של האתר?

    • Avatar photo רועי יוסף 21 יולי 2016, 13:55

      לא. אלא אם הוא גורם לשגיאות JS באתר שלך…

      • Avatar photo Rob 24 יולי 2016, 8:50

        תודה, את השגיאות צריך לבדוק ב-console ?
        איזה שגיאות יכולות להיות?

        • Avatar photo רועי יוסף 24 יולי 2016, 18:03

          לבדוק שגיאות כלשהן הקשורות ל Javascript ב developer tools של הדפדפן..

          • Avatar photo Rob 25 יולי 2016, 8:40

            תודה, אני אנסה את זה

  • Avatar photo Rob 7 אוגוסט 2016, 14:13

    הקוד הזה יכול להשפיע על סליידרים של slider revolution ?
    שמתי את הקוד והסליידר נעלם, אחרי שהורדתי את הקוד הוא חזר.
    יש דרך להכניס את הקוד בלי שהוא יפגע בסליידר?

    • Avatar photo חתול 7 אוגוסט 2016, 14:17

      לבדוק מה התסריט שמריץ את הסליידר ולהוסיף אותו לחריגים יחד עם jquery.

  • Avatar photo רועי יוסף 7 אוגוסט 2016, 15:43

    חתול צודק.. נסה את הקוד הבא:

    /* defer all js except jquery.min.js & revolution slider */
    if ( !is_admin() ) {
        function defer_parsing_of_js ( $url ) {
            if ( FALSE === strpos( $url, '.js' ) ) return $url;
            if ( strpos( $url, 'jquery.min.js' ) ) return $url;
            if ( strpos( $url, 'jquery.themepunch.tools.min.js' ) ) return $url;
            if ( strpos( $url, 'jquery.themepunch.revolution.min.js' ) ) return $url;
    
            return "$url' defer onload='";
        }
    }
    if ( !is_admin() ) {
        add_filter( 'clean_url', 'defer_parsing_of_js', 11, 1 );
    }
    • Avatar photo Rob 8 אוגוסט 2016, 13:56

      תודה.
      ההסברים האלה מאוד עוזרים, תוכל לעשות עמוד שמרכז את כולם ביחד?

    • Avatar photo Rob 9 אוגוסט 2016, 15:18

      העתקתי את הקוד כמו שפרסמת וזה עדיין הוריד את הסליידר.
      אחרי שהסרתי אותו אז הסליידר חזר, מה עשיתי לא נכון?

      • Avatar photo רועי יוסף 11 אוקטובר 2016, 14:47

        רוב, עדכנתי את המאמר, בחלקו האחרון הוספתי הסבר כיצד לבצע defer לבעלי Revolution Slider… בהצלחה 🙂

        • Avatar photo רוב 13 אוקטובר 2016, 8:31

          תודה

        • Avatar photo רוב 9 נובמבר 2016, 11:07

          נראה לי שיש שגיאה בקוד של ה-Revolution Slider.
          בתגובות כתוב jquery.themepunch.tools.min.js ובדוגמה למעלה כתוב jquery.themepunch.tools.min אני מתאר לעצמי שצריך את ה-.min.js?

          • Avatar photo רועי יוסף 12 נובמבר 2016, 15:42

            אני חושב שזה לא ישנה במקרה הזה.. שניהם יעבדו..

          • Avatar photo רוב 13 נובמבר 2016, 8:34

            כנראה שאני עושה משהו לא נכון, כי הסליידר עדיין נעלם לי למורת שאני מעתיק את הקוד

  • Avatar photo ‫אלון 14 אוגוסט 2018, 14:03

    יש תוסף שעושה את זה?

    • Avatar photo רועי יוסף 12 אוקטובר 2018, 2:55

      כן, כמעט כל תוסף Cache מבצע את העבודה בצורה כזו או אחרת..

  • Avatar photo רוב 16 אוקטובר 2018, 15:08

    בעקבות לקוח שאומר שהאתר איטי, קראתי שוב את המאמר שלך. יש הבדל בין סעיף 1 וסעיף 2? צריך את שניהם או רק אחד מהם? בבדיקות שעשיתי אני מקבל הודעה ש-First Byte Time לא טוב, ממה שהבנתי זה קשור לשרת (זה נכון?) יש משהו שאפשר לעשות פרט לאפשרות של מעבר שרת או שדרוג שלו?

    אני מתאר לעצמי שזה אתר באחסון שיתופי, אז בטח הרבה אין מה לעשות, נכון?

  • Avatar photo טל 13 מאי 2019, 23:08

    היי, איך אני יודע מה שם הקובץ של הjquery שלי שהתבנית טוענת?

  • Avatar photo טל 13 מאי 2019, 23:18

    ועוד דבר, בחלק של "לעכב את טעינת הסקריפטים לפי ה handle" לא הבנתי מה ואיפה צריך לשנות?
    זה הקוד שלי בfunction.php

    /* defer all js except jquery.min.js */
    if ( !is_admin() ) {
        function defer_parsing_of_js ( $url ) {
            if ( FALSE === strpos( $url, '.js' ) ) return $url;
            if ( strpos( $url, 'jquery.js' ) ) return $url;
    
            // return "$url' defer ";
            return "$url' defer onload='";
        }
    }
    if ( !is_admin() ) {
        add_filter( 'clean_url', 'defer_parsing_of_js', 11, 1 );
    }
    • Avatar photo רועי יוסף 14 מאי 2019, 15:05

      אתה צריך לשנות את jquery.js לשם קובץ ה jquery הנטען אצלך באתר….

  • Avatar photo אהרן 25 יולי 2019, 22:01

    הי רועי,

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

    • Avatar photo רועי יוסף 25 יולי 2019, 22:07

      היי אהרן,

      שמח לשמוע שאתה נעזר בתוכן 🙂 בכדי לבדוק גש לקוד המקור בדפדפן ותראה אם מופיעה המילה defer בקריאה לקבצי ה javascript….

  • Avatar photo שחר 25 אוגוסט 2019, 9:15

    תודה

  • Avatar photo רוב 24 נובמבר 2019, 9:58

    יש משהו שיכול לטפל בקבצים של ה-CSS? יש קובץ של dashicons.min.css שעושה בעיות לפי גוגל.

  • Avatar photo רוב 8 דצמבר 2019, 9:31

    כדאי להוסיף את defer גם ל Google Analytics? בקוד הוא מופיע עם async…

    • Avatar photo רועי יוסף 8 דצמבר 2019, 9:53

      לא, ההמלצה של גוגל היא לטעון (ולהריץ) את אנליטיקס יחסית מוקדם ולכן השאר את אנליטיקס כ async…

      • Avatar photo רוב 8 דצמבר 2019, 10:30

        תודה, אני רק מקווה שהכלי שלהם לא מתלונן על זה

  • Avatar photo רוב 6 ינואר 2020, 15:14

    נראה לי שיש שינוי ב-Revolution Slider השמות השתנו

    if ( !is_admin() ) {
        function defer_parsing_of_js ( $url ) {
            if ( FALSE === strpos( $url, '.js' ) ) return $url;
            if ( strpos( $url, 'jquery.js' ) ) return $url;
            if ( strpos( $url, 'revolution.tools.min.js' ) ) return $url;
    		if ( strpos( $url, 'rs6.min.js' ) ) return $url;
    
            return "$url' defer onload='";
        }
    }
    if ( !is_admin() ) {
        add_filter( 'clean_url', 'defer_parsing_of_js', 11, 1 );
    }

    יכול להתאים יותר?

    • Avatar photo רועי יוסף 6 ינואר 2020, 15:16

      תודה שאתה משתף רוב! 🙂
      ייתכן מאד, האם ביצעת בדיקה ווידאת שזה עובד?

      • Avatar photo רוב 7 ינואר 2020, 8:56

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

        • Avatar photo רועי יוסף 7 ינואר 2020, 11:31

          מצויין, תודה שוב – תעדכן אם תגלה משהו נוסף…

          • Avatar photo רוב 7 ינואר 2020, 11:46

            (:

תגובה חדשה

ניווט מהיר

Up!
לבלוג
הפוסט עודכן לאחרונה