لقد قضيت السنوات الأربع الماضية في تحسين الصور في تطبيقات Next.js، وسأكون صريحًا -- المشهد في 2026 لا يبدو أبدًا كما كان عندما next/image تم طرحه لأول مرة. تشددت عتبات Core Web Vitals من Google، وقد نضجت صيغ صور جديدة، وقد مرّ مكون next/image نفسه بعمليات إعادة كتابة متعددة. إذا كانت صورك مُعدّة بالطريقة التي كانت عليها في 2023، فأنت تترك الأداء (والترتيبات) على الطاولة.

هذا ليس إعادة صياغة لوثائق Next.js. هذا ما تعلمته من شحن عشرات المواقع الإنتاجية حيث تكون درجات LCP مهمة بالفعل -- حيث كان فرق 200 ميلي ثانية في تحميل الصور يعني الفرق بين الصفحة الأولى والصفحة الثالثة.

جدول المحتويات

تحسين الصور في Next.js لـ Core Web Vitals في 2026

Core Web Vitals في 2026: ما الذي تغيّر

قامت Google بتحديث عتبات Core Web Vitals في أواخر 2025، والتغييرات لم تكن تافهة. إليك الوضع الحالي:

المقياس عتبة "جيدة" في 2023 عتبة "جيدة" في 2026 ما يقيسه
LCP ≤ 2.5s ≤ 2.0s أكبر طلاء محتوى
INP ≤ 200ms ≤ 150ms التفاعل إلى الطلاء التالي
CLS ≤ 0.1 ≤ 0.1 تغيير التخطيط التراكمي
TTFB غير قابل للتطبيق (ليس CWV) بشكل غير رسمي ≤ 600ms الوقت إلى أول بايت

انخفاض عتبة LCP من 2.5 ثانية إلى 2.0 ثانية كان الضربة الأقسى على المواقع الكثيفة الصور. نصف ثانية لا تبدو كبيرة حتى تدرك أنه بالنسبة لـ 60%+ من الصفحات، عنصر LCP هو صورة. عادة ما تكون صورة بطل، أو صورة منتج، أو صورة مصغرة لمقالة مميزة.

استبدال INP بـ FID كان بالفعل قيد التنفيذ، لكن عتبة 150ms المشددة تعني أن حزم JavaScript الثقيلة -- بما في ذلك سكريبتات التحميل البطيء للصور المُعدّة بشكل سيء -- يمكن أن تحطم درجات التفاعل الخاصة بك.

بقي CLS على حاله، وهذه أخبار جيدة. لكن الصور تبقى السبب الأول لتغيير التخطيط عندما لا تحتوي على أبعاد صريحة.

لماذا هذا مهم بالتحديد لـ Next.js

تطبيقات Next.js تميل إلى أن تكون ثقيلة من حيث JavaScript بطبيعتها. أنت تشحن React، أنت تشحن كود الإطار، وإذا لم تكن حذرًا، فأنت تشحن منطق تحسين الصور من جانب العميل أيضًا. الجمع بين ميزانية LCP أكثر صرامة والحمل الكبير من JS لتطبيق React يعني أن لديك مجال خطأ أقل من موقع HTML ثابت.

هذا بالضبط السبب في أننا نركز بشكل كبير على تطوير Next.js -- الإطار يعطيك أدوات لا تصدق، لكن فقط إذا كنت تعرف كيفية تكوينها.

كيف يعمل next/image تحت الغطاء

دعنا نوضح ما يحدث عندما تستخدم <Image /> من next/image. فهم خط الأنابيب يساعدك على اتخاذ قرارات تحسين أفضل.

تدفق الطلب

  1. وقت البناء: Next.js ينشئ HTML مع علامة <img> تشير إلى /_next/image?url=...&w=...&q=...
  2. الطلب الأول: تتلقى API تحسين الصور في Next.js الطلب، وتجلب الصورة الأصلية، وتغيير حجمها، وتحويل الصيغة، وتخزن النتيجة مؤقتًا
  3. الطلبات اللاحقة: يتم تقديم النسخة المخزنة مؤقتًا مباشرة

