دليل كامل للتجديد الثابت المتزايد (ISR) باستخدام Next.js
نشرت: 2022-03-10قبل عام ، أصدر Next.js 9.3 دعمًا لإنشاء موقع ثابت (SSG) مما يجعله أول إطار عمل مختلط. كنت مستخدمًا لـ Next.js سعيدًا منذ حوالي بضع سنوات في هذه المرحلة ، ولكن هذا الإصدار جعل Next.js هو الحل الافتراضي الجديد لي. بعد العمل مع Next.js على نطاق واسع ، انضممت إلى Vercel لمساعدة شركات مثل Tripadvisor و Washington Post في تبنيها وتوسيع نطاق Next.js.
في هذه المقالة ، أود استكشاف تطور جديد لـ Jamstack: التجديد الثابت المتزايد (ISR) . ستجد أدناه دليلًا لـ ISR - بما في ذلك حالات الاستخدام والعروض التوضيحية والمقايضات.
مشكلة إنشاء الموقع الثابت
الفكرة وراء Jamstack جذابة: صفحات ثابتة معروضة مسبقًا يمكن دفعها إلى CDN ومتاحة عالميًا في ثوانٍ. المحتوى الثابت سريع ومرن في مواجهة أوقات التعطل ويتم فهرسته على الفور بواسطة برامج الزحف. لكن هناك بعض القضايا.
إذا كنت قد اعتمدت بنية Jamstack أثناء إنشاء موقع ثابت واسع النطاق ، فقد تكون عالقًا في الانتظار لساعات حتى يتم إنشاء موقعك. إذا قمت بمضاعفة عدد الصفحات ، فإن وقت الإنشاء يتضاعف أيضًا. لنفكر في Target.com. هل من الممكن إنشاء ملايين المنتجات بشكل ثابت مع كل عملية نشر؟
حتى إذا تم إنشاء كل صفحة بشكل ثابت في 1 مللي ثانية غير واقعية ، فستستغرق إعادة إنشاء الموقع بالكامل ساعات . بالنسبة لتطبيقات الويب الكبيرة ، لا يعد اختيار إنشاء موقع ثابت بالكامل بداية. تحتاج الفرق الكبيرة إلى حل هجين أكثر مرونة وتخصيصًا.
أنظمة إدارة المحتوى (CMS)
بالنسبة للعديد من الفرق ، يتم فصل محتوى موقعهم عن الكود. يسمح استخدام Headless CMS لمحرري المحتوى بنشر التغييرات دون إشراك مطور. ومع ذلك ، مع المواقع الثابتة التقليدية ، يمكن أن تكون هذه العملية بطيئة.
ضع في اعتبارك متجرًا للتجارة الإلكترونية يحتوي على 100000 منتج. تتغير أسعار المنتجات بشكل متكرر. عندما يغير محرر المحتوى سعر سماعات الرأس من 100 دولار إلى 75 دولارًا كجزء من عرض ترويجي ، يستخدم نظام إدارة المحتوى الخاص به خطاف ويب لإعادة بناء الموقع بالكامل. ليس من المجدي الانتظار لساعات حتى ينعكس السعر الجديد.
قد تؤدي عمليات الإنشاء الطويلة مع الحسابات غير الضرورية أيضًا إلى تكبد نفقات إضافية. من الناحية المثالية ، يكون تطبيقك ذكيًا بما يكفي لفهم المنتجات التي تم تغييرها وتحديث هذه الصفحات بشكل تدريجي دون الحاجة إلى إعادة بناء كاملة .
تجديد ثابت تزايدي (ISR)
يتيح لك Next.js إنشاء صفحات ثابتة أو تحديثها بعد إنشاء موقعك. يتيح التجديد الثابت المتزايد (ISR) للمطورين ومحرري المحتوى استخدام الإنشاء الثابت على أساس كل صفحة ، دون الحاجة إلى إعادة بناء الموقع بالكامل . باستخدام ISR ، يمكنك الاحتفاظ بمزايا static أثناء التحجيم لملايين الصفحات.
يمكن إنشاء الصفحات الثابتة في وقت التشغيل (عند الطلب) بدلاً من وقت الإنشاء باستخدام ISR. باستخدام التحليلات أو اختبار A / B أو مقاييس أخرى ، فأنت مجهز بالمرونة لإجراء المفاضلة الخاصة بك في أوقات الإنشاء.
ضع في اعتبارك متجر التجارة الإلكترونية من قبل مع 100000 منتج. عند 50 مللي ثانية لإنشاء صفحة كل منتج بشكل ثابت ، سيستغرق ذلك ما يقرب من ساعتين بدون ISR . مع ISR ، يمكننا الاختيار من بين:
- بناء أسرع
قم بتوليد أكثر 1000 منتج شيوعًا في وقت الإنشاء. الطلبات المقدمة إلى المنتجات الأخرى ستفقد ذاكرة التخزين المؤقت وستنشئ بشكل ثابت عند الطلب: إنشاءات لمدة دقيقة واحدة. - ارتفاع معدل ضربات ذاكرة التخزين المؤقت
قم بإنشاء 10000 منتج في وقت الإنشاء ، مما يضمن تخزين المزيد من المنتجات مؤقتًا قبل طلب المستخدم: إنشاءات مدتها 8 دقائق.
دعنا نتصفح مثالاً على ISR لصفحة منتج للتجارة الإلكترونية.
ابدء
جلب البيانات
إذا لم تستخدم Next.js من قبل ، فإنني أوصي بقراءة Getting Started With Next.js لفهم الأساسيات. يستخدم ISR نفس واجهة برمجة تطبيقات Next.js لإنشاء صفحات ثابتة: getStaticProps
. بتحديد revalidate: 60
، نبلغ Next.js لاستخدام ISR لهذه الصفحة.
- يمكن لـ Next.js تحديد وقت إعادة التحقق لكل صفحة. دعنا نضبطه على 60 ثانية.
- سيعرض الطلب الأولي لصفحة المنتج الصفحة المخبأة بالسعر الأصلي.
- يتم تحديث بيانات المنتج في نظام إدارة المحتوى.
- أي طلبات للصفحة بعد الطلب الأولي وقبل 60 ثانية يتم تخزينها مؤقتًا وفوريًا.
- بعد نافذة 60 ثانية ، سيظل الطلب التالي يعرض الصفحة المخبأة (القديمة). يقوم Next.js بتشغيل إعادة إنشاء الصفحة في الخلفية .
- بمجرد إنشاء الصفحة بنجاح ، سيقوم Next.js بإلغاء صلاحية ذاكرة التخزين المؤقت وإظهار صفحة المنتج المحدثة. في حالة فشل إعادة إنشاء الخلفية ، تظل الصفحة القديمة بدون تغيير.
// pages/products/[id].js export async function getStaticProps({ params }) { return { props: { product: await getProductFromDatabase(params.id) }, revalidate: 60 } }
توليد المسارات
يُحدد Next.js المنتجات التي يتم إنشاؤها في وقت الإنشاء وأيها عند الطلب. دعنا ننشئ فقط أكثر 1000 منتج شيوعًا في وقت الإنشاء من خلال تزويد getStaticPaths
بقائمة من أفضل 1000 معرّف للمنتج.
نحتاج إلى تكوين كيفية "إجراء احتياطي" لـ Next.js عند طلب أي من المنتجات الأخرى بعد الإنشاء الأولي. هناك خياران للاختيار من بينها: blocking
true
.
-
fallback: blocking
(مفضل)
عندما يتم تقديم طلب إلى صفحة لم يتم إنشاؤها ، فإن Next.js سيعرض الصفحة على الخادم عند الطلب الأول. ستعمل الطلبات المستقبلية على خدمة الملف الثابت من ذاكرة التخزين المؤقت. -
fallback: true
عند تقديم طلب إلى صفحة لم يتم إنشاؤها ، سيعرض Next.js على الفور صفحة ثابتة مع حالة تحميل في الطلب الأول. عند الانتهاء من تحميل البيانات ، ستتم إعادة عرض الصفحة بالبيانات الجديدة وسيتم تخزينها في ذاكرة التخزين المؤقت. ستعمل الطلبات المستقبلية على خدمة الملف الثابت من ذاكرة التخزين المؤقت.
// pages/products/[id].js export async function getStaticPaths() { const products = await getTop1000Products() const paths = products.map((product) => ({ params: { id: product.id } })) return { paths, fallback: 'blocking' } }
المفاضلات
يركز Next.js أولاً وقبل كل شيء على المستخدم النهائي. "الحل الأفضل" نسبي ويختلف حسب الصناعة والجمهور وطبيعة التطبيق. من خلال السماح للمطورين بالانتقال بين الحلول دون ترك حدود إطار العمل ، يتيح لك Next.js اختيار الأداة المناسبة للمشروع.
التقديم من جانب الخادم
ISR ليست الحل الصحيح دائمًا. على سبيل المثال ، لا يمكن لخلاصة أخبار Facebook إظهار محتوى قديم. في هذه الحالة ، قد ترغب في استخدام SSR ورؤوس cache-control
الخاصة بك مع مفاتيح بديلة لإبطال المحتوى. نظرًا لأن Next.js هو إطار عمل مختلط ، يمكنك إجراء هذه المقايضة بنفسك والبقاء داخل إطار العمل.
// You can cache SSR pages at the edge using Next.js // inside both getServerSideProps and API Routes res.setHeader('Cache-Control', 's-maxage=60, stale-while-revalidate');
SSR والتخزين المؤقت للحافة يشبهان ISR (خاصةً في حالة استخدام رؤوس التخزين المؤقت stale-while-revalidate
) مع الاختلاف الرئيسي هو الطلب الأول . باستخدام ISR ، يمكن ضمان ثبات الطلب الأول إذا تم تقديمه مسبقًا. حتى إذا تعطلت قاعدة البيانات الخاصة بك ، أو كانت هناك مشكلة في الاتصال بواجهة برمجة التطبيقات ، فسيظل المستخدمون لديك يشاهدون الصفحة الثابتة المعروضة بشكل صحيح. ومع ذلك ، سيسمح لك SSR بتخصيص صفحتك بناءً على الطلب الوارد.
ملاحظة : قد يؤدي استخدام SSR بدون تخزين مؤقت إلى أداء ضعيف. كل جزء من الثانية مهم عند منع المستخدم من رؤية موقعك ، ويمكن أن يكون لهذا تأثير كبير على TTFB (الوقت حتى البايت الأول).
إنشاء موقع ثابت
لا يكون ISR دائمًا مفيدًا للمواقع الصغيرة. إذا كانت فترة إعادة التحقق الخاصة بك أكبر من الوقت الذي تستغرقه لإعادة بناء موقعك بالكامل ، فيمكنك أيضًا استخدام إنشاء موقع ثابت تقليدي.
التقديم من جانب العميل
إذا كنت تستخدم React بدون Next.js ، فأنت تستخدم التصيير من جانب العميل. يقدم تطبيقك حالة تحميل ، متبوعة بطلب بيانات داخل JavaScript من جانب العميل (على سبيل المثال useEffect
). على الرغم من أن هذا يزيد من خيارات الاستضافة (حيث لا يوجد خادم ضروري) ، إلا أن هناك مقايضات.
يؤدي عدم وجود محتوى معروض مسبقًا من HTML الأولي إلى تحسين محرك البحث (SEO) بشكل أبطأ وأقل ديناميكية. لا يمكن أيضًا استخدام CSR مع تعطيل JavaScript.
خيارات ISR الاحتياطية
إذا كان من الممكن جلب بياناتك بسرعة ، ففكر في استخدام fallback: blocking
. بعد ذلك ، لا تحتاج إلى التفكير في حالة التحميل وستظهر صفحتك دائمًا نفس النتيجة (بغض النظر عما إذا كانت مخبأة أم لا). إذا كان جلب البيانات بطيئًا ، يسمح لك fallback: true
بإظهار حالة التحميل للمستخدم على الفور.
ISR: ليس مجرد تخزين مؤقت!
بينما قمت بشرح ISR من خلال سياق ذاكرة التخزين المؤقت ، فقد تم تصميمه لاستمرار الصفحات التي تم إنشاؤها بين عمليات النشر. هذا يعني أنه يمكنك التراجع على الفور وعدم فقد صفحاتك التي تم إنشاؤها مسبقًا.
يمكن تمييز كل عملية نشر بواسطة معرّف ، والذي يستخدمه Next.js لاستمرار الصفحات التي تم إنشاؤها بشكل ثابت. عند التراجع ، يمكنك تحديث المفتاح للإشارة إلى النشر السابق ، مما يسمح بالنشر الذري. هذا يعني أنه يمكنك زيارة عمليات النشر الثابتة السابقة وستعمل على النحو المنشود.
- فيما يلي مثال على إرجاع الشفرة باستخدام ISR:
- تدفع الرمز وتحصل على معرّف النشر 123.
- تحتوي صفحتك على "مجلة Smshng" خطأ مطبعي.
- تقوم بتحديث الصفحة في نظام إدارة المحتوى. لا حاجة لإعادة النشر.
- بمجرد أن تعرض صفحتك "مجلة Smashing" ، فإنها تظل في التخزين.
- تدفع بعض التعليمات البرمجية السيئة وتنشر المعرف 345.
- يمكنك التراجع إلى معرّف النشر 123.
- ما زلت ترى "مجلة Smashing".
تعد الصفحات الثابتة المعادة والمستمرة خارج نطاق Next.js وتعتمد على مزود الاستضافة الخاص بك. لاحظ أن ISR يختلف عن عرض الخادم برؤوس Cache-Control
لأنه ، حسب التصميم ، تنتهي صلاحية ذاكرة التخزين المؤقت. لا يتم مشاركتها عبر المناطق وسيتم إزالتها عند الرجوع.
أمثلة على التجديد الثابت المتزايد
يعمل التجديد الثابت المتزايد بشكل جيد مع التجارة الإلكترونية وصفحات التسويق ومنشورات المدونات والوسائط الإعلانية المدعومة والمزيد.
- عرض تجريبي للتجارة الإلكترونية
Next.js Commerce عبارة عن مجموعة بداية شاملة لمواقع التجارة الإلكترونية عالية الأداء. - عرض توضيحي لتفاعلات جيثب
تعامل مع مشكلة GitHub الأصلية وشاهد ISR وهي تقوم بتحديث الصفحة المقصودة التي تم إنشاؤها بشكل ثابت. - عرض تويت ثابت
يتم نشر هذا المشروع في 30 ثانية ، ولكن يمكنه إنشاء 500 مليون تغريدة بشكل ثابت عند الطلب باستخدام ISR.
تعلم Next.js اليوم
يختار المطورون والفرق الكبيرة Next.js لنهجها المختلط وقدرتها على إنشاء صفحات عند الطلب بشكل متزايد. مع ISR ، يمكنك الحصول على مزايا static مع مرونة عرض الخادم. يعمل ISR خارج الصندوق باستخدام next start
.
تم تصميم Next.js للتبني التدريجي. باستخدام Next.js ، يمكنك الاستمرار في استخدام الكود الموجود لديك وإضافة أكبر قدر (أو أقل) من رد الفعل حسب حاجتك. من خلال البدء في إضافة المزيد من الصفحات الصغيرة بشكل تدريجي ، يمكنك منع عمل الميزة عن مساره عن طريق تجنب إعادة الكتابة بالكامل. تعرف على المزيد حول Next.js - وأتمنى لكم ترميزًا سعيدًا للجميع!
قراءة متعمقة
- الشروع في العمل مع Next.js
- مقارنة أساليب التصميم في Next.js
- كيفية إنشاء خادم GraphQL باستخدام مسارات واجهة برمجة تطبيقات Next.js