حزمة Next.js لإدارة مكتبات الجهات الخارجية

في عام 2021، قدّم فريق Chrome Aurora مكوّن Script لتحسين أداء loading للنصوص البرمجية التابعة لجهات خارجية في Next.js. ومنذ إطلاقه، وسّعنا إمكاناته لتسهيل تحميل الموارد التابعة لجهات خارجية على المطوّرين و أسرع.

تقدّم مشاركة المدونة هذه نظرة عامة على الميزات الجديدة التي طرحناها، وأبرزها مكتبة @next/third-parties ، بالإضافة إلى مخطّطنا المستقبلي الذي يتضمن مبادرات جديدة.

تأثير النصوص البرمجية التابعة لجهات خارجية في الأداء

تشكّل النصوص البرمجية ‎41% من جميع طلبات الجهات الخارجية في مواقع Next.js الإلكترونية. على عكس أنواع المحتوى الأخرى، يمكن أن يستغرق تنزيل النصوص البرمجية وتنفيذها وقتًا طويلاً، ما قد يؤدي إلى حظر العرض وتأخير تفاعل المستخدم. تُظهر بيانات "تقرير تجربة مستخدم Chrome" (CrUX) أنّ المواقع الإلكترونية التي تستخدم Next.js وتحمل المزيد من الرمز البرمجي التابع لجهات خارجية تحقّق معدّلات اجتياز أقل لكل من مدى استجابة الصفحة لتفاعلات المستخدم (INP) وسرعة عرض أكبر محتوى مرئي (LCP).

رسم بياني شريطي يعرض انخفاضًا في النسبة المئوية لصفحات Next.js التي تحقّق نتائج جيدة لـ INP وLCL مقارنةً بعدد الجهات الخارجية التي يتم تحميلها
تقرير CrUX لشهر كانون الأول (ديسمبر) 2023 (110,823 موقعًا إلكترونيًا)

لا يشير الارتباط الذي لوحظ في هذا الرسم البياني إلى السببية. ومع ذلك، تقدّم التجارب على الويب محلية دليلاً إضافيًا على أنّ النصوص البرمجية التابعة لجهات خارجية تؤثر بشكل كبير في أداء الصفحة. على سبيل المثال، يقارن الرسم البياني أدناه مقاييس المختبرات المختلفة عند إضافة حاوية أداة "إدارة العلامات من Google" التي تتضمّن 18 علامة تم اختيارها عشوائيًا إلى Taxonomy، وهو مثال شائع على تطبيق Next.js.

رسم بياني شريطي يعرض الفرق في المقاييس المختلفة في المختبر عند تحميل موقع إلكتروني باستخدام أداة "إدارة العلامات من Google" وبدونها
WebPageTest (شبكة 4G الجوّالة - فرجينيا، الولايات المتحدة الأمريكية)

تقدّم مستندات WebPageTest تفاصيل حول كيفية قياس هذه الأوقات. من خلال نظرة سريعة، يتضح أنّ جميع مقاييس الإصدار التجريبي هذه تتأثر بحاوية "إحصاءات Google‏ 4". على سبيل المثال، شهد Total Blocking Time (TBT)، وهو مقياس بديل مفيد في المختبر يقترب من مقياس INP، زيادةً بمقدار 20 ضعفًا تقريبًا.

مكوّن النص البرمجي

عند طرح العنصر <Script> في Next.js، حرصنا على تقديمه من خلال واجهة برمجة تطبيقات سهلة الاستخدام تشبه إلى حد كبير العنصر<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 مكوّن <Script>، بما في ذلك المواقع الإلكترونية الرائجة مثل Patreon وTarget و Notion. على الرغم من فعاليته، أعرب بعض المطوّرين عن مخاوفهم بشأن النقاط التالية:

  • مكان وضع مكوّن <Script> في تطبيق Next.js مع الالتزام بتعليمات التثبيت المختلفة لموفّري الخدمات الخارجيين المختلفين (تجربة المطوّر)
  • استراتيجية التحميل الأكثر فعالية لاستخدامها مع مختلف النصوص البرمجية التابعة لجهات خارجية (تجربة المستخدم)

لحلّ كلتا المشكلتَين، أطلقنا @next/third-parties، وهي مكتبة مخصّصة تقدّم مجموعة من المكوّنات والأدوات المحسّنة المخصّصة للجهات الخارجية الرائجة.

تجربة المطوّرين: تسهيل إدارة المكتبات التابعة لجهات خارجية

يتم استخدام العديد من النصوص البرمجية التابعة لجهات خارجية في نسبة كبيرة من مواقع Next.js الإلكترونية، وتعدّ "إدارة العلامات من Google" الأكثر رواجًا، إذ تستخدمها ‎66% من المواقع الإلكترونية على التوالي. يستند @next/third-parties إلى المكوّن <Script> من خلال تقديم وحدات تغليف ذات مستوى أعلى مصمّمة لتبسيط استخدام حالات الاستخدام الشائعة هذه.

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"، وهي نص برمجي تابع لجهة خارجية يتم استخدامه على نطاق واسع، (‎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" />
    </>
  );
}

تجربة المستخدم: تسريع تحميل المكتبات التابعة لجهات خارجية

