חבילת Next.js לניהול ספריות של צד שלישי

Houssein Djirdeh
Houssein Djirdeh

בשנת 2021, צוות Chrome Aurora השיק את הסקריפט של הרכיב כדי לשפר טעינת סקריפטים של צד שלישי ב-Next.js. מאז ההשקה, הרחבנו את היכולות שלו כדי להקל על הטעינה של משאבים של צד שלישי מהיר יותר למפתחים.

פוסט זה בבלוג מספק סקירה כללית על התכונות החדשות שהשקנו, ברובן בעיקר @next/third-parties ומפרט של יוזמות עתידיות בתוכנית שלנו.

ההשלכות על הביצועים של סקריפטים של צד שלישי

41% מכל הבקשות של צד שלישי באתרי Next.js הן סקריפטים. ביטול לייק לתוכן אחר שונים, נדרש זמן רב להורדה ולהפעלה של סקריפטים, מה שעלול לחסום את הרינדור ולעכב את האינטראקטיביות של המשתמש. נתונים מ-Chrome בדוח חוויית המשתמש (CrUX) מצוין כי אתרי Next.js שטוענים עוד אתרים של צד שלישי לסקריפטים יש אינטראקציה נמוכה יותר לצביעה הבאה (INP) ו-Largest Contentful Paint (LCP) קצבי העברת נתונים (LCP).

תרשים עמודות שבו מוצגת ירידה באחוז של Next.js שהשיגו ציונים טובים ב-INP וב-LCP, ביחס למספר הצדדים השלישיים שנטענו
דוח CrUX לחודש דצמבר 2023 (110,823 אתרים)

המתאם שמוצג בתרשים הזה לא מרמז על סיבתיות. לעומת זאת, באופן מקומי הניסויים מספקים ראיות נוספות לכך שסקריפטים של צד שלישי להשפיע על ביצועי הדפים. לדוגמה, בתרשים הבא מוצגת השוואה בין שיעורי Lab שונים מדדים כאשר מאגר תגים של Google Tag Manager – שמורכב מ-18 פריטים שנבחרו באופן אקראי - נוסף אל טקסונומיה, דוגמה פופולרית של Next.js אפליקציה.

תרשים עמודות שמראה את ההבדל במדדים השונים של שיעור ה-Lab כשאתר נטען עם Google Tag Manager וללא Google Tag Manager.
WebPageTest (Mobile 4G - Virginia USA)

מסמכי התיעוד של WebPageTest מספקת פרטים על האופן שבו התזמונים האלה נמדדים. במבט מהיר, כל המדדים האלה של שיעור ה-Lab מושפעים ממאגר התגים של GTM. עבור לדוגמה, Total Blocked Time (TBT) – שיעור Lab שימוש��. שרת proxy שמעריך את INP - ראה עלייה של כמעט פי 20.

רכיב סקריפט

כששלחנו את הרכיב <Script> ב-Next.js, הקפדנו להציג באמצעות ממשק API ידי��ו��י למ��תמש ��דומה מאוד לפרוטוקול <script> המסורתי לרכיב מסוים. על ידי שימוש במשתנה הזה, המפתחים יכולים לאתר סקריפט של צד שלישי בכל של הרכיב באפליקציה שלהם, ו-Next.js יטפל ברצף של אחרי שמשאבים קריטיים נטענים.

<!-- By default, script will load after page becomes interactive -->
<Script src="https://example.com/sample.js" />

<!-- Script is injected server-side and fetched before any page hydration occurs -->
<Script strategy=”beforeInteractive” src="https://example.com/sample.js" />

<!-- Script is fetched later during browser idle time -->
<Script strategy=”lazyOnload” src="https://example.com/sample.js" />

עשרות אלפי אפליקציות של Next.js — כולל אתרים פופולריים כמו Patreon, Target ו- הערה – צריך להשתמש ברכיב <Script>. למרות יעילות, חלק מהמפתחים העלו חששות לגבי הנושאים הבאים דברים:

  • היכן למקם את הרכיב <Script> באפליקציית Next.js ולפעול בהתאם להוראות ההתקנה השונות של ספקי צד שלישי שונים (למפתחים).
  • איזו אסטרטגיית טעינה היא האופטימלית ביותר סקריפטים של צד שלישי (חוויית המשתמש).

כדי לתת מענה לשתי הבעיות האלה, השקנו את @next/third-parties – לספרייה מיוחדת שמציעה קבוצה של רכיבים ושירותים מותאמים שמותאמות לצדדים שלישיים פופולריים.

חוויית המפתחים: ניהול קל יותר של ספריות של צד שלישי

סקריפטים רבים של צד שלישי נמצאים בשימוש באחוז משמעותי מאתרי Next.js, עם Google Tag Manager הוא Tag Manager הכי פופולרי, 66% מהאתרים בהתאמה. @next/third-parties מתבסס על <Script> באמצעות הכנסת wrappers ברמה גבוהה יותר שמיועדים לפשט את השימוש בתרחישים לדוגמה נפוצים האלה.

import { GoogleAnalytics } from "@next/third-parties/google";

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>{children}</body>
      <GoogleTagManager gtmId="GTM-XYZ" />
    </html>
  );
}

