Backالعودة إلى المدونة

Next.js 14

يتضمن Next.js 14 تحسينات في الأداء، واستقرارًا لإجراءات الخادم (Server Actions)، ودورة تدريبية جديدة لتدريس موجه التطبيق (App Router)، والمزيد.

كما أعلنا في Next.js Conf، يُعد Next.js 14 إصدارنا الأكثر تركيزًا مع:

  • Turbopack: اجتياز 5000 اختبار لموجه التطبيق (App Router) وموجه الصفحات (Pages Router)
    • أسرع بنسبة 53% في بدء الخادم المحلي
    • أسرع بنسبة 94% في تحديثات الكود مع Fast Refresh
  • إجراءات الخادم - Server Actions (مستقرة): تحسينات تدريجية للطفرات (mutations)
    • متكاملة مع التخزين المؤقت وإعادة التحقق
    • استدعاءات دوال بسيطة، أو تعمل بشكل أصلي مع النماذج
  • التصيير الجزئي المسبق - Partial Prerendering (معاينة): استجابة ثابتة أولية سريعة + بث محتوى ديناميكي
  • Next.js Learn (جديد): دورة تدريبية مجانية لتدريس موجه التطبيق (App Router)، والمصادقة، وقواعد البيانات، والمزيد.

قم بالترقية اليوم أو ابدأ باستخدام:

Terminal
npx create-next-app@latest

محرك Next.js: معزز بقوة

منذ Next.js 13، كنا نعمل على تحسين أداء التطوير المحلي في Next.js لكل من موجه الصفحات (Pages Router) وموجه التطبيق (App Router).

سابقًا، كنا نعيد كتابة next dev وأجزاء أخرى من Next.js لدعم هذا الجهد. منذ ذلك الحين، غيرنا نهجنا ليكون أكثر تدرجًا. هذا يعني أن محررنا القائم على Rust سيصل قريبًا إلى الاستقرار، حيث ركزنا مجددًا على دعم جميع ميزات Next.js أولاً.

تم الآن اجتياز 5000 اختبار تكامل لـ next dev باستخدام Turbopack، محرك Rust الأساسي لدينا. تتضمن هذه الاختبارات إصلاحات وإعادة إنتاج للأخطاء على مدى 7 سنوات.

أثناء الاختبار على vercel.com، وهو تطبيق Next.js كبير، لاحظنا:

  • أسرع بنسبة تصل إلى 53.3% في بدء الخادم المحلي
  • أسرع بنسبة تصل إلى 94.7% في تحديثات الكود مع Fast Refresh

هذا المعيار هو نتيجة عملية لتحسينات الأداء التي يمكنك توقعها مع تطبيق كبير (ومخطط وحدة كبير). مع اجتياز 90% من اختبارات next dev الآن، يجب أن تلاحظ أداءً أسرع وأكثر موثوقية باستمرار عند استخدام next dev --turbo.

بمجرد اجتياز 100% من الاختبارات، سننقل Turbopack إلى وضع المستقر في إصدار صغير قادم. سنواصل أيضًا دعم استخدام webpack للتكوينات المخصصة وملحقات النظام البيئي.

يمكنك متابعة نسبة الاختبارات التي تم اجتيازها على areweturboyet.com.

النماذج والطفرات

قدم Next.js 9 مسارات API - طريقة لبناء نقاط نهاية خلفية بسرعة بجانب كود الواجهة الأمامية.

على سبيل المثال، يمكنك إنشاء ملف جديد في دليل api/:

pages/api/submit.ts
import type { NextApiRequest, NextApiResponse } from 'next';
 
export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse,
) {
  const data = req.body;
  const id = await createItem(data);
  res.status(200).json({ id });
}

ثم، على جانب العميل، يمكنك استخدام React ومعالج الأحداث مثل onSubmit لإجراء fetch إلى مسار API الخاص بك.

pages/index.tsx
import { FormEvent } from 'react';
 
export default function Page() {
  async function onSubmit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
 
    const formData = new FormData(event.currentTarget);
    const response = await fetch('/api/submit', {
      method: 'POST',
      body: formData,
    });
 
    // التعامل مع الاستجابة إذا لزم الأمر
    const data = await response.json();
    // ...
  }
 
  return (
    <form onSubmit={onSubmit}>
      <input type="text" name="name" />
      <button type="submit">Submit</button>
    </form>
  );
}

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

