منع الطلبات غير الضرورية من الشبكة باستخدام ذاكرة التخزين المؤقت عبر HTTP

عملية استرجاع الموارد عبر الشبكة بطيئة ومكلفة:

  • تتطلب الاستجابات الكبيرة عدة عمليات إرسال واستقبال بين المتصفِّح والخادم.
  • لن يتم تحميل صفحتك إلى أن يتم تنزيل جميع مواردها المُهمّة بالكامل.
  • في حال وصول مستخدم إلى موقعك الإلكتروني باستخدام خطة بيانات جوّال محدودة، يصبح كل طلب غير ضروري للشبكة هدرًا لأمواله.

كيف يمكنك تجنُّب طلبات الشبكة غير الضرورية؟ تعد ذاكرة التخزين المؤقت لبروتوكول HTTP للمتصفح خط الدفاع الأول. وهو ليس بالضرورة النهج الأكثر فعالية أو مرونة، ولديك قدرة محدودة على التحكم في فترة صلاحية الردود المخزّنة مؤقتًا، ولكنه فعال ويتوافق مع جميع المتصفحات ولا يتطلب الكثير من العمل.

يوضح لك هذا الدليل أساسيات تنفيذ تخزين HTTP مؤقتًا.

توافُق المتصفح

لا توجد في الواقع واجهة برمجة تطبيقات واحدة تسمى ذاكرة التخزين المؤقت لبروتوكول HTTP. إنه الاسم العام لمجموعة من واجهات برمجة التطبيقات للنظام الأساسي للويب. ويمكن استخدام واجهات برمجة التطبيقات هذه في جميع المتصفحات:

طريقة عمل ذاكرة التخزين المؤقت لبروتوكول HTTP

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

يتم التحكّم في سلوك ذاكرة التخزين المؤقت لبروتوكول HTTP من خلال مجموعة من عناوين الطلبات وعناوين الاستجابة. في السيناريو المثالي، سيكون بإمكانك التحكم في كل من رمز تطبيق الويب (الذي سيحدد عناوين الطلبات) وتهيئة خادم الويب (الذي سيحدد عناوين الاستجابة).

راجِع مقالة التخزين المؤقت لبروتوكول HTTP من MDN للحصول على نظرة عامة أكثر تفصيلاً على المفاهيم.

عناوين الطلبات: الالتزام بالإعدادات التلقائية (عادةً)

على الرغم من أنّ هناك عددًا من العناوين المهمة التي يجب تضمينها في الطلبات الصادرة لتطبيق الويب، يعتني المتصفّح دائمًا بإعداد هذه العناوين نيابةً عنك عند تقديم الطلبات. إنّ عناوين الطلبات التي تؤثر في عملية التحقّق من مدى الحداثة، مثل If-None-Match وIf-Modified-Since، لا تظهر إلا بناءً على ما يفهمه المتصفِّح للقيم الحالية في ذاكرة التخزين المؤقت لبروتوكول HTTP.

هذا خبر سارّ، وهو يعني أنّه يمكنك مواصلة تضمين علامات مثل <img src="my-image.png"> في ترميز HTML، وسيتولّى المتصفّح تلقائيًا مهمة التخزين المؤقت لبروتوكول HTTP بدون أي جهد إضافي.

عناوين الاستجابة: ضبط خادم الويب

أكثر أجزاء إعداد التخزين المؤقت لبروتوكول HTTP هي العناوين التي يضيفها خادم الويب إلى كل استجابة صادرة. تُعد العناوين التالية عاملاً مهمًا في سلوك التخزين المؤقت الفعال:

  • Cache-Control. يمكن للخادم عرض التوجيه Cache-Control لتحديد كيفية تخزين الاستجابة الفردية في ذاكرة التخزين المؤقت للاستجابة الفردية ومدتها.
  • ETag. عندما يعثر المتصفّح على استجابة منتهية الصلاحية، يمكنه إرسال رمز مميّز صغير (عادةً ما يكون تجزئة من محتوى الملف) إلى الخادم للتحقّق مما إذا كان الملف قد تغيّر. وإذا عرض الخادم الرمز المميّز نفسه، يكون الملف هو نفسه، ولا حاجة إلى إعادة تنزيله.
  • Last-Modified. يخدم هذا العنوان الغرض نفسه مثل ETag، إلا أنّه يستخدم استراتيجية مستندة إلى الوقت لتحديد ما إذا كان قد تم تغيير أحد الموارد، بدلاً من الاستراتيجية المستندة إلى المحتوى ETag.

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