في Next.js 15 (المستقر الحالي اعتبارًا من أوائل 2026)، يستخدم محسّن الصور sharp بشكل افتراضي في بيئات Node.js. على Vercel، يستخدمون خدمة تحسين الصور المستندة إلى الحافة الخاصة بهم. على الأنظمة الأخرى، يرجع إلى sharp أو squoosh اعتمادًا على إعدادك.

// الاستخدام الأساسي -- لكن هناك الكثير يحدث تحت هذا
import Image from 'next/image';

export default function Hero() {
  return (
    <Image
      src="/hero.jpg"
      alt="Product hero shot"
      width={1200}
      height={630}
      priority
      quality={80}
    />
  );
}

هذا الـ priority prop يفعل أكثر مما تعتقد. إنه يضيف fetchpriority="high" إلى HTML، ويعطل التحميل البطيء، وينشئ علامة <link> preload في <head>. سنعود إلى سبب أهمية هذا لـ LCP.

الإعداد الذي لا يلمسه معظم الناس

ملف next.config.js الخاص بك (أو next.config.ts إذا هاجرت) به مفتاح images يتحكم في كل شيء:

// next.config.js
module.exports = {
  images: {
    formats: ['image/avif', 'image/webp'],
    deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048],
    imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
    minimumCacheTTL: 31536000, // 1 year in seconds
    dangerouslyAllowSVG: false,
    remotePatterns: [
      {
        protocol: 'https',
        hostname: 'your-cms.com',
        pathname: '/assets/**',
      },
    ],
  },
};

ترتيب مصفوفة formats مهم. سيحاول Next.js AVIF أولاً، ثم العودة إلى WebP. ترميز AVIF أبطأ لكنه ينتج ملفات أصغر -- هذا الحل الوسط يستحق الفهم.

مشكلة LCP: لماذا تقتل صورة البطل درجتك

إليك السيناريو الذي أراه في تقريبًا كل عملية تدقيق: صورة بطل جميلة، فوق الطي، تستغرق أكثر من 3 ثوان للطلاء. استخدم المطور next/image، ظن أنهم انتهوا، وتابعوا. لكن الدرجة سيئة.

المرتكبون المعتادون:

1. غياب الـ `priority` Prop

بشكل افتراضي، next/image يحمّل كل شيء بشكل بطيء. هذا رائع للصور تحت الطي ولكنه كارثي لعنصر LCP الخاص بك. بدون priority، يكتشف المتصفح الصورة في وقت لاحق، بعد أن يتم تحديث JavaScript وتفعيل intersection observer.

// ❌ هذا يحمّل صورة LCP الخاصة بك بشكل بطيء
<Image src="/hero.jpg" alt="Hero" width={1200} height={630} />

// ✅ هذا يحملها مسبقًا
<Image src="/hero.jpg" alt="Hero" width={1200} height={630} priority />

2. الضغط الزائد بقيم جودة منخفضة

شاهدت فرقًا تضع quality={50} ظنًا منهم أن أصغر = أسرع. لكن إذا بدت الصورة ضبابية، فلا يزال يتعين على خوارزمية LCP في Chrome الانتظار حتى تطلى بالكامل. وعلى الشاشات عالية الدقة، غالبًا ما تؤدي الجودة أقل من 70 إلى حدوث اختيارات مرئية تجعل التصميم يبدو رخيصًا.

قاعدتي: جودة 75-85 للصور، جودة 90+ للصور التي تحتوي على نص أو حواف حادة.

3. عدم استخدام `sizes` بشكل صحيح

تخبر سمة sizes المتصفح بأي عرض صور طلبه قبل تحليل CSS. بدونها، يفترض Next.js الافتراضي 100vw، مما يعني أن أجهزة الجوال تحمّل صور بحجم سطح المكتب.

<Image
  src="/hero.jpg"
  alt="Hero"
  fill
  priority
  sizes="(max-width: 768px) 100vw, (max-width: 1200px) 80vw, 1200px"
/>

أحدثت هذه الـ prop الواحدة أكبر تحسينات LCP لدي -- أحيانًا 400-800 ميلي ثانية على الجوال.