في عالم مثالي، سيتم تحسين كل مكتبة تابعة لجهة خارجية يتم استخدامها على نطاق واسع بالكامل، ما يجعل أيّ عمليات تجريد لتحسين أدائها غير ضرورية. ومع ذلك، إلى أن يصبح ذلك حقيقة، يمكننا محاولة تحسين تجربتهم عند دمجهم من خلال إطارات عمل شائعة مثل Next.js. يمكننا تجربة أساليب تحميل مختلفة، والتأكّد من تسلسل النصوص البرمجية بالطريقة الصحيحة، ومشاركة ملاحظاتنا في النهاية مع مقدمي خدمات الطرف الثالث لتشجيع التغييرات في المصدر.

لنأخذ عمليات تضمين YouTube كمثال. حيث تحقّق بعض عمليات التنفيذ البديلة أداءً أفضل بكثير من عمليات التضمين الأصلية. في الوقت الحالي، يستخدم <YouTubeEmbed> المكوّن الذي تصدّره أداة @next/third-parties lite-youtube-embed، والذي يتم تحميله بشكلٍ أسرع بكثير عند عرضه في مقارنة "Hello، World" Next.js.

صورة GIF متحرّكة تعرض مقارنة بين وقت تحميل الصفحة باستخدام مكوّن &quot;إدراج YouTube&quot; واستخدام إطار iframe عادي في YouTube
WebPageTest (شبكة 4G الجوّالة - فرجينيا، الولايات المتحدة الأمريكية)

وبالمثل، بالنسبة إلى "خرائط Google"، نضيف loading="lazy" كسمة تلقائية لمحاولة التضمين لضمان عدم تحميل الخريطة إلا عندما تكون على مسافة معيّنة من إطار العرض. قد تبدو هذه السمة واضحة لإدراجها، خاصةً لأنّ مستندات "خرائط Google" تضمّنها في مثال مقتطف الرمز البرمجي، ولكن لا يستخدم سوى loading="lazy" % 45 من مواقع Next.js التي تضمّن "خرائط Google".

تشغيل نصوص برمجية تابعة لجهات خارجية في Web Worker

من بين التقنيات المتقدّمة التي نستكشفها في @next/third-parties، تسهيل تحميل النصوص البرمجية التابعة لجهات خارجية إلى Web Worker. يمكن أن يؤدي ذلك إلى تقليل تأثير النصوص البرمجية التابعة لجهات خارجية على أداء الصفحة بشكل كبير من خلال إعادة تحديد موقعها بالكامل خارج سلسلة المهام الرئيسية، وذلك بفضل مكتبات مثل Partytown التي تروّج لهذا الإجراء.

تعرض الصورة المتحرّكة التالية بتنسيق GIF الاختلافات في المهام الطويلة ووقت حظر السلسلة الرئيسية عند تطبيق استراتيجيات <Script> مختلفة على حاوية أداة "إدارة العلامات من Google" ضمن موقع Next.js الإلكتروني. يُرجى العِلم أنّ التبديل بين خيارات الاستراتيجية يؤدي فقط إلى تأخير توقيت تنفيذ النصوص البرمجية هذه، بينما يؤدي نقلها إلى Web Worker إلى القضاء تمامًا على وقتها في سلسلة المحادثات الرئيسية.

ملف GIF يعرض الاختلافات في وقت حظر سلسلة المهام الرئيسية لاستراتيجيات النصوص البرمجية المختلفة
WebPageTest (شبكة 4G الجوّالة - فرجينيا، الولايات المتحدة الأمريكية)

في هذا المثال تحديدًا، أدّى نقل تنفيذ حاوية "إدارة العلامات من Google" وملفّات برمجة علاماتها المرتبطة بها إلى عامل ويب إلى خفض وقت معالجة الطلب بنسبة%92.

تجدر الإشارة إلى أنّ هذه الطريقة يمكن أن تؤدي إلى توقّف العديد من النصوص البرمجية التابعة لجهات خارجية بدون إشعار، ما يجعل تصحيح الأخطاء أمرًا صعبًا، في حال عدم إدارتها بعناية. في الأشهر القادمة، سنتحقّق مما إذا كانت أيّ مكوّنات تابعة لجهات خارجية تقدّمها @next/third-parties تعمل بشكل صحيح عند تشغيلها في Web Worker. إذا كان الأمر كذلك، سنعمل على توفير طريقة سهلة واختيارية للمطوّرين لاستخدام هذه المحاولة.

الخطوات التالية

أثناء تطوير هذه الحزمة، تبيّن أنّه هناك حاجة إلى تجميع اقتراحات التحميل التابعة لجهات خارجية كي تتمكّن أيضًا أطر العمل الأخرى من الاستفادة من الأساليب الأساسية نفسها المستخدَمة. وقد أدّى ذلك إلى إنشاء Third Party Capital، وهي مكتبة تستخدم تنسيق JSON لوصف تقنيات التحميل التابعة لجهات خارجية، والتي تُعدّ حاليًا الأساس لميزة @next/third-parties.

في إطار خطواتنا التالية، سنواصل التركيز على تحسين المكوّنات المقدّمة لنظام Next.js، بالإضافة إلى توسيع نطاق جهودنا لتشمل أدوات مماثلة في أنظمة إدارة المحتوى (CMS) والمنصات الرائجة الأخرى. نحن نتعاون حاليًا مع مشرفي Nuxt ونخطّط لطرح أدوات خارجية مشابهة مخصّصة لمنظومتهم المتكاملة في المستقبل القريب.

إذا كان أحد التطبيقات التابعة لجهات خارجية التي تستخدمها في تطبيق Next.js متوافقًا مع @next/third-parties، ثبِّت الحزمة جرِّبها. يسرّنا معرفة ملاحظاتك بشأن GitHub.