كيفية تحسين استخدام الذاكرة
مع نمو التطبيقات وزيادة ثراء الميزات، قد تطلب موارد أكبر عند التطوير محليًا أو إنشاء إصدارات إنتاجية.
لنستكشف بعض الاستراتيجيات والتقنيات لتحسين الذاكرة ومعالجة مشاكل الذاكرة الشائعة في Next.js.
تقليل عدد التبعيات
التطبيقات التي تحتوي على عدد كبير من التبعيات ستستخدم ذاكرة أكثر.
يمكن لـ محلل الحزم (Bundle Analyzer) مساعدتك في التحقق من التبعيات الكبيرة في تطبيقك والتي قد يكون من الممكن إزالتها لتحسين الأداء واستخدام الذاكرة.
جرب experimental.webpackMemoryOptimizations
بدءًا من الإصدار v15.0.0
، يمكنك إضافة experimental.webpackMemoryOptimizations: true
إلى ملف next.config.js
لتغيير سلوك Webpack مما يقلل من الحد الأقصى لاستخدام الذاكرة ولكن قد يزيد أوقات التجميع قليلاً.
معلومة مفيدة: هذه الميزة حالياً تجريبية لاختبارها على المزيد من المشاريع أولاً، ولكنها تعتبر منخفضة المخاطر.
تشغيل next build
مع --experimental-debug-memory-usage
بدءًا من الإصدار 14.2.0
، يمكنك تشغيل next build --experimental-debug-memory-usage
لتشغيل عملية البناء في وضع حيث يقوم Next.js بطباعة معلومات عن استخدام الذاكرة بشكل مستمر طوال عملية البناء، مثل استخدام الكومة (heap) وإحصائيات جمع القمامة. كما سيتم أخذ لقطات للكومة تلقائيًا عندما يقترب استخدام الذاكرة من الحد الم configured.
معلومة مفيدة: هذه الميزة غير متوافقة مع خيار عامل بناء Webpack الذي يتم تمكينه تلقائيًا إلا إذا كان لديك تكوين Webpack مخصص.
تسجيل ملف تعريف للكومة (heap profile)
للبحث عن مشاكل الذاكرة، يمكنك تسجيل ملف تعريف للكومة من Node.js وتحميله في Chrome DevTools لتحديد مصادر تسرب الذاكرة المحتملة.
في طرفيتك، مرر علم --heap-prof
إلى Node.js عند بدء بناء Next.js:
node --heap-prof node_modules/next/dist/bin/next build
في نهاية عملية البناء، سيتم إنشاء ملف .heapprofile
بواسطة Node.js.
في Chrome DevTools، يمكنك فتح علامة تبويب الذاكرة والنقر على زر "Load Profile" لتصور الملف.
تحليل لقطة للكومة (heap snapshot)
يمكنك استخدام أداة مفتش (inspector) لتحليل استخدام الذاكرة في التطبيق.
عند تشغيل أمر next build
أو next dev
، أضف NODE_OPTIONS=--inspect
في بداية الأمر. هذا سيعرض وكيل المفتش على المنفذ الافتراضي.
إذا كنت ترغب في التوقف قبل بدء أي كود مستخدم، يمكنك تمرير --inspect-brk
بدلاً من ذلك. أثناء تشغيل العملية، يمكنك استخدام أداة مثل Chrome DevTools للاتصال بمنفذ التصحيح لتسجيل وتحليل لقطة للكومة لمعرفة ما يتم الاحتفاظ به في الذاكرة.
بدءًا من الإصدار 14.2.0
، يمكنك أيضًا تشغيل next build
مع علم --experimental-debug-memory-usage
لتسهيل أخذ لقطات الكومة.
أثناء التشغيل في هذا الوضع، يمكنك إرسال إشارة SIGUSR2
إلى العملية في أي لحظة، وسوف تأخذ العملية لقطة للكومة.
سيتم حفظ لقطة الكومة في جذر مشروع تطبيق Next.js ويمكن تحميلها في أي محلل كومة، مثل Chrome DevTools، لمعرفة ما يتم الاحتفاظ به في الذاكرة. هذا الوضع غير متوافق بعد مع عمال بناء Webpack.
راجع كيفية تسجيل وتحليل لقطات الكومة لمزيد من المعلومات.
عامل بناء Webpack (Webpack build worker)
يسمح عامل بناء Webpack بتشغيل تجميعات Webpack داخل عامل Node.js منفصل مما يقلل استخدام الذاكرة في تطبيقك أثناء عمليات البناء.
يتم تمكين هذا الخيار افتراضيًا إذا لم يكن لدى تطبيقك تكوين Webpack مخصص بدءًا من الإصدار v14.1.0
.
إذا كنت تستخدم إصدارًا أقدم من Next.js أو لديك تكوين Webpack مخصص، يمكنك تمكين هذا الخيار عن طريق تعيين experimental.webpackBuildWorker: true
داخل ملف next.config.js
.
معلومة مفيدة: قد لا تكون هذه الميزة متوافقة مع جميع إضافات Webpack المخصصة.
تعطيل ذاكرة التخزين المؤقت لـ Webpack
ذاكرة التخزين المؤقت لـ Webpack تحفظ وحدات Webpack التي تم إنشاؤها في الذاكرة و/أو على القرص لتحسين سرعة عمليات البناء. هذا يمكن أن يساعد في الأداء، ولكنه أيضًا يزيد من استخدام الذاكرة في تطبيقك لتخزين البيانات المؤقتة.
يمكنك تعطيل هذا السلوك عن طريق إضافة تكوين Webpack مخصص إلى تطبيقك:
/** @type {import('next').NextConfig} */
const nextConfig = {
webpack: (
config,
{ buildId, dev, isServer, defaultLoaders, nextRuntime, webpack }
) => {
if (config.cache && !dev) {
config.cache = Object.freeze({
type: 'memory',
})
}
// مهم: إرجاع التكوين المعدل
return config
},
}
export default nextConfig
تعطيل التحليل الثابت (static analysis)
قد يتطلب التحقق من الأنواع (typechecking) وفحص الأخطاء (linting) الكثير من الذاكرة، خاصة في المشاريع الكبيرة. ومع ذلك، فإن معظم المشاريع لديها مشغل CI مخصص يتولى بالفعل هذه المهام. عندما تسبب عملية البناء مشاكل نفاد الذاكرة أثناء خطوة "التحقق من الأخطاء والتحقق من صحة الأنواع"، يمكنك تعطيل هذه المهام أثناء عمليات البناء:
/** @type {import('next').NextConfig} */
const nextConfig = {
eslint: {
// تحذير: هذا يسمح لعمليات البناء الإنتاجية بالإكمال بنجاح حتى إذا
// كان مشروعك يحتوي على أخطاء ESLint.
ignoreDuringBuilds: true,
},
typescript: {
// !! تحذير !!
// يسمح بشكل خطير لعمليات البناء الإنتاجية بالإكمال بنجاح حتى إذا
// كان مشروعك يحتوي على أخطاء في الأنواع.
// !! تحذير !!
ignoreBuildErrors: true,
},
}
export default nextConfig
ضع في اعتبارك أن هذا قد ينتج عنه عمليات نشر معيبة بسبب أخطاء في الأنواع أو مشاكل في فحص الأخطاء. نوصي بشدة بعدم ترقية البناء إلى الإنتاج إلا بعد اكتمال التحليل الثابت. إذا كنت تقوم بالنشر على Vercel، يمكنك الاطلاع على دليل النشر التجريبي (staging deployments) لمعرفة كيفية ترقية البناء إلى الإنتاج بعد نجاح المهام المخصصة.
تعطيل خرائط المصدر (source maps)
يستهلك إنشاء خرائط المصدر ذاكرة إضافية أثناء عملية البناء.
يمكنك تعطيل إنشاء خرائط المصدر عن طريق إضافة productionBrowserSourceMaps: false
و experimental.serverSourceMaps: false
إلى تكوين Next.js الخاص بك.
معلومة مفيدة: قد تقوم بعض الإضافات بتشغيل خرائط المصدر وقد تتطلب تكوينًا مخصصًا لتعطيلها.
مشاكل الذاكرة في Edge runtime
قام Next.js v14.1.3
بإصلاح مشكلة ذاكرة عند استخدام Edge runtime. يرجى التحديث إلى هذا الإصدار (أو أحدث) لمعرفة ما إذا كان يحل مشكلتك.
تحميل المدخلات مسبقًا (Preloading Entries)
عند بدء تشغيل خادم Next.js، يقوم بتحميل وحدات JavaScript لكل صفحة في الذاكرة مسبقًا، بدلاً من وقت الطلب.
هذا التحسين يسمح بأوقات استجابة أسرع، مقابل زيادة في البصمة الأولية للذاكرة.
لتعطيل هذا التحسين، عيّن علامة experimental.preloadEntriesOnStart
إلى false
.
import type { NextConfig } from 'next'
const config: NextConfig = {
experimental: {
preloadEntriesOnStart: false,
},
}
export default config
/** @type {import('next').NextConfig} */
const config = {
experimental: {
preloadEntriesOnStart: false,
},
}
export default config
لا يقوم Next.js بإلغاء تحميل وحدات JavaScript هذه، مما يعني أنه حتى مع تعطيل هذا التحسين، فإن بصمة الذاكرة لخادم Next.js الخاص بك ستكون في النهاية نفسها إذا تم طلب جميع الصفحات في النهاية.