لتوفير بعض عمليات البحث، إليك إرشادات حول تهيئة بعض خوادم الويب الشائعة:

لا يؤدي ترك عنوان الاستجابة Cache-Control إلى إيقاف التخزين المؤقت عبر HTTP. بدلاً من ذلك، تخمن المتصفحات بطريقة فعالة نوع سلوك التخزين المؤقت الأكثر ملاءمةً لنوع معيّن من المحتوى. من المحتمل أنك تريد المزيد من التحكّم أكثر من تلك العروض، لذا خصِّص الوقت الكافي لضبط عناوين الردود.

ما قيم عنوان الاستجابة التي يجب عليك استخدامها؟

هناك حالتان مهمتان يجب تناولهما عند تهيئة عناوين الاستجابة لخادم الويب.

تخزين مؤقت طويل الأمد لعناوين URL المكرّرة

كيفية الاستفادة من عناوين URL المحدَّدة في إصدارات استراتيجية التخزين المؤقت
وتُعدّ عناوين URL التي تم إصدارها هي ممارسة جيدة لأنّها تسهّل إلغاء صلاحية الردود المخزّنة مؤقتًا.

لنفترض أنّ الخادم يطلب من المتصفحات تخزين ملف CSS في ذاكرة التخزين المؤقت لمدة عام واحد (Cache-Control: max-age=31536000)، ولكنّ المصمم قد أجرى للتو تحديثًا طارئًا يفرض عليك طرحه على الفور. كيف يتم إرسال إشعار إلى المتصفّحات لتعديل النسخة المخزَّنة مؤقتًا "القديمة" من الملف؟ لن تتمكّن من إجراء ذلك، على الأقل ليس بدون تغيير عنوان URL للمورد. بعد أن يخزّن المتصفّح الاستجابة في ذاكرة التخزين المؤقت، يتم استخدام النسخة المخزَّنة مؤقتًا إلى أن تصبح النسخة غير حديثة، كما هو محدّد في max-age أو expires، أو إلى أن يتم إخراجها من ذاكرة التخزين المؤقت لسبب آخر، مثل محو المستخدم لذاكرة التخزين المؤقت الخاصة بالمتصفّح. ونتيجة لذلك، قد يستخدم مستخدمون مختلفون نُسخًا مختلفة من الملف عند إنشاء الصفحة: يستخدم المستخدمون الذين جلبوا المورد النسخة الجديدة، في حين يستخدم المستخدمون الذين خزّنوا نسخة مؤقتة (ولكن لا تزال صالحة) نسخة قديمة من رده. كيف يمكنك الاستفادة إلى أقصى حدّ من الميزتَين: التخزين المؤقت من جهة العميل والتحديثات السريعة؟ يمكنك تغيير عنوان URL للمصدر وإجبار المستخدم على تنزيل الرد الجديد كلما تغيّر محتواه. ويمكنك تنفيذ ذلك عادةً من خلال تضمين بصمة إصبع أو رقم إصدار في اسم الملف، مثل style.x234dff.css.

عند الردّ على طلبات عناوين URL التي تتضمّن "بصمة رقمية" أو معلومات عن الإصدارات والتي لا تهدف مطلقًا إلى تغيير محتواها، أضِف السمة Cache-Control: max-age=31536000 إلى ردودك.

يؤدي ضبط هذه القيمة إلى إعلام المتصفّح بأنّه عندما يحتاج إلى تحميل عنوان URL نفسه في أي وقت على مدار العام التالي (31,536,000 ثانية، والحد الأقصى للقيمة المسموح بها)، يمكنه استخدام القيمة على الفور في ذاكرة التخزين المؤقت لبروتوكول HTTP، بدون الحاجة إلى تقديم طلب الشبكة إلى خادم الويب على الإطلاق. هذا رائع - لقد اكتسبت على الفور الموثوقية والسرعة اللتين تأتيان من تجنب الشبكة!

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

إعادة التحقّق من الخادم لعناوين URL التي لم يتم نسخها