إجراءات الخادم - Server Actions (مستقرة)

ماذا لو لم تكن بحاجة إلى إنشاء مسار API يدويًا؟ بدلاً من ذلك، يمكنك تحديد دالة تعمل بأمان على الخادم، يتم استدعاؤها مباشرة من مكونات React الخاصة بك.

تم بناء موجه التطبيق (App Router) على قناة React canary، التي مستقرة للأطر لاعتماد الميزات الجديدة. اعتبارًا من الإصدار 14، قام Next.js بالترقية إلى أحدث React canary، الذي يتضمن إجراءات خادم مستقرة.

يمكن تبسيط المثال السابق من موجه الصفحات (Pages Router) إلى ملف واحد:

app/page.tsx
export default function Page() {
  async function create(formData: FormData) {
    'use server';
    const id = await createItem(formData);
  }
 
  return (
    <form action={create}>
      <input type="text" name="name" />
      <button type="submit">Submit</button>
    </form>
  );
}

يجب أن تبدو إجراءات الخادم مألوفة لأي مطورين استخدموا أطر عمل مركزة على الخادم في الماضي. إنها مبنية على أساسيات الويب مثل النماذج وواجهة برمجة تطبيقات FormData.

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

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

التخزين المؤقت، إعادة التحقق، إعادة التوجيه، والمزيد

إجراءات الخادم متكاملة بعمق في نموذج موجه التطبيق (App Router) بأكمله. يمكنك:

  • إعادة التحقق من البيانات المخزنة مؤقتًا باستخدام revalidatePath() أو revalidateTag()
  • إعادة التوجيه إلى مسارات مختلفة عبر redirect()
  • تعيين وقراءة ملفات تعريف الارتباط عبر cookies()
  • التعامل مع تحديثات واجهة المستخدم المتفائلة باستخدام useOptimistic()
  • التقاط وعرض الأخطاء من الخادم باستخدام useFormState()
  • عرض حالات التحميل على العميل باستخدام useFormStatus()

تعلم المزيد عن النماذج والطفرات مع إجراءات الخادم أو عن نموذج الأمان وأفضل الممارسات لمكونات الخادم وإجراءات الخادم.

التصيير الجزئي المسبق - Partial Prerendering (معاينة)

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

يبني التصيير الجزئي المسبق على عقد من البحث والتطوير في عرض جانب الخادم (SSR)، وتوليد الموقع الثابت (SSG)، وإعادة التحقق الثابت التدريجي (ISR).

الدافع

لقد سمعنا ملاحظاتكم. هناك حاليًا الكثير من أوقات التشغيل، وخيارات التكوين، وطرق العرض التي يجب مراعاتها. تريد السرعة والموثوقية من الثابت، مع دعم الاستجابات الديناميكية المخصصة بالكامل.

لا ينبغي أن تأتي الأداء الرائع عالميًا والتخصيص على حساب التعقيد.

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

لا يتطلب التصيير الجزئي المسبق تعلم واجهات برمجة تطبيقات جديدة.

مبني على React Suspense

يتم تعريف التصيير الجزئي المسبق من خلال حدود Suspense الخاصة بك. إليك كيف يعمل. ضع في اعتبارك صفحة التجارة الإلكترونية التالية:

app/page.tsx
export default function Page() {
  return (
    <main>
      <header>
        <h1>My Store</h1>
        <Suspense fallback={<CartSkeleton />}>
          <ShoppingCart />
        </Suspense>
      </header>
      <Banner />
      <Suspense fallback={<ProductListSkeleton />}>
        <Recommendations />
      </Suspense>
      <NewProducts />
    </main>
  );
}

مع تمكين التصيير الجزئي المسبق، تنشئ هذه الصفحة غلافًا ثابتًا بناءً على حدود <Suspense /> الخاصة بك. يتم تصيير fallback من React Suspense مسبقًا.

ثم يتم استبدال حالات السقوط في Suspense في الغلاف بمكونات ديناميكية، مثل قراءة ملفات تعريف الارتباط لتحديد عربة التسوق، أو عرض لافتة بناءً على المستخدم.

عند تقديم طلب، يتم تقديم غلاف HTML الثابت على الفور:

<main>
  <header>
    <h1>My Store</h1>
    <div class="cart-skeleton">
      <!-- Hole -->
    </div>
  </header>
  <div class="banner" />
  <div class="product-list-skeleton">
    <!-- Hole -->
  </div>
  <section class="new-products" />