تحسين الصور في Next.js لـ Core Web Vitals في 2026 - العمارة

حروب الصيغ: AVIF مقابل WebP مقابل JPEG XL في 2026

قد استقر مشهد الصيغة بشكل كبير. إليك حيث نحن:

الصيغة دعم المتصفح (2026) الضغط سرعة الترميز الأفضل لـ
AVIF ~95% عالميًا ممتاز (أصغر 30-50% من WebP) بطيء الصور، صور البطل
WebP ~98% عالميًا جيد (أصغر 25-35% من JPEG) سريع الاستخدام العام
JPEG XL ~45% (أسقط Chrome دعمه) ممتاز متوسط غير موصى به للويب
JPEG عالمي الخط الأساسي سريع البديل فقط
PNG عالمي سيء للصور سريع الشفافية، لقطات الشاشة

كان JPEG XL يحمل مواصفات واعدة، لكن قرار Chrome بإزالة الدعم في أواخر 2023 قضى فعليًا عليه للاستخدام على الويب. أضافت Safari الدعم، Firefox لديه دعم جزئي، لكن لا يمكنك الاعتماد عليه.

توصيتي: اضبط formats: ['image/avif', 'image/webp'] وانسَ الأمر. يتعامل Next.js مع المفاوضة حول المحتوى تلقائيًا من خلال رأس Accept.

تكلفة ترميز AVIF

إليك شيء لا تشدد الوثائق عليه بما فيه الكفاية: ترميز AVIF يتطلب موارد CPU كثيرة. في أول طلب لخادم Next.js الخاص بك، قد يستغرق ترميز صورة AVIF بحجم 1200px من 2-5 ثوان على خادم متواضع. الزائر الأول يتحمل التكلفة.

استراتيجيات للتخفيف من هذا:

  • ما قبل التوليد عند وقت البناء باستخدام next export أو سكريبتات البناء المخصصة
  • استخدم CDN مع تحسين صور مدمج (Cloudflare Images, Imgix, Cloudinary)
  • دفء ذاكرة التخزين المؤقت بعد النشر باستخدام سكريبت يضرب جميع عناوين URL الصور الحرجة
# سكريبت تدفئة ذاكرة التخزين المؤقت البسيط
#!/bin/bash
URLs=("https://yoursite.com/_next/image?url=%2Fhero.jpg&w=1200&q=80"
      "https://yoursite.com/_next/image?url=%2Fhero.jpg&w=750&q=80")

for url in "${URLs[@]}"; do
  curl -s -o /dev/null -H "Accept: image/avif,image/webp" "$url"
  echo "Warmed: $url"
done

الصور المتجاوبة كما يجب

الصور المتجاوبة في Next.js ليست صعبة، لكنها تتطلب فهم كيفية عمل deviceSizes و imageSizes وـ sizes prop معًا.

نمط تخطيط `fill`

بالنسبة للصور حيث لا تعرف نسبة العرض إلى الارتفاع عند وقت البناء (محتوى CMS، تحميلات المستخدم)، استخدم الـ fill prop:

<div className="relative aspect-[16/9] w-full">
  <Image
    src={post.featuredImage}
    alt={post.title}
    fill
    className="object-cover"
    sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
  />
</div>

الـ div الأب مع موضع relative ونسبة عرض إلى ارتفاع أمر بالغ الأهمية. بدونها، صور fill تنهار إلى ارتفاع صفر وتحصل على درجة CLS ستجعلك تتألم.

توجيه الفن باستخدام ``

أحيانًا تحتاج إلى محاصيل مختلفة لأحجام شاشة مختلفة. next/image لا يدعم <picture> بشكل أصلي، لكن يمكنك إيجاد حل بديل:

// حل بديل لتوجيه الفن
export function ResponsiveHero({ mobileSrc, desktopSrc, alt }) {
  return (
    <>
      <div className="block md:hidden relative aspect-[9/16] w-full">
        <Image src={mobileSrc} alt={alt} fill priority sizes="100vw" />
      </div>
      <div className="hidden md:block relative aspect-[16/9] w-full">
        <Image src={desktopSrc} alt={alt} fill priority sizes="100vw" />
      </div>
    </>
  );
}