لا يتم إصدار نُسخ معيّنة من جميع عناوين URL التي تحمّلها. قد لا تتمكن من تضمين خطوة إصدار قبل نشر تطبيق الويب، وبالتالي لا يمكنك إضافة علامات تجزئة إلى عناوين URL لمواد العرض. ويحتاج كل تطبيق ويب إلى ملفات HTML، ولن تحتوي هذه الملفات (تقريبًا) على معلومات عن الإصدارات، لأنّه لن يضطر أي شخص إلى استخدام تطبيق الويب الخاص بك إذا كان بحاجة إلى تذكّر أنّ عنوان URL الذي ستتم زيارته هو https://example.com/index.34def12.html. إذًا، ما الذي يمكنك فعله لعناوين URL هذه؟

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

يمكن أن تساعدك قيم Cache-Control التالية في تحسين مكان وطريقة تخزين عناوين URL التي لم يتم نسخها في ذاكرة التخزين المؤقت:

  • no-cache. يؤدي هذا إلى توجيه المتصفّح إلى أنّه يجب إعادة التحقّق مع الخادم في كل مرة قبل استخدام نسخة مخزّنة مؤقتًا من عنوان URL.
  • no-store. وهذا يوجه المتصفح وذاكرات التخزين المؤقت الوسيطة الأخرى (مثل شبكات توصيل المحتوى (CDN)) لعدم تخزين أي نسخة من الملف مطلقًا.
  • private. يمكن للمتصفحات أن تخزّن الملف في ذاكرة التخزين المؤقت، ولكن لا يمكن لذاكرات التخزين المؤقت المتوسطة ذلك.
  • public. يمكن تخزين الرد في أي ذاكرة تخزين مؤقت.

يمكنك الاطّلاع على الملحق: مخطط Cache-Control انسيابي لعرض عملية تحديد قيم Cache-Control المطلوب استخدامها. يُرجى العِلم أيضًا أنّه بإمكان Cache-Control قبول قائمة توجيهات مفصولة بفواصل. يمكنك الاطّلاع على الملحق: Cache-Control مثال.

بالإضافة إلى ذلك، يمكن أن يساعد أيضًا ضبط أحد عنوانَي استجابة إضافيَين: ETag أو Last-Modified. كما هو مذكور في عناوين الاستجابة، يخدم كل من ETag وLast-Modified الغرض نفسه، وهو تحديد ما إذا كان المتصفّح يحتاج إلى إعادة تنزيل ملف مخزَّن مؤقتًا منتهي الصلاحية. وETag هي الطريقة المقترَحة لأنّها أكثر دقة.

مثال على علامة ETag

لنفترض أنّه قد مرت 120 ثانية على الجلب الأولي وبدأ المتصفِّح بطلب جديد للمورد نفسه. أولاً، يفحص المتصفّح ذاكرة التخزين المؤقت لبروتوكول HTTP ويعثر على الاستجابة السابقة. للأسف، لا يمكن للمتصفّح استخدام الردّ السابق بسبب انتهاء صلاحية الردّ الآن. في هذه المرحلة، يمكن للمتصفح إرسال طلب جديد واسترجاع الاستجابة الكاملة الجديدة. في المقابل، هذا الإجراء غير فعّال لأنّه إذا لم يتغيّر المورد، لن يكون هناك سبب لتنزيل المعلومات نفسها الموجودة في ذاكرة التخزين المؤقت. هذه هي المشكلة التي صُممت الرموز المميزة للتحقّق من الصحة، كما هو محدّد في عنوان ETag، لحلها. ينشئ الخادم رمزًا مميّزًا عشوائيًا ويعرضه، والذي يكون عادةً تجزئة أو بصمة إصبع أخرى لمحتويات الملف. لا يحتاج المتصفّح إلى معرفة كيفية إنشاء بصمة الإصبع، بل يحتاج فقط إلى إرسالها إلى الخادم عند الطلب التالي. إذا لم تتغيّر بصمة الإصبع، هذا يعني أنّ المورد لم يتغير وسيتمكّن المتصفّح من تخطّي عملية التنزيل.

من خلال ضبط ETag أو Last-Modified، سيتم توفير طلب إعادة التحقق بشكل أكثر فعالية. يؤدي ذلك إلى ظهور عناوين الطلبات If-Modified-Since أو If-None-Match المذكورة في عناوين الطلب.

