أداة إضافية لمساعدتك في تحقيق التوازن بين السرعة والحداثة عند عرض تطبيق الويب
ما الذي تم شحنه؟
يساعد stale-while-revalidate
المطوّرين في تحقيق التوازن بين السرعة، أي تحميل المحتوى المخزّن مؤقتًا على الفور، وحداثة المحتوى، أي ضمان استخدام التعديلات على المحتوى المخزّن مؤقتًا في المستقبل. إذا
كنت تدير خدمة ويب أو مكتبة تابعة لجهة خارجية يتم تعديلها بجدول زمني
منتظم، أو إذا كانت مواد عرض الطرف الأول تميل إلى أن تكون قصيرة المدة، قد يكون
stale-while-revalidate
إضافة مفيدة إلى سياسات التخزين المؤقت
الحالية.
يتوفّر خيار ضبط stale-while-revalidate
إلى جانب max-age
في عنوان استجابة
Cache-Control
في Chrome 75
وFirefox 68.
ستتجاهل المتصفّحات التي لا تتيح استخدام stale-while-revalidate
قيمة الإعداد هذه بصمت، وستستخدم
max-age
،
كما سأوضّح قريبًا…
ما معنى ذلك؟
لنقسّم stale-while-revalidate
إلى جزءَين: فكرة أنّ الردّ المُخزَّن مؤقتًا
قد يكون قديمًا وعملية إعادة التحقّق.
أولاً، كيف يعرف المتصفّح ما إذا كانت الاستجابة المخزّنة مؤقتًا "قديمة"؟ يجب أن يحتوي عنوان استجابة
Cache-Control
الذي يحتوي على stale-while-revalidate
على
max-age
أيضًا، وعدد الثواني المحدّد من خلال max-age
هو ما يحدّد
القيمة القديمة. يُعتبر أيّ استجابة مخبأة أحدث من max-age
حديثة، ويُعتبَر
أنّ الاستجابات المخبأة الأقدم قديمة.
إذا كانت الاستجابة المخزّنة مؤقتًا على الجهاز لا تزال جديدة، يمكن استخدامها كما هي ل
تلبية طلب المتصفّح. من وجهة نظر stale-while-revalidate
،
ليس هناك أي إجراء يمكن اتّخاذه في هذا السيناريو.
ولكن إذا كانت الاستجابة المخزّنة مؤقتًا قديمة، يتم إجراء عملية تحقّق أخرى تستند إلى العمر:
هل عمر الاستجابة المخزّنة مؤقتًا ضمن الفترة الزمنية الإضافية التي يوفّرها الإعداد
stale-while-revalidate
؟
إذا كان عمر الردّ القديم يقع ضمن هذه النافذة، سيتم استخدامه للقيام بمعالجة طلب المتصفّح. وفي الوقت نفسه، سيتم إرسال طلب "إعادة التحقّق"
إلى الشبكة بطريقة لا تؤخّر استخدام الردّ المُخزَّن مؤقتًا. قد يحتوي الردّ الذي يتم إرجاعه على المعلومات نفسها الواردة في
الردّ المخزّن مؤقتًا سابقًا، أو قد يكون مختلفًا. وفي كلتا الحالتَين، يتم تخزين ردّ الشبكة محليًا، ما يؤدي إلى استبدال أي بيانات كانت محفوظة في ذاكرة التخزين المؤقت في السابق، وإلى إعادة ضبط الموقّت "للحداثة" المستخدَم أثناء أي عمليات مقارنة مستقبلية max-age
.
ومع ذلك، إذا كان الردّ المخزّن مؤقتًا قديمًا بما يكفي ليقع خارج مهلة
stale-while-revalidate
، لن يستوفي طلب المتصفّح. سيسترجع المتصفّح بدلاً من ذلك ردًا من الشبكة، وسيستخدمه
لإكمال الطلب الأوّلي وتعبئة ذاكرة التخزين المؤقت المحلية
بردّ جديد.
مثال على بث مباشر
في ما يلي مثال بسيط على واجهة برمجة تطبيقات HTTP لعرض الوقت الحالي، أو بشكل أدق، عدد الدقائق الحالية التي مضت من الساعة.
في هذا السيناريو، يستخدم خادم الويب رأس Cache-Control
هذا في استجابة HTTP:
Cache-Control: max-age=1, stale-while-revalidate=59
يعني هذا الإعداد أنّه في حال تكرار طلب الوقت خلال 1 ثانية، ستظل القيمة المخزّنة مؤقتًا صالحة وستُستخدَم كما هي بدون أي إعادة إثبات صلاحية.
في حال تكرار الطلب بعد مدة تتراوح بين ثانية واحدة و60 ثانية، ستكون القيمة المخزّنة مؤقتًا قديمة، ولكن سيتم استخدامها لاستيفاء طلب واجهة برمجة التطبيقات. وفي الوقت نفسه، "في الخلفية"، سيتم تقديم طلب إعادة التحقّق من أجل تعبئة ذاكرة التخزين المؤقت بقيمة جديدة لاستخدامها في المستقبل.
إذا تم تكرار الطلب بعد أكثر من 60 ثانية، لن يتم استخدام الاستجابة القديمة على الإطلاق، وسيعتمد استيفاء طلب المتصفّح وإعادة التحقّق من صحة المحتوى في ملف التخزين المؤقت على تلقّي استجابة من الشبكة.
في ما يلي تفاصيل عن هذه الحالات الثلاث المختلفة، بالإضافة إلى الفترة الزمنية التي تنطبق فيها كل حالة على مثالنا:
ما هي حالات الاستخدام الشائعة؟
على الرغم من أنّ المثال أعلاه لخدمة واجهة برمجة التطبيقات "بعد دقائق من الساعة" مصطنَع، فإنه يوضّح حالة الاستخدام المتوقّعة، وهي الخدمات التي تقدّم معلومات تحتاج إلى تعديل، ولكن يُسمح ببعض الدقائق من التأخير.
ومن الأمثلة الأقل تعقيدًا واجهة برمجة تطبيقات لظروف الطقس الحالية، أو أهم عناوين الأخبار التي تم كتابتها خلال الساعة الماضية.
بشكل عام، أيّ ردّ يتم تعديله على فترات زمنية معروفة، ومن المرجّح أن يتم طلبه عدة مرات، ويكون ثابتًا خلال تلك الفترة، هو مرشح جيد لأجل ملف التخزين المؤقت على المدى القصير من خلال max-age
. يؤدي استخدام stale-while-revalidate
بالإضافة
إلى max-age
إلى زيادة احتمالية تلبية الطلبات المستقبلية من
الذاكرة المؤقتة التي تتضمّن محتوى أحدث، بدون حظر استجابة الشبكة.
كيف يتفاعل مع عمال الخدمة؟
إذا سمعت عن stale-while-revalidate
، من المرجّح أنّه كان في سياق
الوصفات
المستخدَمة ضمن عامل الخدمة.
يتشارك استخدام علامة stale-while-revalidate من خلال عنوان Cache-Control
بعضًا من
التشابهات مع استخدامه في الخدمة العاملة، وتنطبق العديد من
الاعتبارات نفسها حول مفاضلات الحداثة والحد الأقصى لأوقات الصلاحية. ومع ذلك،
هناك بعض الاعتبارات التي يجب مراعاتها عند تحديد
ما إذا كنت تريد تنفيذ نهج يستند إلى مهام الخدمة، أو الاعتماد فقط على إعدادات العنوان
Cache-Control
.
استخدِم نهج الخدمة العاملة في الحالات التالية:
- إذا كنت تستخدم حاليًا مشغّل خدمات في تطبيق الويب
- إذا كنت بحاجة إلى التحكّم بشكل دقيق في محتوى ذاكرات التخزين المؤقت، وأردت تنفيذ سياسة مثل سياسة انتهاء الصلاحية الأقل استخدامًا مؤخرًا يمكن أن تساعدك وحدة انتهاء صلاحية ذاكرة التخزين المؤقت في Workbox في حلّ هذه المشكلة.
- تريد أن يتم إعلامك عندما يتغيّر ردّ قديم في الخلفية أثناء خطوة إعادة التحقّق. يمكن أن تساعدك وحدة تعديل ذاكرة التخزين المؤقت للبث في Workbox في حلّ هذه المشكلة.
- يجب أن يكون هذا السلوك
stale-while-revalidate
متاحًا في جميع المتصفحات الحديثة.
استخدِم نهج Cache-Control في الحالات التالية:
- لا تريد التعامل مع النفقات العامة لعملية نشر عامل الخدمة وصيانته لتطبيق الويب.
- لا بأس من السماح لإدارة ذاكرة التخزين المؤقت التلقائية للمتصفح بمنع تضخم ذاكرات التخزين المؤقت المحلية.
- لا بأس باستخدام نهج غير متاح حاليًا في جميع المتصفّحات الحديثة (اعتبارًا من تموز/يوليو 2019، وقد يصبح متاحًا في المستقبل).
إذا كنت تستخدم عامل خدمة وفعّلت أيضًا stale-while-revalidate
لبعض الاستجابات من خلال عنوان Cache-Control
، سيحصل عامل الخدمة،
بشكل عام، على "المحاولة الأولى" للاستجابة لطلب معيّن. إذا قرر العامل في الخدمة عدم الردّ، أو إذا أرسل أثناء إنشاء الردّ طلبًا على الشبكة باستخدام fetch()
،
سيتم تطبيق السلوك الذي تم ضبطه من خلال عنوان Cache-Control
.
مزيد من المعلومات
- استجابة
stale-while-revalidate
في مواصفات واجهة برمجة التطبيقات Fetch API - RFC 5861، الذي يتناول المواصفات الأولية لصيغة
stale-while-revalidate
- ذاكرة التخزين المؤقت لبروتوكول HTTP: خط الدفاع الأول، من دليل "надежность сети" (موثوقية الشبكة) على هذا الموقع الإلكتروني
الصورة الرئيسية من إنشاء سامويل زيلر