نعم، هذا يحمّل HTML لكلا الصورتين، لكن واحدة فقط تعرض، والصورة المخفية لن تحمّل بفضل افتراضات التحميل البطيء (ستطبق priority فقط على المطابقة لـ viewport).

استراتيجيات تحسين CDN والحافة

إذا كنت تاستضيف ذاتيًا Next.js (وعدد من الفرق هي كذلك)، فأنت تحتاج إلى استراتيجية CDN للصور.

الخيار 1: دع Vercel يتعامل معها

يعمل تحسين الصور في Vercel عند الحافة. بالنسبة لمعظم المشاريع، هذا هو الطريق الأسهل. اعتبارًا من 2026، يتضمن خطة Vercel Pro صور مصدر 5000 مع التحسين، مع صور إضافية بسعر 5 دولارات لكل 1000. تتمتع خطط Enterprise برعاية مخصصة.

الخيار 2: خدمة تحسين صور خارجية

يعمل Cloudinary و Imgix و Cloudflare Images مع Next.js من خلال الـ loader prop أو محمل مخصص:

// next.config.js مع Cloudinary
module.exports = {
  images: {
    loader: 'custom',
    loaderFile: './lib/cloudinary-loader.js',
  },
};
// lib/cloudinary-loader.js
export default function cloudinaryLoader({ src, width, quality }) {
  const params = [
    `w_${width}`,
    `q_${quality || 'auto'}`,
    'f_auto',
    'c_limit',
  ];
  return `https://res.cloudinary.com/your-cloud/image/upload/${params.join(',')}${src}`;
}
الخدمة الطبقة المجانية تسعير Pro (2026) عقد الحافة دعم AVIF
Cloudinary 25 رصيد/شهر $89/شهر (25GB) 60+ نعم
Imgix لا شيء $100/شهر (100GB) عالمي نعم
Cloudflare Images لا شيء $5/شهر (100K متغيرات) 310+ نعم
Vercel (مدمج) 1000 صورة (Hobby) مضمن في Pro الحافة نعم

بالنسبة لمشاريع تطوير CMS بدون رأس الخاصة بنا، نستخدم عادة Cloudinary أو خط أنابيب الصور المدمج في CMS (لـ Sanity و Contentful و Hygraph جميعهم لديهم APIs صور لائقة).

الخيار 3: Cloudflare Polish + Next.js

إذا كنت بالفعل خلف Cloudflare، يمكن لميزة Polish الخاصة بهم التعامل مع تحويل الصيغة عند الحافة. ستعطل تحسين الصور في Next.js واترك Cloudflare يفعل الشغل:

module.exports = {
  images: {
    unoptimized: true, // دع Cloudflare يتعامل معها
  },
};

لست كبير معجب بهذا النهج لأنك تفقد التحجيم المتجاوب الذي يوفره next/image، لكنه يعمل مع الإعدادات الأبسط.

قياس ما يهم: الأدوات والمعايير

لا يمكنك تحسين ما لا تقيسه. إليك مكدس الاختبار الخاص بي:

أدوات المختبر

  • Chrome DevTools Lighthouse (v12 اعتبارًا من 2026): لا يزال نقطة البداية. قم بتشغيله في الوضع الخفي بدون ملحقات.
  • WebPageTest: اضبطه على Dulles، VA على جهاز Moto G Power بـ 4G. هذا يمثل مستخدمًا "بطيئًا" واقعيًا.
  • Unlighthouse: فحص شامل لموقعك بالكامل. مذهل لاكتشاف الصفحات التي نسيتها.

بيانات الحقل

  • Chrome UX Report (CrUX): البيانات الفعلية التي تستخدمها Google لإشارات الترتيب. متاح في PageSpeed Insights و BigQuery.
  • web-vitals.js: أضفه إلى تطبيقك لجمع قياسات المستخدم الحقيقي:
// app/layout.tsx
import { onLCP, onINP, onCLS } from 'web-vitals';

if (typeof window !== 'undefined') {
  onLCP(console.log);
  onINP(console.log);
  onCLS(console.log);
}

