شرح التخزين المؤقت HTTP: ETag و Cache-Control وشبكات CDN
لماذا يبدو موقعك بطيئًا (وكيف يصلح التخزين المؤقت ذلك)
لقد قمت بتحسين صورك، وتصغير CSS، وحتى ترقية خادمك. ومع ذلك، لا يزال الزوار المتكررون يعانون من أوقات تحميل بطيئة، ويستهلك خادمك الأصلي النطاق الترددي. ما السبب؟ التخزين المؤقت HTTP غير الفعال. بدون ترويسات التخزين المؤقت المناسبة، تعيد المتصفحات تنزيل نفس الأصول في كل زيارة، ولا يمكن لشبكات CDN أداء عملها بفعالية.
يعد التخزين المؤقت HTTP أحد أعلى تحسينات الأداء فعالية المتاحة. فهو يقلل زمن الاستجابة، ويخفض تكاليف النطاق الترددي، ويخفف الحمل على خوادمك الأصلية. في هذا الدليل، سنشرح الآليات الرئيسية: ETag وCache-Control وكيف تندرج شبكات CDN في الصورة. ستتعلم استراتيجيات عملية لتنفيذها بشكل صحيح.
كيف يعمل التخزين المؤقت HTTP: الصورة الكبيرة
عندما يطلب المتصفح موردًا، يمكنه إما جلبه من الخادم الأصلي أو تقديم نسخة مخزنة محليًا. يحدد التخزين المؤقت HTTP قواعد متى تعتبر النسخة المخزنة حديثة ومتى يجب إعادة التحقق منها.
يوجد نوعان رئيسيان من التخزين المؤقت:
- تخزين المتصفح المؤقت (خاص): يخزن متصفح المستخدم الموارد محليًا. يفيد هذا مستخدمًا واحدًا عبر صفحات أو زيارات متعددة.
- التخزين المؤقت المشترك (CDN، وكيل): تخزن الخوادم الوسيطة الموارد لعدة مستخدمين. يقلل هذا الحمل على الأصل ويسرع التسليم عالميًا.
يعتمد كلاهما على ترويسات HTTP لتحديد الحداثة وإعادة التحقق. أهم ترويستين هما Cache-Control وETag.
Cache-Control: قواعد الحداثة
Cache-Control هي الترويسة الأساسية لتحديد سياسات التخزين المؤقت. إنها ترويسة قائمة على التوجيهات تخبر ذاكرات التخزين المؤقت بكيفية التعامل مع الاستجابة.
التوجيهات الرئيسية
- max-age: عدد الثواني التي تعتبر فيها الاستجابة حديثة. على سبيل المثال،
Cache-Control: max-age=3600تعني أن الاستجابة حديثة لمدة ساعة واحدة. - s-maxage: مثل max-age ولكن خاصة بذاكرات التخزين المؤقت المشتركة (شبكات CDN). تتجاوز max-age لذواكر التخزين المؤقت المشتركة.
- public: يمكن تخزين الاستجابة مؤقتًا بواسطة أي ذاكرة تخزين مؤقت، بما في ذلك المشتركة.
- private: الاستجابة مخصصة لمستخدم واحد ولا ينبغي تخزينها بواسطة ذواكر التخزين المؤقت المشتركة.
- no-cache: يمكن تخزين الاستجابة، ولكن يجب إعادة التحقق منها مع الأصل قبل كل استخدام.
- no-store: يجب عدم تخزين الاستجابة في أي ذاكرة تخزين مؤقت. استخدمها للبيانات الحساسة.
- must-revalidate: بمجرد أن تصبح قديمة، يجب ألا تستخدم ذاكرة التخزين المؤقت الاستجابة دون إعادة التحقق.
- immutable: لن تتغير الاستجابة خلال عمر صلاحيتها. مفيدة للأصول ذات الإصدارات.
مثال: Cache-Control: public, max-age=31536000, immutable مثالية للأصول الثابتة ذات أسماء الملفات المجزأة.
ETag والطلبات الشرطية
ETag (Entity Tag) هو معرف لإصدار معين من مورد. عندما يتغير المورد، يتغير ETag. تستخدم المتصفحات ETags لتقديم طلبات شرطية: ترسل ETag المخزنة في ترويسة If-None-Match. إذا لم يتغير المورد، يستجيب الخادم بـ 304 Not Modified بدون محتوى، مما يوفر النطاق الترددي.
وبالمثل، يعمل Last-Modified مع If-Modified-Since، لكن ETags أكثر دقة (يمكنها اكتشاف التغييرات خلال نفس الثانية).
كيفية إنشاء ETags
تنشئ معظم خوادم الويب وأطر العمل ETags تلقائيًا. على سبيل المثال، في Express.js يمكنك تمكينها باستخدام app.set('etag', 'strong'). في Nginx، تكون ETags مفعلة افتراضيًا للملفات الثابتة.
تضمن ETags القوية (مثل "abc123") تطابق البايت تمامًا. تشير ETags الضعيفة (مثل W/"abc123") إلى التكافؤ الدلالي، وليس البايتات الدقيقة.
تخزين CDN المؤقت: ذاكرة تخزين مؤقت مشتركة على نطاق واسع
تعمل شبكات CDN (شبكات توصيل المحتوى) كذاكرات تخزين مؤقت مشتركة موزعة عالميًا. تخزن محتواك في مواقع الحافة، وتقدمه للمستخدمين من نقطة وجود قريبة. يقلل هذا من زمن الاستجابة ويخفف الحمل عن أصلك.
تحترم شبكات CDN ترويسات Cache-Control ولكن غالبًا ما يكون لديها تكوينها الخاص. المفاهيم الرئيسية:
- ذاكرة التخزين المؤقت للحافة: ذاكرة التخزين المؤقت المحلية لـ CDN. تخزن الاستجابات بناءً على مفاتيح التخزين المؤقت (عادةً URL + ترويسات مثل
Accept-Encoding). - درع الأصل: طبقة تخزين مؤقت إضافية تقلل الطلبات إلى أصلك.
- إبطال التخزين المؤقت: توفر شبكات CDN واجهات برمجة تطبيقات لمسح المحتوى المخزن مؤقتًا عند تحديث الموارد.
عند استخدام CDN، اضبط Cache-Control مع s-maxage للتحكم في حداثة ذاكرة التخزين المؤقت المشتركة بشكل منفصل عن ذاكرة تخزين المتصفح المؤقتة. على سبيل المثال: Cache-Control: public, max-age=600, s-maxage=3600 تعني أن المتصفحات تخزن مؤقتًا لمدة 10 دقائق، لكن CDN تخزن لمدة ساعة واحدة.
مقارنة ترويسات التخزين المؤقت
| الترويسة | الغرض | مثال |
|---|---|---|
Cache-Control |
تحدد قواعد الحداثة والتخزين المؤقت | public, max-age=3600 |
ETag |
معرف فريد لإصدار المورد | "abc123" |
Last-Modified |
طابع زمني لآخر تعديل | Wed, 21 Oct 2025 07:28:00 GMT |
Expires |
تاريخ انتهاء مطلق قديم | Wed, 21 Oct 2025 07:28:00 GMT |
Vary |
تحدد الترويسات التي تؤثر على التخزين المؤقت | Accept-Encoding |
ملاحظة: تم استبدال Expires بـ Cache-Control ولكن لا يزال يستخدم من قبل العملاء الأقدم.
استراتيجية التخزين المؤقت العملية لتطبيقات الويب
اتبع هذه الخطوات لتنفيذ تخزين مؤقت فعال:
- بصم الأصول الثابتة: استخدم أسماء ملفات مجزأة (مثل
app.a1b2c3.js) واضبطmax-ageطويلة معimmutable. عندما يتغير الملف، يتغير التجزئة، مما يكسر ذاكرة التخزين المؤقت. - اضبط Cache-Control المناسب لـ HTML: عادةً ما يجب أن تكون HTML
no-cacheأوmax-ageقصيرة حتى يحصل المستخدمون على التحديثات بسرعة. استخدمETagلإعادة التحقق. - استخدم
Vary: Accept-Encoding: إذا كنت تقدم إصدارات مضغوطة وغير مضغوطة، فهذا يضمن تخزين ذاكرات التخزين المؤقت لها بشكل منفصل. - استفد من CDN مع s-maxage: اضبط
s-maxageأطول لذاكرات التخزين المؤقت المشتركة لتقليل الحمل على الأصل، مع إبقاء ذاكرة تخزين المتصفح المؤقتة أقصر إذا لزم الأمر. - أبطل بحكمة: استخدم واجهات برمجة تطبيقات مسح CDN عند نشر تحديثات حرجة. بالنسبة للأصول الثابتة، تتجنب البصمة الحاجة إلى المسح.
- راقب نسبة إصابة ذاكرة التخزين المؤقت: استخدم تحليلات CDN للتأكد من فعالية ذاكرة التخزين المؤقت. نسبة الإصابة المنخفضة تعني ترويسات خاطئة التكوين.
المزالق الشائعة وكيفية تجنبها
- الإفراط في تخزين HTML مؤقتًا: يرى المستخدمون محتوى قديمًا. استخدم
no-cacheأوmax-ageقصيرة. - عدم كفاية تخزين الأصول الثابتة مؤقتًا: اضبط
max-ageطويلة (مثل سنة واحدة) مع البصمة. - تجاهل
Vary: قد تقدم ذاكرات التخزين المؤقت محتوى خاطئًا (مثل gzip مقابل عادي). اضبط دائمًاVary: Accept-Encoding. - نسيان
privateللبيانات الخاصة بالمستخدم: قد تسرب ذاكرات التخزين المؤقت المشتركة البيانات. استخدمCache-Control: privateللاستجابات الموثقة. - إساءة استخدام
no-store: يمنع كل التخزين المؤقت، مما قد يضر بالأداء. استخدمه فقط للبيانات الحساسة.
اختبار إعداد التخزين المؤقت الخاص بك
استخدم أدوات مطوري المتصفح (علامة تبويب الشبكة) لفحص ترويسات الاستجابة ومعرفة ما إذا كانت الموارد تقدم من ذاكرة التخزين المؤقت (ابحث عن "(من ذاكرة التخزين المؤقت على القرص)" أو "(من ذاكرة التخزين المؤقت)"). لسلوك CDN، استخدم curl -I لفحص ترويسات مثل X-Cache أو CF-Cache-Status. يمكن لأدوات مثل WebPageTest تصور التخزين المؤقت عبر الزيارات.
الأسئلة الشائعة
ما الفرق بين ETag و Last-Modified؟
ETag هو معرف مبهم يتغير عندما يتغير المورد، بينما Last-Modified هو طابع زمني. ETags أكثر دقة لأنها يمكنها اكتشاف التغييرات خلال نفس الثانية ولا تعتمد على مزامنة الساعة.
متى يجب استخدام no-cache مقابل no-store؟
استخدم no-cache عندما تريد أن تخزن ذاكرة التخزين المؤقت الاستجابة ولكن تعيد التحقق منها مع الأصل قبل كل استخدام. استخدم no-store للبيانات الحساسة التي يجب عدم كتابتها أبدًا على القرص أو الذاكرة بواسطة أي ذاكرة تخزين مؤقت.
كيف تتعامل شبكات CDN مع إبطال التخزين المؤقت؟
توفر شبكات CDN واجهات برمجة تطبيقات مسح تتيح لك إزالة عناوين URL محددة أو مجلدات كاملة من ذاكرات التخزين المؤقت للحافة. بعضها يدعم أيضًا المسح الناعم الذي يحدد المحتوى كقديم ويعيد التحقق عند الطلب التالي. غالبًا ما تكون بصمة الأصول أكثر كفاءة من المسح.
الخاتمة
إتقان التخزين المؤقت HTTP باستخدام ETag وCache-Control وشبكات CDN أمر ضروري لبناء تطبيقات ويب سريعة وقابلة للتوسع. ابدأ بضبط الترويسات المناسبة لأصولك الثابتة و HTML، واستفد من ذاكرات التخزين المؤقت المشتركة لـ CDN باستخدام s-maxage، واختبر تكوينك دائمًا. يمكن أن تؤدي التغييرات الصغيرة في ترويسات التخزين المؤقت إلى مكاسب كبيرة في الأداء.
هل تحتاج إلى تحليل سجلات خادمك بسرعة لمعرفة نسب إصابة ذاكرة التخزين المؤقت؟ جرب محلل سجلات Nginx الخاص بنا لتحليل وتصور سجلات الوصول الخاصة بك.