</main>

بما أن <ShoppingCart /> يقرأ من cookies للنظر في جلسة المستخدم، يتم بث هذا المكون بعد ذلك كجزء من نفس طلب HTTP مثل الغلاف الثابت. لا توجد حاجة لرحلات شبكة إضافية.

app/cart.tsx
import { cookies } from 'next/headers'
 
export default function ShoppingCart() {
  const cookieStore = cookies()
  const session = cookieStore.get('session')
  return ...
}

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

قريبًا

التصيير الجزئي المسبق قيد التطوير النشط. سنشارك المزيد من التحديثات في إصدار صغير قادم.

تحسينات البيانات الوصفية

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

ضمان إرسال علامات meta هذه مع المحتوى الأولي للصفحة يساعد في تجربة مستخدم سلسة، ويمنع وميض الصفحة بسبب تغيير لون السمة، أو تغيير التخطيط بسبب تعديلات نافذة العرض.

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

أصبحت خيارات البيانات الوصفية التالية مهملة وسيتم إزالتها من metadata في إصدار رئيسي مستقبلي:

  • viewport: يضبط مستوى التكبير الأولي وخصائص أخرى لنافذة العرض
  • colorScheme: يحدد أوضاع الدعم (فاتح/غامق) لنافذة العرض
  • themeColor: يحدد اللون الذي يجب أن يعرض به الإطار حول نافذة العرض

بدءًا من Next.js 14، هناك خيارات جديدة viewport و generateViewport لاستبدال هذه الخيارات. جميع خيارات metadata الأخرى تبقى كما هي.

يمكنك البدء في اعتماد واجهات برمجة التطبيقات الجديدة هذه اليوم. خيارات metadata الحالية ستستمر في العمل.

دورة تعلم Next.js

اليوم نطلق دورة جديدة كليًا ومجانية على Next.js Learn. هذه الدورة تعلم:

  • موجه تطبيق Next.js
  • التنسيق و Tailwind CSS
  • تحسين الخطوط والصور
  • إنشاء تخطيطات وصفحات
  • التنقل بين الصفحات
  • إعداد قاعدة بيانات Postgres الخاصة بك
  • جلب البيانات مع مكونات الخادم
  • التصيير الثابت والديناميكي
  • البث
  • التصيير الجزئي المسبق (اختياري)
  • إضافة البحث والترقيم
  • تحوير البيانات
  • معالجة الأخطاء
  • تحسين إمكانية الوصول
  • إضافة المصادقة
  • إضافة البيانات الوصفية

علمت Next.js Learn ملايين المطورين أساسيات الإطار، ولا يمكننا الانتظار لسماع ملاحظاتكم على إضافتنا الجديدة. توجه إلى nextjs.org/learn لأخذ الدورة.

تغييرات أخرى

  • [تغيير رئيسي] الحد الأدنى لإصدار Node.js أصبح الآن 18.17
  • [تغيير رئيسي] إزالة هدف WASM لبناء next-swc (PR)
  • [تغيير رئيسي] إيقاف دعم @next/font لصالح next/font (أداة تحويل الأكواد)
  • [تغيير رئيسي] تغيير استيراد ImageResponse من next/server إلى next/og (أداة تحويل الأكواد)
  • [تغيير رئيسي] أمر next export تمت إزالته لصالح output: 'export' في الإعدادات (المستندات)
  • [إهمال] onLoadingComplete لـ next/image أصبح مهملاً لصالح onLoad
  • [إهمال] domains لـ next/image أصبح مهملاً لصالح remotePatterns
  • [ميزة] يمكن تفعيل تسجيل أكثر تفصيلاً حول تخزين fetch (المستندات)
  • [تحسين] حجم دالة أصغر بنسبة 80% لتطبيق أساسي تم إنشاؤه بـ create-next-app
  • [تحسين] تحسين إدارة الذاكرة عند استخدام edge runtime في وضع التطوير

المساهمون

Next.js هي نتيجة العمل المشترك لأكثر من 2900 مطور فردي، شركاء صناعيين مثل Google و Meta، وفريقنا الأساسي في Vercel. انضم إلى المجتمع على GitHub Discussions، Reddit، و Discord.

هذا الإصدار تم بفضل:

