تقسيم الرمز باستخدام عمليات الاستيراد الديناميكية في Next.js

كيفية تسريع تطبيق Next.js باستخدام استراتيجيات تقسيم الرموز والتحميل الذكي

ماذا ستتعلم؟

تشرح هذه المشاركة أنواعًا مختلفة من الرموز البرمجية تقسيم البيانات وكيفية استخدام عمليات الاستيراد الديناميكية لتسريع تطبيقات Next.js.

تقسيم الرموز استنادًا إلى المسار واستنادًا إلى المكوّنات

بشكل افتراضي، يقسم Next.js JavaScript إلى أجزاء منفصلة لكل مسار. عندما يُحمِّل المستخدمون تطبيقك، لا يرسل Next.js سوى الرمز المطلوب المسار الأولي. عندما يتنقل المستخدمون حول التطبيق، فإنهم يجلبون المقاطع المرتبطة بالمسارات الأخرى. يؤدي تقسيم الرموز استنادًا إلى المسار إلى تقليل مقدار النص الذي يجب تحليله وتجميعه مرة واحدة، مما ينتج عنه في أوقات تحميل صفحة أسرع.

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

تتوافق Next.js مع ديناميكية import()، الذي يتيح لك استيراد وحدات JavaScript (بما في ذلك مكوِّنات React). ديناميكيًا وتحميل كل عملية استيراد كمقطع منفصل. يمنحك ذلك تقسيم الرمز على مستوى المكون وتتيح لك التحكم في تحميل الموارد بحيث تنزيل الرمز الذي يحتاجه المستخدمون فقط للجزء الذي من الموقع التي يشاهدها. في Next.js، يتم عرض هذه المكوّنات من جهة الخادم (SSR) تلقائيًا.

تنفيذ عمليات الاستيراد الديناميكية

تتضمن هذه المشاركة إصدارات متعددة من نموذج تطبيق يتكون من زر واحد. عند النقر على الزر، يمكنك رؤية جرو لطيف. بالنسبة عند التنقل في كل إصدار من إصدارات التطبيق، سترى كيفية عمل عمليات الاستيراد الديناميكية مختلفة عن الثابتة الواردات وكيفية التعامل معها.

في الإصدار الأول من التطبيق، يعيش الجرو في components/Puppy.js. إلى سيعرض شكل الجرو على الصفحة، يستورد التطبيق مكوّن Puppy من index.js مع عبارة استيراد ثابتة:

import Puppy from "../components/Puppy";

للاطّلاع على كيفية تجميع Next.js للتطبيق، افحص عملية تتبُّع الشبكة في "أدوات مطوري البرامج":

  1. لمعاينة الموقع الإلكتروني، اضغط على عرض التطبيق. ثم اضغط ملء الشاشة ملء الشاشة

  2. اضغط على "Control+Shift+J" (أو "Command+Option+J" على أجهزة Mac) لفتح "أدوات مطوري البرامج".

  3. انقر على علامة التبويب الشبكة.

  4. ضع علامة في مربّع الاختيار إيقاف ذاكرة التخزين المؤقت.

  5. إعادة تحميل الصفحة

عند تحميل الصفحة، يتم عرض كل الرموز اللازمة، بما في ذلك Puppy.js. مجمعة في index.js:

علامة تبويب "شبكة أدوات مطوّري البرامج" تعرض ستة ملفات JavaScript وهي: index.js وapp.js وwebpack.js وmain.js و0.js وملف dll (مكتبة الروابط الديناميكية).

عند الضغط على الزر انقر هنا، سيتم فقط إرسال طلب صورة جرو JPEG تمت إضافته إلى علامة التبويب الشبكة:

علامة تبويب "شبكة أدوات مطوّري البرامج" بعد النقر على الزر، وتعرض ملفات JavaScript الستة نفسها وصورة واحدة

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

تحقق الآن من إصدار ثاني من التطبيق، فيه الاستيراد الثابت بالاستيراد الديناميكي. يتضمن Next.js السمة next/dynamic، مما يجعل من من الممكن استخدام عمليات الاستيراد الديناميكية لأي مكونات في "التالي":

import Puppy from "../components/Puppy";
import dynamic from "next/dynamic";

// ...

const Puppy = dynamic(import("../components/Puppy"));

اتّبِع الخطوات الواردة في المثال الأول لفحص سجلّ تتبُّع الشبكة.

عند تحميل التطبيق لأول مرة، يتم تنزيل index.js فقط. هذه المرة أصغر حجمًا 0.5 كيلوبايت (انخفض من 37.9 كيلوبايت إلى 37.4 كيلوبايت) بسبب لا يتضمن الرمز الخاص بالمكوِّن Puppy:

تعرض شبكة "أدوات مطوري البرامج" ملفات JavaScript الستة نفسها، باستثناء أن حجم ملف index.js أصبح الآن أصغر بمقدار 0.5 كيلوبايت.

يتوفّر المكوِّن Puppy الآن في مجموعة منفصلة، 1.js، ويتم تحميلها فقط. عند الضغط على الزر:

علامة التبويب "الشبكة" من DevTools بعد النقر على الزر، وتعرض ملف 1.js الإضافي والصورة المضافة إلى أسفل قائمة الملفات.

في التطبيقات الواقعية، غالبًا ما تكون المكونات وأكبر حجمًا مع التحميل الكسول يمكنك تقليل حمولة JavaScript الأولية بمئات الكيلوبايت.

عمليات الاستيراد الديناميكية مع مؤشر تحميل مخصّص

عند التحميل الكسول للموارد، من الأفضل توفير مؤشر تحميل في حالة حدوث أي تأخير. في Next.js، يمكنك القيام بذلك عن طريق توفير وسيطة إضافية إلى الدالة dynamic():

const Puppy = dynamic(() => import("../components/Puppy"), {
  loading: () => <p>Loading...</p>
});

لرؤية مؤشّر التحميل قيد التشغيل، عليك محاكاة اتصال شبكة بطيء في أدوات مطوري البرامج:

  1. لمعاينة الموقع الإلكتروني، اضغط على عرض التطبيق. ثم اضغط ملء الشاشة ملء الشاشة

  2. اضغط على "Control+Shift+J" (أو "Command+Option+J" على أجهزة Mac) لفتح "أدوات مطوري البرامج".

  3. انقر على علامة التبويب الشبكة.

  4. ضع علامة في مربّع الاختيار إيقاف ذاكرة التخزين المؤقت.

  5. في القائمة المنسدلة Throttling، اختَر Fast 3G.

  6. اضغط على الزر انقر هنا.

الآن، عند النقر على الزر، يستغرق تحميل المكوِّن والتطبيق بعض الوقت يعرض رسالة "جارٍ التحميل..." رسالة في غضون ذلك.

شاشة داكنة تعرض النص

عمليات الاستيراد الديناميكية بدون معرّف الخدمة الذاتية (SSR)

إذا كنت تريد عرض مكوِّن من جهة العميل فقط (مثل محادثة التطبيق المصغَّر) يمكنك إجراء ذلك من خلال ضبط خيار ssr على false:

const Puppy = dynamic(() => import("../components/Puppy"), {
  ssr: false,
});

الخاتمة

مع دعم عمليات الاستيراد الديناميكية، يمنحك Next.js رمزًا على مستوى المكوّنات تقسيم البيانات، الذي يمكن أن يقلل من أحمال JavaScript ويحسّن التطبيق وقت التحميل. ويتم عرض جميع المكوّنات بشكل تلقائي من جهة الخادم، ويمكنك وتعطيل هذا الخيار كلما لزم الأمر.