في الإنتاج، أرسل هذه إلى منصة التحليلات الخاصة بك بدلاً من console.log. نستخدم مزيجًا من Vercel Speed Insights ونقطة نهاية مخصصة تكتب إلى BigQuery.

أهداف المعايير لـ 2026

بناءً على المواقع التي قمنا بتدقيقها هذا العام، إليك ما يبدو عليه "جيد" لمواقع Next.js الكثيفة الصور:

  • LCP على الجوال (p75): < 1.8s (يعطيك حاشية تحت عتبة 2.0s)
  • إجمالي وزن الصور فوق الطي: < 200KB
  • وقت تحميل الصورة البطل: < 800ms على 4G
  • CLS من الصور: 0

تقنيات متقدمة تحرك الإبرة فعلاً

عناصر نائبة ضبابية باستخدام BlurHash

يدعم Next.js placeholder="blur" بشكل أصلي للواردات الثابتة. بالنسبة للصور الديناميكية (من CMS)، ستحتاج إلى توليد عناوين URL بيانات ضبابية:

import { getPlaiceholder } from 'plaiceholder';

export async function getStaticProps() {
  const { base64 } = await getPlaiceholder('/path/to/image.jpg');
  return {
    props: { blurDataURL: base64 },
  };
}

// في المكون
<Image
  src={dynamicUrl}
  alt="Dynamic image"
  fill
  placeholder="blur"
  blurDataURL={blurDataURL}
/>

هذا لا يحسن LCP مباشرة، لكنه يحسن بشكل دراماتيكي الأداء المتصورة ويمنع CLS.

HTTP/3 و Early Hints

إذا كان CDN الخاص بك يدعم HTTP/3 (Cloudflare و Fastly و Vercel جميعهم يفعلون)، يمكنك استخدام 103 Early Hints لبدء إرسال صورة LCP قبل أن يتم حتى توليد وثيقة HTML بالكامل:

// middleware.ts
import { NextResponse } from 'next/server';

export function middleware(request) {
  const response = NextResponse.next();
  
  if (request.nextUrl.pathname === '/') {
    response.headers.set(
      'Link',
      '</hero.avif>; rel=preload; as=image; type="image/avif"'
    );
  }
  
  return response;
}

تحميل الهياكل العظمية باستخدام CSS `content-visibility`

بالنسبة للصفحات الطويلة التي تحتوي على العديد من الصور، يخبر content-visibility: auto المتصفح بتخطي عرض محتوى خارج الشاشة تمامًا:

.image-grid-item {
  content-visibility: auto;
  contain-intrinsic-size: 300px 200px; /* حجم مقدر */
}

قلل هذا INP بـ 30-40 ميلي ثانية على صفحة قائمة منتجات قمنا بتحسينها الربع الماضي.

الأخطاء الشائعة التي أراها في كل عملية تدقيق

  1. استخدام next/image للصور الزخرفية SVG: فقط استخدم علامة <img> أو ضمّن SVG. يضيف خط الأنابيب النفقات العامة بدون فائدة.

  2. ضبط unoptimized عالميًا لأن "الصور تبدو ضبابية": بدلاً من ذلك، أصلح إعداد الجودة. unoptimized يلغي كل شيء.

  3. نسيان نص alt: هذا ليس فقط إمكانية الوصول -- بحث صور Google يدفع حركة المرور، ويحتاج إلى نص alt لفهرسة صورك.

  4. عدم تعيين minimumCacheTTL: الافتراضي هو 60 ثانية. هذا يعني أن الخادم يعيد تحسين نفس الصورة كل دقيقة تحت الحمل. اضبطه على الأقل 2592000 (30 يومًا).

  5. استخدام صور مصدر ضخمة: تحميل صورة DSLR 6000x4000px والتوقع من Next.js أن يتعامل معها. معالجة مسبقة لصور المصدر الخاصة بك إلى أقصى 2x أكبر حجم عرض لديك.

  6. تجاهل علامة التبويب الشبكة: افتح DevTools، صفّي بـ Img، رتّب حسب الحجم. ستجد المشاكل في 30 ثانية.

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

الأسئلة الشائعة