ومساهمات: @05lazy، @0xadada، @2-NOW، @aarnadlr، @aaronbrown-vercel، @aaronjy، @abayomi185، @abe1272001، @abhiyandhakal، @abstractvector، @acdlite، @adamjmcgrath، @AdamKatzDev، @adamrhunter، @ademilter، @adictonator، @adilansari، @adtc، @afonsojramos، @agadzik، @agrattan0820، @akd-io، @AkifumiSato، @akshaynox، @alainkaiser، @alantoa، @albertothedev، @AldeonMoriak، @aleksa-codes، @alexanderbluhm، @alexkirsz، @alfred-mountfield، @alpha-xek، @andarist، @Andarist، @andrii-bodnar، @andykenward، @angel1254mc، @anonrig، @anthonyshew، @AntoineBourin، @anujssstw، @apeltop، @aralroca، @aretrace، @artdevgame، @artechventure، @arturbien، @Aryan9592، @AviAvinav، @aziyatali، @BaffinLee، @Banbarashik، @bencmbrook، @benjie، @bennettdams، @bertho-zero، @bigyanse، @Bitbbot، @blue-devil1134، @bot08، @bottxiang، @Bowens20832، @bre30kra69cs، @BrennanColberg، @brkalow، @BrodaNoel، @Brooooooklyn، @brunoeduardodev، @brvnonascimento، @carlos-menezes، @cassidoo، @cattmote، @cesarkohl، @chanceaclark، @charkour، @charlesbdudley، @chibicode، @chrisipanaque، @ChristianIvicevic، @chriswdmr، @chunsch، @ciruz، @cjmling، @clive-h-townsend، @colinhacks، @colinking، @coreyleelarson، @Cow258، @cprussin، @craigwheeler، @cramforce، @cravend، @cristobaldominguez95، @ctjlewis، @cvolant، @cxa، @danger-ahead، @daniel-web-developer، @danmindru، @dante-robinson، @darshanjain-entrepreneur، @darshkpatel، @davecarlson، @David0z، @davidnx، @dciug، @delbaoliveira، @denchance، @DerTimonius، @devagrawal09، @DevEsteves، @devjiwonchoi، @devknoll، @DevLab2425، @devvspaces، @didemkkaslan، @dijonmusters، @dirheimerb، @djreillo، @dlehmhus، @doinki، @dpnolte، @Drblessing، @dtinth، @ducanhgh، @DuCanhGH، @ductnn، @duncanogle، @dunklesToast، @DustinsCode، @dvakatsiienko، @dvoytenko، @dylanjha، @ecklf، @EndangeredMassa، @eps1lon، @ericfennis، @escwxyz، @Ethan-Arrowood، @ethanmick، @ethomson، @fantaasm، @feikerwu، @ferdingler، @FernandVEYRIER، @feugy، @fgiuliani، @fomichroman، @Fonger، @ForsakenHarmony، @franktronics، @FSaldanha، @fsansalvadore، @furkanmavili، @g12i، @gabschne، @gaojude، @gdborton، @gergelyke، @gfgabrielfranca، @gidgudgod، @Gladowar، @Gnadhi، @gnoff، @goguda، @greatSumini، @gruz0، @Guilleo03، @gustavostz، @hanneslund، @HarshaVardhanReddyDuvvuru، @haschikeks، @Heidar-An، @heyitsuzair، @hiddenest، @hiro0218، @hotters، @hsrvms، @hu0p، @hughlilly، @HurSungYun، @hustLer2k، @iamarpitpatidar، @ianldgs، @ianmacartney، @iaurg، @ibash، @ibrahemid، @idoob، @iiegor، @ikryvorotenko، @imranbarbhuiya، @ingovals، @inokawa، @insik-han، @isaackatayev، @ishaqibrahimbot، @ismaelrumzan، @itsmingjie، @ivanhofer، @IvanKiral، @jacobsfletch، @jakemstar، @jamespearson، @JanCizmar، @janicklas-ralph، @jankaifer، @JanKaifer، @jantimon، @jaredpalmer، @javivelasco، @jayair، @jaykch، @Jeffrey-Zutt، @jenewland1999، @jeremydouglas، @JesseKoldewijn، @jessewarren-aa، @jimcresswell، @jiwooIncludeJeong، @jocarrd، @joefreeman، @JohnAdib، @JohnAlbin، @JohnDaly، @johnnyomair، @johnta0، @joliss، @jomeswang، @joostdecock، @Josehower، @josephcsoti، @josh، @joshuabaker، @JoshuaKGoldberg، @joshuaslate، @joulev، @jsteele-stripe، @JTaylor0196، @JuanM04، @jueungrace، @juliusmarminge، @Juneezee، @Just-Moh-it، @juzhiyuan، @jyunhanlin، @kaguya3222، @karlhorky، @kevinmitch14، @keyz، @kijikunnn، @kikobeats، @Kikobeats، @kleintorres، @koba04، @koenpunt، @koltong، @konomae، @kosai106، @krmeda، @kvnang، @kwonoj، @ky1ejs، @kylemcd، @labyrinthitis، @lachlanjc، @lacymorrow، @laityned، @Lantianyou، @leerob، @leodr، @leoortizz، @li-jia-nan، @loettz، @lorenzobloedow، @lubakravche، @lucasassisrosa، @lucasconstantino، @lucgagan، @LukeSchlangen، @LuudJanssen، @lycuid، @M3kH، @m7yue، @manovotny، @maranomynet، @marcus-rise، @MarDi66، @MarkAtOmniux، @martin-wahlberg، @masnormen، @matepapp، @matthew-heath، @mattpr، @maxleiter، @MaxLeiter، @maxproske، @meenie، @meesvandongen، @mhmdrioaf، @michaeloliverx، @mike-plummer، @MiLk، @milovangudelj، @Mingyu-Song، @mirismaili، @mkcy3، @mknichel، @mltsy، @mmaaaaz، @mnajdova، @moetazaneta، @mohanraj-r، @molebox، @morganfeeney، @motopods، @mPaella، @mrkldshv، @mrxbox98، @nabsul، @nathanhammond، @nbouvrette، @nekochantaiwan، @nfinished، @Nick-Mazuk، @nickmccurdy، @niedziolkamichal، @niko20، @nikolovlazar، @nivak-monarch، @nk980113، @nnnnoel، @nocell، @notrab، @nroland013، @nuta، @nutlope، @obusk، @okcoker، @oliviertassinari، @omarhoumz، @opnay، @orionmiz، @ossan-engineer، @patrick91، @pauek، @peraltafederico، @Phiction، @pn-code، @pyjun01، @pythagoras-yamamoto، @qrohlf، @raisedadead، @reconbot، @reshmi-sriram، @reyrodrigez، @ricardofiorani، @rightones، @riqwan، @rishabhpoddar، @rjsdnql123، @rodrigofeijao، @runjuu، @Ryan-Dia، @ryo-manba، @s0h311، @sagarpreet-xflowpay، @sairajchouhan، @samdenty، @samsisle، @sanjaiyan-dev، @saseungmin، @SCG82، @schehata، @Schniz، @sepiropht، @serkanbektas، @sferadev، @ShaunFerris، @shivanshubisht، @shozibabbas، @silvioprog، @simonswiss، @simPod، @sivtu، @SleeplessOne1917، @smaeda-ks، @sonam-serchan، @SonMooSans، @soonoo، @sophiebits، @souporserious، @sp00ls، @sqve، @sreetamdas، @stafyniaksacha، @starunaway، @steebchen، @stefanprobst، @steppefox، @steven-tey، @suhaotian، @sukkaw، @SukkaW، @superbahbi، @SuttonJack، @svarunid، @swaminator، @swarnava، @syedtaqi95، @taep96، @taylorbryant، @teobler، @Terro216، @theevilhead، @thepatrick00، @therealrinku، @thomasballinger، @thorwebdev، @tibi1220، @tim-hanssen، @timeyoutakeit، @tka5، @tknickman، @tomryanx، @trigaten، @tristndev، @tunamagur0، @tvthatsme، @tyhopp، @tyler-lutz، @UnknownMonk، @v1k1، @valentincostam، @valentinh، @valentinpolitov، @vamcs، @vasucp1207، @vicsantizo، @vinaykulk621، @vincenthongzy، @visshaljagtap، @vladikoff، @wherehows، @WhoAmIRUS، @WilderDev، @Willem-Jaap، @williamli، @wiredacorn، @wiscaksono، @wojtekolek، @ws-jm، @wxh06، @wyattfry، @wyattjoh، @xiaolou86، @y-tsubuku، @yagogmaisp، @yangshun، @yasath، @Yash-Singh1، @yigithanyucedag، @ykzts، @Yovach، @yutsuten، @yyuemii، @zek، @zekicaneksi، @zignis، و @zlrlyy