وعندما يرى خادم الويب المهيأ بشكل صحيح رؤوس الطلبات الواردة هذه، يمكنه تأكيد ما إذا كان إصدار المورد الذي يتوفر للمتصفح في ذاكرة التخزين المؤقت لبروتوكول HTTP يتطابق مع أحدث إصدار على خادم الويب. وفي حال العثور على تطابق، يمكن للخادم الاستجابة لطلبات HTTP 304 Not Modified التي توازي عبارة "مرحبًا، ندعوك إلى مواصلة استخدام البيانات المتوفّرة لديك حاليًا". هناك القليل جدًا من البيانات المراد نقلها عند إرسال هذا النوع من الردود، لذلك عادةً ما يكون ذلك أسرع بكثير من الاضطرار فعليًا إلى إرسال نسخة من المورد الفعلي المطلوب.

رسم تخطيطي لعميل يطلب موردًا والخادم الذي يستجيب بعنوان 304.
يطلب المتصفّح /file من الخادم ويتضمن عنوان If-None-Match لتوجيه الخادم بعرض الملف الكامل فقط إذا لم يتطابق ETag للملف على الخادم مع قيمة If-None-Match للمتصفح. في هذه الحالة، تتطابق القيمتان، لذلك يعرض الخادم استجابة 304 Not Modified مع تعليمات حول المدة اللازمة لتخزين الملف في ذاكرة التخزين المؤقت (Cache-Control: max-age=120).

ملخّص

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

تعتبر إعدادات Cache-Control التالية بداية جيدة:

  • Cache-Control: no-cache للموارد التي يجب إعادة التحقُّق منها مع الخادم قبل كل استخدام.
  • Cache-Control: no-store للموارد التي يجب عدم تخزينها مؤقتًا مطلقًا.
  • Cache-Control: max-age=31536000 للموارد التي تم تحديد إصداراتها.

ويمكن أن يساعدك العنوان ETag أو Last-Modified في إعادة التحقّق من صحة موارد ذاكرة التخزين المؤقت المنتهية الصلاحية بكفاءة أكبر.

مزيد من المعلومات

إذا كنت تريد تجاوز أساسيات استخدام عنوان Cache-Control، يمكنك الاطّلاع على دليل أفضل ممارسات التخزين المؤقت والأهداف القصوى من "جيك أرشيبالد".

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

الملحق: مزيد من النصائح

إذا كان لديك مزيد من الوقت، فإليك المزيد من الطرق التي يمكنك من خلالها تحسين استخدام ذاكرة التخزين المؤقت لبروتوكول HTTP:

  • استخدم عناوين URL متسقة. إذا كنت تعرض المحتوى نفسه على عناوين URL مختلفة، فسيتم جلب ذلك المحتوى وتخزينه مرات عديدة.
  • قلِّل من إيقاف الاستخدام. إذا كان جزء من المورد (مثل ملف CSS) يتم تحديثه بشكل متكرر، بينما لا يتم تحديث باقي الملف (مثل رمز المكتبة)، يمكنك تقسيم الرمز الذي يتم تحديثه بشكل متكرر إلى ملف منفصل واستخدام استراتيجية تخزين مؤقت قصيرة للرمز الذي يتم تحديثه بشكل متكرر واستراتيجية تخزين مؤقت طويلة للرمز الذي لا يتم تغييره كثيرًا.
  • اطّلِع على توجيه stale-while-revalidate الجديد إذا كان الحداثة نوعًا ما مقبولاً في سياسة Cache-Control.

الملحق: رسم بياني انسيابي Cache-Control

رسم بياني انسيابي

الملحق: Cache-Control مثال

قيمة Cache-Control الشرح
max-age=86400 يمكن أن يتم تخزين الاستجابة مؤقتًا من خلال المتصفحات وذاكرة التخزين المؤقت الوسيطة لمدة تصل إلى يوم واحد (60 ثانية × 60 دقيقة × 24 ساعة).
private, max-age=600 يمكن للمتصفّح تخزين الاستجابة مؤقتًا (وليس ذاكرات التخزين المؤقت الوسيطة) لمدة تصل إلى 10 دقائق (60 ثانية × 10 دقائق).
public, max-age=31536000 يمكن تخزين الرد في أي ذاكرة تخزين مؤقت لمدة سنة واحدة.
no-store لا يُسمح بتخزين الاستجابة مؤقتًا ويجب جلبها بالكامل عند كل طلب.