تخطّى إلى المحتوى الرئيسي
‏next/image في Next.js 16: ما الذي لا يحدث تلقائيًا في تحسين الصور

‏next/image في Next.js 16: ما الذي لا يحدث تلقائيًا في تحسين الصور

August 14, 2026
هندسة الواجهات
6 دقيقة قراءة

أهم النقاط

‏next/image يؤجل تحميل كل صورة افتراضيًا، بما فيها الصورة التي تمثل عنصر Largest Contentful Paint. خاصية priority وحدها هي التي تلغي التأجيل وتضيف تلميح تحميل مسبق بأولوية عالية.

خاصية sizes تخبر المتصفح بالعرض الذي ستُعرض به الصورة قبل تطبيق CSS. الصورة التي تستخدم fill بدون sizes تُعامَل على أنها 100vw، ما يجعل المتصفح يختار أكبر نسخة في srcset.

‏Next.js 16 أزال خيار images.domains، وأصبح images.remotePatterns هو الطريقة المدعومة الوحيدة للسماح بمصدر خارجي.

‏Next.js 16 يقصر خاصية quality على القيم المذكورة في images.qualities، وقيمتها الافتراضية [75].

عملية تحويل الصورة هي مزيج فريد من الصورة المصدر والعرض والجودة وصيغة الإخراج، لذلك فإن قائمة deviceSizes الواسعة تضاعف التكلفة وعدد مرات فقد الكاش معًا.

لماذا يظل LCP بطيئًا رغم استخدام next/image؟

لأن next/image يؤجل تحميل كل صورة افتراضيًا، بما فيها عنصر Largest Contentful Paint. الصورة المؤجلة لا يُطلب تحميلها إلا بعد أن ينفذ المتصفح التخطيط ويقرر أنها قريبة من نافذة العرض، لذا لا يبدأ ماسح التحميل المسبق تنزيلها أثناء تحليل HTML.

الحل هو خاصية priority مطبَّقة على صورة واحدة فقط في كل صفحة. هي تزيل loading=lazy وتضبط fetchpriority=high وتضيف رابط preload في رأس المستند. وضع priority على ست صور يعادل عدم وضعها إطلاقًا، لأن ست طلبات عالية الأولوية تتنافس على الاتصال نفسه.

هناك فخّان مرتبطان كلّفا فريقنا وقتًا. خيار placeholder=blur يدمج صورة base64 داخل HTML، فالـ blurDataURL الثقيل يزيد حجم المستند على المسار الحرج. كما أن الصورة التي يعرضها مكوّن عميل لا يُركَّب إلا بعد الـ hydration لا يمكن تحميلها مسبقًا مهما كانت قيمة priority، لأن الوسم غير موجود وقت عمل ماسح التحميل المسبق.

ماذا تفعل خاصية sizes فعليًا؟

خاصية sizes تخبر المتصفح بالعرض الذي ستُعرض به الصورة كي يختار نسخة من srcset قبل تطبيق ملفات التنسيق. بدون sizes يولّد Next.js قائمة ثابتة 1x/2x مبنية على قيمة width التي مررتها. ومع sizes يولّد قائمة كاملة مأخوذة من images.deviceSizes (الافتراضي 640 و750 و828 و1080 و1200 و1920 و2048 و3840) ومن images.imageSizes (الافتراضي 16 و32 و48 و64 و96 و128 و256 و384).

خاصية fill بدون sizes تُعامَل على أنها 100vw. على شاشة بعرض 1920 بكسل بنسبة بكسل جهاز 2 يطلب المتصفح ملف 3840 بكسل لبطاقة تُعرض بعرض 400 بكسل. قاعدتنا في المراجعة بسيطة: صورة تستخدم fill بدون sizes هي خلل وليست تفضيلًا شكليًا. القيمة الصحيحة لبطاقة بحد أقصى 400 بكسل تبدو هكذا: (max-width: 640px) 100vw, (max-width: 1024px) 50vw, 400px.

هل نستخدم fill أم width وheight الصريحتين؟

استخدم width وheight الصريحتين كلما كانت الأبعاد الأصلية معروفة، لأن Next.js يحوّلهما إلى aspect-ratio في CSS يحجز المساحة ويبقي Cumulative Layout Shift عند الصفر. الاستيراد الساكن لملف داخل المستودع يوفّر الأبعاد وblurDataURL مولَّدًا وقت البناء.

لا تلجأ إلى fill إلا حين يحدد CSS حجم الصندوق وتتغير نسبة أبعاد المصدر، مثل صور المستخدمين أو صور الغلاف القادمة من نظام إدارة محتوى. خاصية fill تضع الصورة بتموضع مطلق، لذا يحتاج العنصر الأب إلى position relative وارتفاع غير صفري، ويصبح القص مسؤوليتك عبر object-fit.

ما الذي تغيّر في الصور مع Next.js 16؟

شدّد Next.js 16 إعدادات الصور بثلاث طرق تكسر ملفات الإعداد القائمة. أُزيل خيار images.domains لصالح images.remotePatterns. وأصبحت خاصية quality مقصورة على القيم المذكورة في images.qualities التي قيمتها الافتراضية [75]. وأضيف images.localPatterns لتقييد المسارات المحلية التي يقبلها المحسّن، وهذا مهم لأن ‎/_next/image نقطة نهاية عامة يستطيع أي شخص استدعاؤها بوسائط اختيارية.

