انتقل إلى المحتوى
العودة إلى المدونةTechnical

تحسين أداء Next.js: دليل شامل

١٥ مارس ٢٠٢٦12 min readSonics Yard Team

أصبح Next.js الإطار المفضل لتطبيقات React الإنتاجية، ولسبب وجيه. يمنحك التصيير من جانب الخادم المدمج، وتقسيم الكود الآلي، وخط البناء المحسّن أساسًا قويًا للأداء مباشرة. لكن تحقيق نتيجة 95+ في PageSpeed Insights يتطلب تحسينًا مقصودًا عبر طبقات متعددة من تطبيقك.

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

القياس قبل التحسين

قبل لمس أي كود، حدد خط الأساس. شغّل Google PageSpeed Insights وLighthouse وWebPageTest على رابط الإنتاج. سجّل مؤشرات الويب الأساسية: Largest Contentful Paint (LCP) وInteraction to Next Paint (INP) وCumulative Layout Shift (CLS). هذه المقاييس الثلاثة تحدد كيف يقيّم Google تجربة صفحتك، وتؤثر مباشرة على ترتيبك في البحث.

أعدّ مراقبة المستخدم الحقيقي (RUM) باستخدام Vercel Analytics أو Google Analytics 4 أو أداة مثل SpeedCurve. اختبارات المعمل تمنحك بيئة مضبوطة، لكن بيانات RUM تُظهر ما يختبره المستخدمون الفعليون عبر أجهزة وظروف شبكات مختلفة.

تحسين الصور

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

استخدام مكوّن Image في Next.js بشكل صحيح

  • حدد دائمًا خاصيتي width وheight لمنع تحول التخطيط. يستخدم مكوّن Image هذه لحساب نسبة العرض إلى الارتفاع وحجز المساحة قبل تحميل الصورة.
  • استخدم خاصية sizes لإخبار المتصفح بحجم الصورة المطلوب تحميله عند كل نقطة توقف. بدونها، يحمّل المتصفح أكبر نسخة بغض النظر عن عرض نافذة العرض.
  • عيّن priority={true} فقط للصور فوق الطية. هذا يفعّل التحميل المسبق الذي يساعد LCP لكنه يضر الأداء إذا أُفرط في استخدامه.
  • استخدم خاصية fill مع object-fit للحاويات المتجاوبة حيث تحدد الأبعاد من العنصر الأب.

استراتيجيات الصور المتقدمة

لصور البطل واللافتات الكبيرة، فكّر في استخدام سمة fetchpriority والاتصال المسبق بشبكة توصيل المحتوى للصور. إذا استضفت الصور على نطاق منفصل، أضف رابط preconnect في رأس المستند لإزالة عبء البحث عن DNS ومصافحة TLS.

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

تقسيم الكود وتحسين الحزم

يقسم Next.js كودك آليًا حسب المسار، لكن هناك تقنيات إضافية لتقليل JavaScript الذي يحمّله مستخدموك.

الاستيراد الديناميكي للمكوّنات الثقيلة

استخدم next/dynamic لتحميل المكوّنات كسولًا التي لا تُحتاج عند التصيير الأولي. الرسوم البيانية والخرائط ومحررات النصوص الغنية والنوافذ المنبثقة كلها مرشحات ممتازة. عندما يزور مستخدم صفحتك، يجب أن يحمّل فقط JavaScript المطلوب لما يراه مباشرة.

تحليل حزمك

ثبّت @next/bundle-analyzer وشغّله بانتظام. ابحث عن تبعيات كبيرة غير متوقعة ومكتبات مكررة ووحدات يمكن استبدالها ببدائل أخف. المخالفون الشائعون يشملون moment.js (استبدلها بـ date-fns أو dayjs) وlodash (استورد الدوال الفردية بدلاً من المكتبة بأكملها) ومكتبات مكوّنات UI الثقيلة حيث تستخدم جزءًا صغيرًا فقط من المكوّنات.

هز الشجرة وإزالة الكود الميت

تأكد أن استيراداتك قابلة لهز الشجرة. استخدم الاستيرادات المسماة بدلاً من استيرادات مساحة الاسم. للمكتبات التي لا تدعم هز الشجرة جيدًا، استخدم إعداد modularizeImports في next.config.js لتحويل الاستيرادات تلقائيًا إلى معادلاتها الوحدوية.

التصيير من جانب الخادم واستراتيجيات التخزين المؤقت

يمنحك Next.js 15 مع App Router تحكمًا دقيقًا في التصيير والتخزين المؤقت على مستوى المكوّن. فهم متى تستخدم كل استراتيجية أمر حاسم للأداء.

التوليد الثابت لصفحات المحتوى

أي صفحة لا تتغير لكل مستخدم يجب أن تُولّد ثابتًا وقت البناء. منشورات المدونة والتوثيق وصفحات التسويق وقوائم المنتجات ذات التحديثات النادرة كلها مرشحات. استخدم generateStaticParams لتصيير هذه الصفحات مسبقًا وتقديمها مباشرة من حافة CDN.

إعادة التوليد الثابت التدريجي (ISR)

للصفحات التي تُحدَّث دوريًا لكنها لا تحتاج بيانات فورية، ISR هو الحل الأمثل. حدد فترة إعادة التحقق لتقديم نسخة مخزنة بينما يعيد Next.js توليد الصفحة في الخلفية. هذا يمنحك سرعة الصفحات الثابتة مع حداثة المحتوى المصيَّر من الخادم.