Google Analytics – סקריפט נוסף של צד שלישי שנמצא בשימוש נפוץ (52% מאתרי Next.js) – גם יש רכיב ייעודי משלו.

import { GoogleAnalytics } from "@next/third-parties/google";

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>{children}</body>
      <GoogleAnalytics gaId="G-XYZ" />
    </html>
  );
}

@next/third-parties מפשט את תהליך הטעינה של סקריפטים נפוצים, אבל זה גם מרחיב את היכולת שלנו לפתח כלים לצדדים שלישיים קטגוריות, כמו הטמעות. לדוגמה, מפות Google והטמעות YouTube בשימוש ב- 8% וגם 4% של אתרי Next.js בהתאמה, וגם שלחנו רכיבים כדי להפוך אותם קל יותר לטעינה.

import { GoogleMapsEmbed } from "@next/third-parties/google";
import { YouTubeEmbed } from "@next/third-parties/google";

export default function Page() {
  return (
    <>
      <GoogleMapsEmbed
        apiKey="XYZ"
        height={200}
        width="100%"
        mode="place"
        q="Brooklyn+Bridge,New+York,NY"
      />
      <YouTubeEmbed videoid="ogfYd705cRs" height={400} params="controls=0" />
    </>
  );
}

חוויית משתמש: טעינה מהירה יותר של ספריות של צד שלישי

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

למשל, הטמעות YouTube. במקרים שבהם יש הטמעות חלופיות ביצועים טובים בהרבה מאלה של ההטמעה המקורית. נכון לעכשיו, <YouTubeEmbed> רכיב שיוצא על ידי @next/third-parties משתמש lite-youtube-embed, כשמראים את הדגימות "שלום, עולם" השוואה של Next.js, נטענת באופן משמעותי מהר יותר.

קובץ GIF שמציג השוואה של טעינת הדפים בין רכיב ההטמעה של YouTube ל-iframe רגיל של YouTube
WebPageTest (Mobile 4G - Virginia USA)

באופן דומה, במפות Google, אנחנו כוללים את loading="lazy" כמאפיין ברירת המחדל עבור כדי לוודא שהמפה נטענת רק כשמרחק מסוים ממנה אזור התצוגה. זה נראה כמו מאפיין מובן מאליו שצריך לכלול, במיוחד מאז מפות Google מסמכי תיעוד כוללים אותו בקטע הקוד לדוגמה, אבל רק 45% מאתרי Next.js שמטמיעים את מפות Google משתמשים ב-loading="lazy".

הפעלת סקריפטים של צד שלישי ב-Web Worker

אחת מהשיטות המתקדמות שאנחנו בוחנים ב-@next/third-parties היא קל יותר להעביר לעובדי אינטרנט את הסקריפטים של צד שלישי. פופולרי על ידי כמו Partytown את ההשפעה של סקריפטים של צד שלישי על ביצועי הדף באופן משמעותי להעביר אותן לגמרי מהשרשור הראשי.

בקובץ ה-GIF המונפש הבא אפשר לראות את הווריאציות במשימות הארוכות ובשרשור הראשי את זמן החסימה כשמחילים אסטרטגיות שונות של <Script> על מאגר תגים של GTM באתר Next.js. הערה: כשעוברים רק בין אפשרויות אסטרטגיה מעכב את תזמון ההפעלה של הסקריפטים האלה, ומעביר אותם ל-Web Worker ומבטלת לגמרי את הזמן שלהם לשרשור הראשי.

קובץ GIF שמציג הבדלים בזמן החסימה של השרשורים העיקריים בשיטות השונות של הסקריפטים
WebPageTest (Mobile 4G - Virginia USA)

בדוגמה הספציפית הזו, העברת ההפעלה של מאגר התגים של GTM סקריפטים משויכים של תגים לעובדי אינטרנט הפחיתו את TBT ב-92%.

חשוב לציין שאם לא מנהלים אותה בקפידה, להשבית סקריפטים רבים של צד שלישי, מה שמקשה על ניפוי באגים. ב- חודשים, נבדוק אם רכיבים של צד שלישי מוצעים הפונקציה @next/third-parties פועלת בצורה תקינה כשמריצים אותה ב-Web Worker. אם כן, היא לספק דרך קלה ואופציונלית שתאפשר למפתחים להשתמש בה לעיבוד טקסט.

השלבים הבאים

בתהליך הפיתוח של החבילה הזו התברר שיש צריך לרכז את המלצות הטעינה של צדדים שלישיים כך שמסגרות אחרות גם הוא יכול להפיק תועלת מאותן שיטות בסיסיות שבהן נעשה שימוש. זה הוביל אותנו build צד שלישי עיר גדולה, ספרייה שמשתמשת ב-JSON כדי לתאר טכניקות טעינה של צד שלישי, משמש כבסיס ל-@next/third-parties.

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

אם אחד מהצדדים השלישיים שאתם משתמשים בהם באפליקציית Next.js נתמך על ידי @next/third-parties, להתקין את החבילה תנסו בעצמכם! נשמח לקבל ממך משוב לגבי GitHub.