להבין את החזון שמאחורי רכיב הסקריפט Next.js, שמספק פתרון מובנה לביצוע אופטימיזציה של טעינת סקריפטים של צד שלישי.
כ-45% מהבקשות מאתרים שמוצגים בנייד ובמחשב הן בקשות של צד שלישי, מתוכן 33% הן סקריפטים. הגודל, זמן האחזור והטעינה של סקריפטים של צד שלישי יכולים להשפיע באופן משמעותי על ביצועי האתר. רכיב הסקריפט Next.js כולל שיטות מומלצות וברירות מחדל מובנות שנועדו לעזור למפתחים להוסיף סקריפטים של צד שלישי לאפליקציות שלהם, ובמקביל לטפל בבעיות אפשריות בביצועים.
סקריפטים של צד שלישי וההשפעה שלהם על הביצועים
סקריפטים של צד שלישי מאפשרים למפתחי אתרים להשתמש בפתרונות קיימים כדי להטמיע תכונות נפוצות ולקצר את זמן הפיתוח. עם זאת, בדרך כלל אין ליוצרי הסקריפטים האלה תמריץ לבחון את ההשפעה על הביצועים של אתר שצורך אותו. הסקריפטים האלה הם גם תיבת שחורה למפתחים שמשתמשים בהם.
סקריפטים אחראים למספר משמעותי של בייטים של צד שלישי שהורדתם על ידי אתרים בקטגוריות שונות של בקשות של צד שלישי. כברירת מחדל, הדפדפן נותן עדיפות לסקריפטים על סמך המיקום שלהם במסמך, דבר שעלול לעכב את זיהוי הסקריפטים או את ביצועם, אם הם קריטיים לחוויית המשתמש.
כדי להציג את הדף, צריך לטעון מוקדם את הספריות של הצד השלישי הנדרשות לפריסה. צריך לדחות צדדים שלישיים שלא נדרשים לעיבוד הראשוני, כדי שהם לא יחסמו עיבוד אחר ב-thread הראשי. ב-Lighthouse יש שני ביקורות שמסמנות סקריפטים שחוסמים את הרינדור או את השרשור הראשי.
חשוב להתייחס לרצף של טעינת המשאבים בדף, כדי שלא יהיה עיכוב במשאבים קריטיים ושהמשאבים שאינם קריטיים לא יחסמו משאבים קריטיים.
יש שיטות מומלצות לצמצום ההשפעה של צדדים שלישיים, אבל יכול להיות שלא כולם יודעים איך להטמיע אותן בכל צד שלישי שבו הם משתמשים. זה עשוי להיות מורכב מהסיבות הבאות:
- בממוצע, אתרים משתמשים ב21 עד 23 צדדים שלישיים שונים – כולל סקריפטים – בניידים ובמחשבים. השימוש וההמלצות עשויים להיות שונים בכל אחד מהם.
- הטמעת צדדים שלישיים רבים עשויה להיות שונה בהתאם לשימוש במסגרת ספציפית או בספריית ממשק משתמש ספציפית.
- אנחנו מוסיפים לעיתים קרובות ספריות חדשות יותר של צד שלישי.
- דרישות עסקיות שונות שקשורות לאותו צד שלישי מקשות על המפתחים לסטנדרטיזציה של השימוש בו.
התמקדות של Aurora בסקריפטים של צד שלישי
חלק משיתוף הפעולה של Aurora עם כלים ותבניות אינטרנט בקוד פתוח הוא לספק הגדרות ברירת מחדל חזקות וכלים עם דעה מוגדרת מראש, כדי לעזור למפתחים לשפר היבטים של חוויית המשתמש כמו ביצועים, נגישות, אבטחה והתאמה לנייד. בשנת 2021 התמקדנו בסיוע ל-framework stacks לשפר את חוויית המשתמש ואת המדדים של Core Web Vitals.
אחד מהשלבים המשמעותיים ביותר להשגת המטרה שלנו לשיפור הביצועים של framework הוא חיפוש של רצף הטעינה האידיאלי של סקריפטים של צד שלישי ב-Next.js. מסגרות כמו Next.js הן במיקום ייחודי שמאפשר להן לספק הגדרות ברירת מחדל ותכונות מועילות שיעזרו למפתחים לטעון משאבים ביעילות, כולל משאבים של צדדים שלישיים. בדקנו נתונים נרחבים מ-HTTP Archive ומ-Lighthouse כדי למצוא אילו צדדים שלישיים חוסמים את העיבוד הכי הרבה בפלטפורמות שונות.
כדי לטפל בבעיה של חסימת סקריפטים של צד שלישי שחוסמים שרשור ראשי באפליקציה, פיתחנו את רכיב הסקריפט. הרכיב מכיל תכונות של רצף כדי לספק למפתחים אמצעי בקרה טובים יותר לטעינה של סקריפטים של צד שלישי.
סידור סקריפטים של צד שלישי ללא רכיב מסגרת
ההנחיות הזמינות להפחתת ההשפעה של סקריפטים שחוסמים את הרינדור כוללות את השיטות הבאות לטעינה יעילה של סקריפטים של צד שלישי ולסדרת הפעלתם:
יש להשתמש במאפיין
async
או במאפייןdefer
עם תגי<script>
מורים לדפדפן לטעון סקריפטים לא קריטיים של צד שלישי בלי לחסום את מנתח המסמך. סקריפטים שלא נדרשים לטעינת הדף הראשונית או לאינטראקציה הראשונה של המשתמש עשויים להיחשב כלא קריטיים.<script src="https://example.com/script1.js" defer></script> <script src="https://example.com/script2.js" async></script>
יצירת חיבורים מראש למקורות נדרשים באמצעות קישור מראש ושליפה מוקדמת של נתוני DNS. כך אפשר להתחיל את ההורדה של סקריפטים קריטיים מוקדם יותר.
<head> <link rel="preconnect" href="http://PreconnThis.com"> <link rel="dns-prefetch" href="http://PrefetchThis.com"> </head>
טעינה איטית של משאבים מוטמעים ושל משאבים של צד שלישי אחרי שהתוכן הראשי של הדף מסתיים בטעינה, או כשהמשתמש גולל למטה לחלק של הדף שבו הם כלולים.
הרכיב Script ב-Next.js
רכיב הסקריפט Next.js מיישם את השיטות שלמעלה לסידור סקריפטים ברצף, ומספק תבנית למפתחים להגדרת אסטרטגיית הטעינה שלהם. אחרי שיצוין האסטרטגיה המתאימה, היא תיטען בצורה אופטימלית בלי לחסום משאבים קריטיים אחרים.
רכיב הסקריפט מבוסס על תג ה-HTML <script> ומספק אפשרות להגדיר את עדיפות הטעינה של סקריפטים של צד שלישי באמצעות מאפיין האסטרטגיה.
// Example for beforeInteractive:
<Script src="https://cdnjs.cloudflare.com/polyfill/v3/polyfill.min.js?features=IntersectionObserverEntry%2CIntersectionObserver" strategy="beforeInteractive" />
// Example for afterInteractive (default):
<Script src="https://example.com/samplescript.js" />
// Example for lazyonload:
<Script src="https://connect.facebook.net/en_US/sdk.js" strategy="lazyOnload" />
למאפיין strategy יש שלושה ערכים אפשריים.
beforeInteractive
: ניתן להשתמש באפשרות הזו לסקריפטים קריטיים שאמורים לפעול לפני שהדף הופך לאינטראקטיבי. Next.js מוודא שסקריפטים כאלו יוחדרו ל-HTML הראשוני בשרת, ויבוצעו לפני JavaScript אחר באריזה עצמית. ניהול הסכמה, סקריפטים לזיהוי בוטים או ספריות עזר שנדרשות כדי להציג תוכן קריטי הם מועמדים טובים לאסטרטגיה הזו.afterInteractive
: זוהי אסטרטגיית ברירת המחדל שחלה, והיא זהה לטעינה של סקריפט עם המאפיין defer. צריך להשתמש בו עבור סקריפטים שהדפדפן יכול להריץ אחרי שהדף הופך לאינטראקטיבי – לדוגמה, סקריפטים של ניתוח נתונים. מערכת Next.js מזריצה את הסקריפטים האלה בצד הלקוח, והם פועלים אחרי שהדף מתאושש. לכן, אלא אם צוין אחרת, כל הסקריפטים של צד שלישי שמוגדרים באמצעות רכיב ה-Script נדחים על ידי Next.js, וכך מתקבלת ברירת מחדל חזקה.lazyOnload
: אפשר להשתמש באפשרות הזו כדי לטעון סקריפטים בעדיפות נמוכה באופן איטי כשהדפדפן לא פעיל. הפונקציות שמספקים סקריפטים כאלה לא נדרשות מיד אחרי שהדף הופך לאינטראקטיבי – לדוגמה, פלאגינים של צ'אט או של רשתות חברתיות.
מפתחים יכולים לציין את האסטרטגיה כדי להגדיר ל-Next.js איך האפליקציה שלהם משתמשת בסקריפט. כך המערכת יכולה להחיל אופטימיזציות ושיטות מומלצות כדי לטעון את הסקריפט, תוך שמירה על רצף הטעינה הטוב ביותר.
באמצעות הרכיב Script, מפתחים יכולים להציב סקריפט של צד שלישי בכל מקום באפליקציה עבור צדדים שלישיים שנטענים בשלב מאוחר, וברמת המסמך עבור סקריפטים קריטיים. המשמעות היא שרכיב הסקריפט יכול להיות ממוקם באותו מיקום גיאוגרפי כמו הרכיב שמשתמש בסקריפט. אחרי ההידרציה, הסקריפט יוזרק לכותרת של המסמך שעבר עיבוד ראשוני או לתחתית הגוף, בהתאם לאסטרטגיה שבה נעשה שימוש.
מדידת ההשפעה
השתמשנו בתבניות של אפליקציית המסחר ושל בלוג ההתחלה של Next.js כדי ליצור שתי אפליקציות הדגמה שיעזרו למדוד את ההשפעה של הכללת סקריפטים של צד שלישי. צדדים שלישיים נפוצים של Google Tag Manager והטמעות של רשתות חברתיות נכללו בדפים של האפליקציות האלה ישירות ולאחר מכן באמצעות רכיב הסקריפט. לאחר מכן השווינו את הביצועים של הדפים האלה ב-WebPageTest.
סקריפטים של צד שלישי באפליקציית מסחר של Next.js
כדי להדגים את האפשרות הזו, הוספנו לתבנית של אפליקציית המסחר סקריפטים של צד שלישי, כפי שמפורט בהמשך.
בהשוואה הבאה אפשר לראות את ההתקדמות החזותית בשתי הגרסאות של Next.js commerce- Kit. כמו שנראו, LCP מתרחש כמעט שנייה אחת קודם, כשרכיב הסקריפט הופעל עם אסטרטגיית הטעינה הנכונה.
סקריפטים של צד שלישי בבלוג של Next.js
סקריפטים של צד שלישי נוספו לאפליקציית הבלוג לדוגמה, כפי שמפורט בהמשך.
לפני | אחרי |
---|---|
Google Tag Manager עם אסינכרוני | רכיב סקריפט עם אסטרטגיה = lazyonload לכל אחד מארבעת הסקריפטים |
לחצן 'מעקב' ב-Twitter עם אסינכרוניזציה | |
לחצן הרשמה ל-YouTube ללא אירועים אסינכרונים או השהיה | |
לחצן 'למעקב' ב-LinkedIn ללא אירוע אסינכרוני או דחייה |
כפי שמוצג בסרטון, הצגת תוכן ראשוני (FCP) מתרחשת תוך 0.9 שניות בדף ללא רכיב הסקריפט ותוך 0.4 שניות עם רכיב הסקריפט.
מה צפוי לרכיב הסקריפט
אפשרויות האסטרטגיה של afterInteractive
ו-lazyOnload
מספקות שליטה משמעותית על סקריפטים שחוסמים את הרינדור, אבל אנחנו גם בודקים אפשרויות אחרות שיעזרו לשפר את התועלת של רכיב הסקריפט.
שימוש ב-web workers
אפשר להשתמש בWeb workers כדי להריץ סקריפטים עצמאיים בשרשור רקע, וכך לפנות את השרשור הראשי לטיפול במשימות עיבוד של ממשק המשתמש ולשפר את הביצועים. Web Workers מתאימים במיוחד להעברת עומס העיבוד של JavaScript מה-thread הראשי, ולא לעבודה עם ממשק המשתמש. סקריפטים שמשמשים לתמיכת לקוחות או לשיווק, שבדרך כלל אין להם אינטראקציה עם ממשק המשתמש, יכולים להיות מועמדים טובים להפעלה בשרשור ברקע. אפשר להשתמש בספרייה קלה של צד שלישי – PartyTown – כדי לבודד סקריפטים כאלה ב-web worker.
בהטמעה הנוכחית של רכיב הסקריפט של Next.js, מומלץ לדחות את הסקריפטים האלה בשרשור הראשי על ידי הגדרת האסטרטגיה ל-afterInteractive
או ל-lazyOnload
. בעתיד, אנחנו מתכננים להציג אפשרות אסטרטגיה חדשה, 'worker'
, שתאפשר ל-Next.js להשתמש ב-PartyTown או בפתרון בהתאמה אישית כדי להריץ סקריפטים ב-web workers. אנחנו מקבלים בברכה תגובות ממפתחים ב-RFC הזה.
צמצום CLS
תוכן מוטמע של צד שלישי, כמו מודעות, סרטונים או פידים של רשתות חברתיות, עלול לגרום לשינויים בפריסה במהלך טעינת פריטים בזמן אמת. המצב הזה משפיע על חוויית המשתמש ועל המדד Cumulative Layout Shift (CLS) של הדף. כדי לצמצם את הערך של CLS, אפשר לציין את הגודל של המאגר שבו התוכן המוטמע ייטען.
אפשר להשתמש ברכיב Script כדי לטעון תוכן מוטמע שעלול לגרום לשינויי פריסה. אנחנו שוקלים להרחיב אותו כדי לספק אפשרויות הגדרה שיעזרו להפחית את ה-CLS. אפשר להציג את הקוד הזה בתוך רכיב הסקריפט עצמו או כרכיב נלווה.
רכיבי Wrapper
בדרך כלל, התחביר ואסטרטגיית הטעינה של הוספת סקריפטים פופולריים של צד שלישי, כמו Google Analytics או Google Tag Manager (GTM), הם קבועים. אפשר גם להכיל אותם ברכיבי עטיפה נפרדים לכל סוג של סקריפט. רק קבוצה מינימלית של מאפיינים ספציפיים לאפליקציה (כמו מזהה מעקב) תהיה זמינה למפתחים. רכיבי העטיפה יעזרו למפתחים:
- קל יותר לכלול תגי סקריפט פופולריים.
- מוודאים שהמסגרת משתמשת באסטרטגיה האופטימלית ביותר.
סיכום
בדרך כלל, סקריפטים של צד שלישי נוצרים כדי לכלול תכונות ספציפיות באתר הצרכן. כדי לצמצם את ההשפעה של סקריפטים לא קריטיים, מומלץ לדחות אותם. רכיב הסקריפט של Next.js עושה זאת כברירת מחדל. המפתחים יכולים להיות בטוחים שהסקריפטים הכלולים לא יגרמו לעיכוב בפונקציונליות קריטית, אלא אם הם יפעילו במפורש את האסטרטגיה beforeInteractive
. בדומה לרכיב הסקריפט של Next.js, מפתחי מסגרות יכולים גם לבחון את האפשרות לפתח את התכונות האלה במסגרות אחרות. אנחנו בודקים אפשרות להוסיף רכיב דומה בשיתוף עם צוות Nuxt.js. על סמך המשוב, אנחנו גם מקווים לשפר את רכיב הסקריפט כדי לכלול תרחישי שימוש נוספים.
אימות חתימות
תודה לKara Erickson, לJanicklas Ralph, לKatie Hempenius, לPhilip Walton, לJeremy Wagner ולAddy Osmani על המשוב ששלחו לגבי הפוסט הזה.