البث وSuspense

استخدم حدود React Suspense لبث أجزاء صفحتك للمتصفح عندما تصبح جاهزة. هذا فعّال بشكل خاص للصفحات التي تحتوي مصادر بيانات سريعة وبطيئة. يرى المستخدم تخطيط الصفحة والمحتوى فوق الطية فورًا، بينما المكوّنات الأبطأ مثل التوصيات المخصصة أو لوحات التحليلات تُحمَّل تدريجيًا.

تحسين الخطوط

خطوط الويب مصدر متكرر لتحول التخطيط وحظر التصيير. يوفر Next.js وحدة next/font لمعالجة هذا، واستخدامها بشكل صحيح يمكن أن يزيل CLS الناتج عن تحميل الخطوط بالكامل.

  • استخدم next/font/google أو next/font/local لاستضافة الخطوط ذاتيًا. هذا يزيل الطلب الخارجي لـ Google Fonts ويُمكّن تقسيم الخط تلقائيًا.
  • عيّن خاصية display إلى 'swap' لضمان ظهور النص فورًا بخط بديل، ثم يُبدَّل للخط المخصص بعد تحميله.
  • استخدم خيار adjustFontFallback لتوليد خط بديل بمقاييس متطابقة، مما يقضي عمليًا على CLS أثناء التبديل.
  • حدد عدد أوزان الخطوط والأنماط التي تحمّلها. كل متغير يضيف لحجم التحميل.

إدارة السكريبتات الخارجية

سكريبتات التحليلات وأدوات المحادثة وبكسلات التسويق غالبًا ما تكون أكبر قاتلات الأداء. استخدم مكوّن Script في Next.js للتحكم في وقت تحميل السكريبتات الخارجية.

  • استخدم strategy='lazyOnload' للسكريبتات غير الحرجة لتجربة المستخدم، مثل التحليلات وبكسلات التتبع.
  • استخدم strategy='afterInteractive' للسكريبتات التي تحتاج العمل بعد أن تصبح الصفحة تفاعلية لكن قبل إجراءات المستخدم، مثل أدوات المحادثة.
  • لا تستخدم strategy='beforeInteractive' أبدًا إلا إذا كان السكريبت ضروريًا بشكل مطلق لعمل الصفحة.
  • فكّر في استخدام Partytown لنقل السكريبتات الخارجية إلى web worker، مما يحافظ على الخيط الرئيسي حرًا لتفاعلات المستخدم.

تحسين قاعدة البيانات وواجهات برمجة التطبيقات

أداء جانب الخادم يؤثر مباشرة على Time to First Byte (TTFB) وLCP. حسّن طبقة البيانات إلى جانب واجهتك الأمامية.

  • طبّق إزالة تكرار الطلبات باستخدام React cache() لتجنب جلب نفس البيانات عدة مرات أثناء تصيير واحد.
  • استخدم جلب البيانات المتوازي مع Promise.all() عندما تكون عدة استدعاءات API مستقلة مطلوبة لصفحة واحدة.
  • أضف ترويسات تخزين مؤقت لاستجابات API واستفد من ذاكرة التخزين المؤقت لـ fetch في Next.js لطلبات جانب الخادم.
  • فكّر في قواعد بيانات متوافقة مع الحافة مثل PlanetScale أو Neon أو Turso للبيانات التي تحتاج تقديمها عالميًا بزمن استجابة منخفض.

قائمة تحقق الأداء

قبل نشر أي تطبيق Next.js، راجع هذه القائمة للتأكد من تغطية الأساسيات:

  1. شغّل Lighthouse في وضع الإنتاج وعالج جميع المشاكل المُشار إليها فوق مستوى 'منخفض'.
  2. تحقق أن جميع الصور فوق الطية تستخدم خاصية priority والأحجام الصحيحة.
  3. تأكد من عدم حدوث تحولات في التخطيط أثناء تحميل الصفحة بتسجيل تتبع CLS.
  4. حلّل حزمة JavaScript وتأكد من عدم شحن تبعيات غير مستخدمة للعميل.
  5. اختبر على اتصال 3G مخنوق وجهاز موبايل متوسط لمحاكاة ظروف العالم الحقيقي.
  6. تحقق أن السكريبتات الخارجية مؤجلة ولا تحظر الخيط الرئيسي لأكثر من 50 مللي ثانية.
  7. تأكد أن وقت استجابة الخادم أقل من 200 مللي ثانية للصفحات الثابتة وأقل من 500 مللي ثانية للصفحات الديناميكية.
  8. تأكد أن ترويسات التخزين المؤقت مضبوطة بشكل صحيح للأصول الثابتة واستجابات API والصفحات المصيَّرة.

مراقبة الأداء المستمرة

تحسين الأداء ليس مهمة لمرة واحدة. كل ميزة جديدة أو تبعية أو تحديث محتوى لديه القدرة على إرجاع مقاييسك. أعدّ Lighthouse CI آليًا في خط نشرك لاكتشاف الانحدار قبل وصوله للإنتاج. اضبط تنبيهات لحدود مؤشرات الويب الأساسية حتى يُنبَّه فريقك عندما تتدهور مقاييس المستخدم الحقيقي.

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

احجز مكالمة استراتيجية مجانية

Free. No obligation. 30 minutes.

Chat with us