لا يزال المحسّن يرفض SVG ما لم تضبط dangerouslyAllowSVG على true، وهذا الافتراضي صحيح. ملف SVG مستند قابل للتنفيذ، وتحسين ملف قادم من مصدر غير موثوق يحوّل نطاقك إلى وسيلة توصيل لسكربتاته. قدّم ملفات SVG كأصول ساكنة مع سياسة Content-Security-Policy مشددة بدلًا من ذلك.

هل نضع AVIF أم WebP أولًا في images.formats؟

ضع AVIF أولًا حين يكون عرض النطاق هو القيد، وضع WebP أولًا حين يكون زمن الطلب الأول هو القيد. مصفوفة images.formats مرتبة حسب الأفضلية، والمحسّن يختار أول صيغة يقبلها المتصفح الطالب.

‏AVIF ينتج ملفات أصغر من WebP بجودة بصرية مماثلة لكنه أبطأ بوضوح في الترميز. وWebP أكبر من AVIF وأصغر بكثير من مصدر JPEG، وترميزه سريع. المفاضلة غير متساوية داخل الموقع الواحد: في صفحة تسويقية بخمس صور رئيسية يحمّلها كل زائر، يحدث ترميز AVIF مرة واحدة وتربح البايتات الأصغر دائمًا. أما في كتالوج فيه خمسون ألف صورة منتج تُشاهد أغلبها مرة واحدة، فإن الترميز الأبطأ يقع على الطلب الأول لمستخدم حقيقي.

كيف نضبط تكلفة تحويلات الصور؟

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

قلّص deviceSizes، فثمانية عروض افتراضية مضروبة في صيغتين تعني ستة عشر تحويلًا ممكنًا لكل صورة مصدر؛ إذا كان تخطيطك فيه ثلاث نقاط توقف حقيقية فاذكر ثلاثة عروض. واعتمد قيمة جودة واحدة. وارفع minimumCacheTTL لأن المدة القصيرة تعيد حساب تحويلات دفعت ثمنها بالفعل، مع الانتباه إلى أن Next.js يحترم Cache-Control القادم من المصدر حين يكون أطول، فنظام إدارة محتوى يرسل no-store يبطل الكاش بصمت.

ضع خاصية unoptimized على الأصول المحسّنة مسبقًا مثل صفائح الأيقونات وأيقونات PNG الصغيرة. وانتبه لمعاملات كسر الكاش في الروابط: رابط مصدر يحمل رمزًا متغيرًا يعني صورة مصدر جديدة في كل طلب، وبالتالي تحويلًا جديدًا في كل طلب.

متى نتجاوز next/image تمامًا؟

ثلاث حالات تبرر ترك المكوّن. للإخراج الفني، أي قصّ مختلف على الجوال عنه على سطح المكتب، استدعِ getImageProps() (مستقرة منذ Next.js 15 وكانت تُسمى unstable_getImgProps) للحصول على srcset المولَّد وتمريره إلى عنصر picture أو خلفية CSS. وفي التصدير الساكن لا يوجد خادم لتشغيل المحسّن، لذا يجب ضبط images.unoptimized على true أو توفير محمّل مخصص. وإذا كنت تدفع بالفعل مقابل شبكة صور مثل Cloudinary أو imgix، فوجّه images.loaderFile إليها بدل التحسين مرتين.

للاستضافة الذاتية شرط إضافي: المحسّن المدمج يحتاج حزمة sharp مثبتة. أُزيل البديل المكتوب بجافاسكربت الخالصة في إصدارات سابقة، لذا فإن نشرًا ذاتي الاستضافة بلا sharp يفشل في التحسين بدل أن يتدهور بصمت.

أسئلة شائعة

س: هل نضيف priority لكل صورة فوق طيّة الشاشة؟

ج: لا. أضف priority للصورة الواحدة الأرجح أن تكون عنصر Largest Contentful Paint. تعدد الصور عالية الأولوية يجعلها تتنافس على النطاق وتؤخر الصورة التي تحدد المقياس فعلًا.

س: لماذا تبدو الصورة المحسّنة غير حادة على شاشة Retina؟

ج: ‏Next.js لا يكبّر الصورة أبدًا فوق حجمها الأصلي. إذا طلب المتصفح نسخة بعرض 1600 بكسل وكان المصدر بعرض 800 بكسل، تُعرض 800 بكسل داخل صندوق 1600 بكسل. استبدل ملف المصدر؛ لا يوجد إعداد يصلح ذلك.

س: هل حزمة sharp مطلوبة عند الاستضافة الذاتية؟

ج: نعم. المحسّن المدمج يحتاج حزمة sharp خارج Vercel، حيث توفر المنصة طبقة تحسين خاصة بها.

س: هل يعمل next/image مع output: 'export'؟

ج: ليس مع المحمّل الافتراضي، لأن التصدير الساكن بلا خادم. اضبط images.unoptimized على true لإخراج وسوم img عادية، أو اضبط images.loaderFile ليشير إلى شبكة صور خارجية.

س: هل AVIF هو الخيار الأفضل دائمًا؟

ج: لا. ‏AVIF ينتج ملفات أصغر من WebP بجودة مماثلة لكنه يستغرق وقتًا أطول بوضوح في الترميز، فعلى الصور ذات نسبة إصابة كاش منخفضة يقع ذلك الوقت على الطلب الأول لمستخدم حقيقي.