هل يقوم next/image تلقائيًا بتحويل الصور إلى AVIF؟ نعم، إذا كان لديك 'image/avif' في مصفوفة images.formats في next.config.js (يتم تضمينها افتراضيًا منذ Next.js 14). يحدث التحويل عند الطلب عندما يرسل متصفح رأس Accept يتضمن image/avif. الطلب الأول أبطأ بسبب الترميز، لكن الطلبات اللاحقة تُقدم من الذاكرة المؤقتة.

كم ينخفض حجم ملف AVIF فعليًا مقارنة بـ WebP؟ في اختبارنا عبر مئات من الصور الإنتاجية، يبلغ AVIF بمعدل 30-50% أصغر من WebP بجودة بصرية معادلة، و 50-70% أصغر من JPEG. الفوائد الأكثر درامية على المحتوى الفوتوغرافي. بالنسبة للقطات الشاشة أو الصور التي تحتوي على نص، ينخفض الفارق إلى 15-25%.

هل يجب أن أستخدم priority على صور متعددة؟ استخدمها بشكل متناثر -- فقط على الصور التي تكون فوق الطي بحق وظاهرة على التحميل الأولي. إضافة priority إلى أكثر من 2-3 صور يُلغي الغرض لأن المتصفح لا يمكنه إعطاء الأولوية لكل شيء في نفس الوقت. بالنسبة إلى بطل الصفحة الرئيسية وربما شعار، فقط هذا.

لماذا يكون LCP الخاص بي بطيئًا حتى مع next/image و priority؟ السبب الأكثر شيوعًا هو أن وقت استجابة الخادم (TTFB) يأكل في ميزانيتك. إذا استغرق خادم Next.js 800 ميلي ثانية للرد، فلديك فقط 1.2 ثانية متبقية لتحميل الصورة وطلاءها. المرتكبون الآخرون: CSS محظور العرض، حزم JavaScript كبيرة تؤخر hydration، أو مصدر الصورة على خادم بطيء.

هل يمكنني استخدام next/image مع التصدير الثابت (next export)؟ ليس مع التحسين المدمج. يتطلب التصدير الثابت images.unoptimized: true أو محمل مخصص يشير إلى خدمة خارجية مثل Cloudinary أو Imgix. هذا أحد الأسباب التي تجعلنا أحيانًا ننصح بـ Astro للمواقع الثابتة تمامًا -- معالجة الصور الخاصة به لا تتطلب خادمًا قيد التشغيل.

كيف أتعامل مع الصور من CMS بدون رأس باستخدام next/image؟ أضف مجال الصور في CMS إلى images.remotePatterns في الإعداد الخاص بك. معظم منصات CMS بدون رأس (Sanity, Contentful, Storyblok, Hygraph) لديها APIs تحويل صور خاصة بها. يمكنك إما استخدام تلك من خلال محمل مخصص أو السماح لـ Next.js بالتعامل مع التحسين. نفضل عادة خط أنابيب CMS الأصلي لمشاريع CMS بدون رأس لأنه يقلل من حمل الخادم.

ما هي تأثير تحسين الصور على إشارات ترتيب Core Web Vitals؟ أكدت Google في 2025 أن Core Web Vitals تبقى إشارة ترتيب، على الرغم من أن صلة المحتوى لا تزال تهيمن. ومع ذلك، بالنسبة للاستعلامات التنافسية حيث تكون جودة المحتوى متشابهة عبر النتائج الأعلى، يمكن أن تكون CWV هي الفاصل. شهدنا مواقع تتحرك 3-8 مراكز بعد إصلاح مشاكل LCP التي كانت بسبب الصور غير المحسّنة في الغالب.

هل يجب أن أحمل كل الصور أسفل الطي بشكل بطيء؟ نعم، و Next.js يفعل هذا افتراضيًا (ما لم تضيف priority). سمة loading="lazy" الأصلية هي ما يستخدمه next/image تحت الغطاء. لا حاجة لمكتبة تحميل بطيء قائمة على JavaScript بعد الآن -- تحميل بطيء أصلي للمتصفح كان مستقرًا عبر جميع المتصفحات الرئيسية منذ 2022.