الكاش (التخزين المؤقت) هو حفظ نتيجة عملية مكلفة في مكان أسرع للوصول، بحيث تُعاد الاستفادة منها بدل إعادة حسابها في كل مرة. على الويب توجد طبقات كاش متعدّدة تعمل معًا: كاش المتصفّح عند المستخدم، كاش الصفحة وكاش الكائنات على الخادم، كاش Opcode للأكواد، وكاش CDN على الحافة قرب الزائر. كل طبقة تحلّ مشكلة مختلفة، والإعداد الصحيح قد يقلّل زمن الاستجابة من ثوانٍ إلى أجزاء من الثانية. أصعب جزء ليس تفعيل الكاش بل إبطاله في الوقت المناسب حتى لا يرى الزائر محتوى قديمًا.
في هذا الدليل نفكّك كل نوع من أنواع الكاش: كيف يعمل، أين يُخزَّن، متى تستخدمه ومتى تتجنّبه، وكيف تتعامل مع مشاكله الشائعة. هذا المقال جزء من سلسلة الأداء، ويُكمّل الدليل الأشمل تسريع موقعك الذي يربط كل عناصر السرعة معًا.
ما هو الكاش ولماذا نحتاجه؟
الكاش في جوهره فكرة بسيطة: بدل أن تكرّر عملًا مكلفًا، احفظ نتيجته في مكان أسرع واسترجعها. عندما يطلب زائر صفحة، قد يتطلّب توليدها تنفيذ كود PHP، استعلامات قاعدة بيانات، تجميع قوالب، ثم بناء HTML نهائي. هذه السلسلة قد تستغرق مئات الميلي ثانية أو أكثر. إذا كانت النتيجة نفسها ستُعرَض لآلاف الزوار، فمن الهدر تكرار كل ذلك في كل طلب.
الكاش يحلّ مشكلتين أساسيتين:
- تقليل العمل المتكرّر (Computation): لا داعي لإعادة تنفيذ نفس الاستعلامات والمعالجة آلاف المرّات للنتيجة ذاتها.
- تقليل زمن الاستجابة (Latency): جلب نتيجة من ذاكرة سريعة أو من خادم قريب جغرافيًا أسرع بكثير من بنائها من الصفر أو جلبها من خادم بعيد.
والنتيجة العملية مزدوجة: الزائر يحصل على صفحة أسرع، والخادم يتحمّل عبئًا أقل فيخدم زوارًا أكثر بنفس الموارد. هذا الأثر المركّب هو ما يجعل الكاش أهم رافعة أداء منفردة لأي موقع تقريبًا.
قاعدة محلية الموقع (Locality)
الكاش يعمل لأن الوصول للبيانات يميل إلى التكرار: المحتوى نفسه يُطلَب مرارًا (محلية زمنية)، والبيانات المترابطة تُطلَب معًا (محلية مكانية). كلما زاد تكرار الطلب على نفس المورد، زادت قيمة تخزينه مؤقتًا. ولهذا يكون الكاش فعّالًا جدًا للمحتوى العام الثابت نسبيًا (مقالات، صفحات تعريفية، صور) وأقل فائدة — بل ضارًا أحيانًا — للمحتوى الشخصي المتغيّر لكل مستخدم.
كيف يعمل الكاش مفهوميًا؟
أي نظام كاش يدور حول دورة حياة واحدة:
- الطلب يصل: يبحث النظام أولًا في الكاش عن نتيجة مخزّنة لهذا المفتاح (Cache Key).
- إصابة (Hit) أو إخفاق (Miss): إذا وُجدت نتيجة صالحة فهذه "إصابة" تُعاد فورًا. إذا لم تُوجد فهذا "إخفاق" يستدعي توليد النتيجة من المصدر.
- التخزين: عند الإخفاق، تُحسَب النتيجة وتُخزَّن في الكاش بمفتاح ومدّة صلاحية (TTL).
- الإبطال (Invalidation): عندما يتغيّر المصدر، يجب تحديث أو حذف النسخة المخزّنة حتى لا تبقى قديمة.
أهم ثلاثة مفاهيم تتحكّم في سلوك أي كاش:
| المفهوم | الوصف | لماذا يهم |
|---|---|---|
| مفتاح الكاش (Cache Key) | المعرّف الذي يُخزَّن ويُسترجع به العنصر (غالبًا الرابط + معاملات) | مفتاح خاطئ يخلط بين محتوى مستخدمين أو يمنع الإصابات |
| مدّة الحياة (TTL) | كم تبقى النسخة صالحة قبل اعتبارها منتهية | قصيرة جدًا تُضعف الفائدة، طويلة جدًا تُبقي محتوى قديمًا |
| الإبطال (Invalidation/Purge) | متى وكيف تُحذف النسخة القديمة عند تغيّر المصدر | المشكلة الأصعب، ومصدر معظم أعطال الكاش |
معدّل الإصابة (Hit Rate) هو المقياس الأهم لصحّة أي كاش: نسبة الطلبات التي خُدِمت من الكاش بدل المصدر. كاش بمعدّل إصابة 95٪ يعني أن 5٪ فقط من الطلبات وصلت للخادم الأصلي، وهذا تخفيف هائل للحمل.
ما أنواع الكاش الرئيسية على الويب؟
من السهل الخلط بين الأنواع لأنها كلها تُسمّى "كاش"، لكنها تعمل في طبقات مختلفة وتحلّ مشاكل مختلفة. الجدول التالي يلخّص الصورة الكبيرة قبل التفصيل:
| النوع | أين يعمل | ما الذي يخزّنه | يخفّض ماذا |
|---|---|---|---|
| كاش المتصفّح | جهاز الزائر | ملفات ثابتة (CSS/JS/صور) | تكرار التحميل وزمن الشبكة |
| كاش الصفحة (Page) | الخادم الأصلي | HTML كامل للصفحة | توليد الصفحة بالكامل |
| كاش الكائنات (Object) | ذاكرة الخادم (Redis/Memcached) | نتائج استعلامات وحسابات | ضغط قاعدة البيانات |
| كاش Opcode | محرّك PHP على الخادم | البايت كود المُترجَم | إعادة تفسير الأكواد |
| كاش قاعدة البيانات | محرّك قاعدة البيانات | نتائج/صفحات بيانات متكرّرة | قراءة القرص والاستعلام |
| كاش CDN / الحافة | خوادم موزّعة عالميًا | ملفات وصفحات قرب الزائر | المسافة للخادم الأصلي |
| كاش DNS | المحلِّل والمتصفّح والنظام | تحويل النطاق إلى IP | استعلامات DNS المتكرّرة |
في الطلب الواحد قد تمرّ البيانات عبر عدّة طبقات: يحلّ DNS العنوان، يخدم CDN الملف من الحافة، يُعاد HTML من كاش الصفحة، ويُسترجع جزء ديناميكي من كاش الكائنات. كلها تتعاون، ولكل منها إعداد منفصل.
كيف يعمل كاش المتصفّح وما رؤوسه؟
كاش المتصفّح يخزّن الملفات الثابتة على جهاز الزائر نفسه، فلا يحتاج المتصفّح إعادة تنزيلها في كل زيارة. هذا أرخص أنواع الكاش وأقربها للمستخدم — الملف يُقرأ من القرص المحلي بدل الشبكة بالكامل.
التحكّم يتمّ عبر رؤوس HTTP التي يرسلها الخادم مع الاستجابة. أهمها:
Cache-Control: public, max-age=31536000, immutable
ETag: "a1b2c3d4"
Expires: Wed, 11 Jun 2027 10:00:00 GMT
Last-Modified: Tue, 10 Jun 2026 08:30:00 GMT
شرح الرؤوس الأساسية:
| الرأس | الوظيفة | ملاحظة عملية |
|---|---|---|
Cache-Control | الرأس الحديث الرئيسي للتحكّم بالكاش | يتجاوز Expires ويُفضَّل دائمًا |
max-age | مدّة الصلاحية بالثواني | 31536000 = سنة كاملة للأصول الثابتة |
public / private | هل يُسمح للوسطاء (CDN) بالتخزين؟ | استخدم private للمحتوى الشخصي |
no-cache | يجب التحقّق من الخادم قبل الاستخدام | لا يعني "لا تخزّن" بل "تحقّق دائمًا" |
no-store | ممنوع التخزين نهائيًا | للبيانات الحسّاسة فقط |
immutable | الملف لن يتغيّر أبدًا خلال المدّة | يلغي إعادة التحقّق عند التحديث |
ETag | بصمة للمحتوى للتحقّق المشروط | يردّ الخادم 304 إن لم يتغيّر |
Expires | تاريخ انتهاء مطلق (قديم) | احتياطي لمتصفّحات قديمة |
التحقّق المشروط و304
حتى بعد انتهاء max-age، لا يضطرّ المتصفّح دائمًا لإعادة تنزيل الملف كاملًا. يرسل المتصفّح If-None-Match بقيمة الـETag المخزّنة، فإن لم يتغيّر المحتوى يردّ الخادم بـ304 Not Modified بلا جسم استجابة. هذا يوفّر النطاق الترددي مع ضمان الحداثة. ومع ذلك، يبقى التحقّق المشروط رحلة شبكة كاملة، لذا الأصول الثابتة تُفضَّل بمدّة طويلة + immutable لتجنّب حتى هذه الرحلة.
ما الفرق بين كاش الصفحة وكاش الكائنات؟
هذان النوعان يعملان على الخادم الأصلي وهما الأكثر تأثيرًا في أنظمة إدارة المحتوى مثل ووردبريس، ويُخلَط بينهما كثيرًا رغم اختلافهما الجذري.
كاش الصفحة (Page Cache)
كاش الصفحة يخزّن مخرجات HTML النهائية كاملة بعد توليدها. عند أول طلب لصفحة، ينفّذ الخادم كل الكود والاستعلامات وينتج HTML، ثم يحفظ هذا الناتج. الطلبات التالية تُخدَم من النسخة المحفوظة مباشرة دون تشغيل أي كود تقريبًا. هذا الأقوى أثرًا: قد ينقل زمن الاستجابة من 800 ميلي ثانية إلى أقل من 50 تقريبًا.
عيبه أنه "كل شيء أو لا شيء": إن كانت الصفحة تحتوي جزءًا شخصيًا واحدًا (اسم المستخدم، سلة الشراء) فلا يمكن تخزينها كما هي للجميع. الحلّ هو استثناء هذه الصفحات أو استخدام تقنيات تجزئة مثل ESI أو حقن الأجزاء الشخصية عبر JavaScript بعد التحميل.
كاش الكائنات (Object Cache)
كاش الكائنات يخزّن نتائج جزئية مكلفة في ذاكرة سريعة مثل Redis أو Memcached: نتيجة استعلام معقّد، إعدادات، قائمة تصنيفات، نتائج API. بدل الذهاب لقاعدة البيانات في كل مرّة، تُسترجع النتيجة من الذاكرة بمفتاح. هذا مفيد للصفحات الديناميكية التي لا يمكن تخزينها كصفحة كاملة لكنها تكرّر نفس الاستعلامات الداخلية.
| البُعد | كاش الصفحة | كاش الكائنات |
|---|---|---|
| ما يُخزَّن | HTML كامل للصفحة | نتائج استعلامات/حسابات جزئية |
| الموقع | قرص/ذاكرة الخادم | Redis / Memcached |
| الأنسب لـ | صفحات عامة ثابتة | صفحات ديناميكية وشخصية |
| أثر السرعة | الأكبر (يتجاوز PHP كلّه) | متوسط (يخفّف قاعدة البيانات) |
| التعامل مع الشخصنة | ضعيف (يحتاج استثناء) | ممتاز (يخزّن الأجزاء فقط) |
القاعدة العملية: استخدم كاش الصفحة للمحتوى العام، وكاش الكائنات لتسريع الأجزاء الديناميكية التي لا يمكن تخزينها كصفحة. وهما يعملان معًا لا أحدهما بديلًا عن الآخر. للتعمّق في تطبيق هذين النوعين على ووردبريس تحديدًا، راجع تسريع ووردبريس.
ووردبريس أسرع وأكثر أمانًا بلا إعدادات
ووردبريس المُدار من wpressly: سرعة وكاش وحماية وتحديثات تلقائية مع دعم عربي — ركّز على محتواك لا على السيرفر.
جرّب ووردبريس المُداركيف يعمل كاش Opcode (OPcache)؟
كود PHP مكتوب نصًّا يجب أن يُحلَّل ويُترجَم إلى بايت كود قبل تنفيذه في كل طلب. OPcache يخزّن البايت كود المُترجَم في الذاكرة المشتركة، فيتخطّى محرّك PHP خطوة التحليل والترجمة في الطلبات التالية ويقفز مباشرة للتنفيذ.
أثره كبير وصامت: لا يغيّر مخرجات الصفحة بل يسرّع توليدها، وغالبًا يقلّل زمن معالجة PHP بنسبة ملموسة دون أي تغيير في الكود. وهو مختلف جوهريًا عن الأنواع السابقة لأنه يخزّن الكود المُترجَم لا البيانات أو المخرجات.
| الخاصية | القيمة النموذجية | الوظيفة |
|---|---|---|
opcache.enable | 1 | تفعيل OPcache |
opcache.memory_consumption | 128–256 (ميغابايت) | حجم الذاكرة المخصّصة للبايت كود |
opcache.max_accelerated_files | 10000+ | عدد الملفات القابلة للتخزين |
opcache.validate_timestamps | 1 تطوير / 0 إنتاج | هل يفحص تغيّر الملفات؟ |
opcache.revalidate_freq | 2–60 (ثانية) | كل كم يُعاد فحص الملفات |
في بيئة الإنتاج، إيقاف validate_timestamps يعطي أقصى أداء لكنه يعني أن أي تعديل على الكود لن يُلتقَط حتى تُفرَّغ ذاكرة OPcache يدويًا أو يُعاد تشغيل PHP — وهذه نقطة تعطّل شائعة بعد النشر.
OPcache إعداد على مستوى الخادم، ولهذا قد لا تتحكّم به على الاستضافة المشتركة بينما تملكه كاملًا على VPS أو الاستضافة المُدارة. مزوّدو الاستضافة الجادّون يُفعّلونه افتراضيًا مع إعدادات إنتاج مناسبة. للفرق بين هذه البيئات في التحكّم بالخادم راجع الاستضافة المشتركة مقابل VPS مقابل المُدارة.
جاهز لإطلاق موقعك على استضافة سريعة؟
خطط استضافة wpressly على أقراص NVMe مع SSL مجاني ودعم عربي — اختر الخطة المناسبة لحجمك وانطلق اليوم.
اكتشف خطط الاستضافةكيف يخدم كاش CDN المحتوى من الحافة؟
شبكة توصيل المحتوى (CDN) تنشر نسخًا من ملفاتك — وأحيانًا صفحات HTML كاملة — على خوادم موزّعة عالميًا تُسمّى نقاط الحضور (PoPs). عندما يطلب زائر موردًا، يُخدَم من أقرب نقطة جغرافية بدل الخادم الأصلي البعيد، فينخفض زمن الرحلة من مئات الميلي ثانية إلى عشرات.
كاش الحافة يعمل بنفس مبادئ الكاش لكن مع بُعد جغرافي: عند إخفاق على نقطة حافة، تجلب النقطة المورد من الأصل مرّة واحدة، تخزّنه، ثم تخدمه محليًا لكل الزوار في تلك المنطقة. للأصول الثابتة هذا يكاد يكون مجانيًا في الأداء؛ ولـHTML يتطلّب ضبطًا دقيقًا لمنع تخزين المحتوى الشخصي.
| الميزة | الفائدة |
|---|---|
| التوزيع الجغرافي | تقليل زمن الرحلة (Latency) للزوار البعيدين |
| تفريغ الأصل (Origin Offload) | الخادم الأصلي يخدم طلبات أقل بكثير |
| امتصاص الذروة | يتحمّل موجات الزوار دون إجهاد الأصل |
| حماية ضمنية | يمتصّ جزءًا من هجمات الحمل الزائد |
CDN يكمّل كاش الخادم ولا يغني عنه: كاش الصفحة يسرّع توليد المحتوى على الأصل، وCDN يسرّع توصيله للزائر. شرح آلية الـCDN بالتفصيل تجده في ما هي شبكة CDN.
رؤوس الكاش والـCDN
يحترم الـCDN في الغالب رؤوس Cache-Control نفسها، مع تمييز مهم: s-maxage يحدّد مدّة الكاش للوسطاء المشتركين (مثل CDN) منفصلة عن max-age للمتصفّح:
Cache-Control: public, max-age=0, s-maxage=3600
هذا المثال يعني: لا تثق بكاش المتصفّح (max-age=0) لكن اسمح للـCDN بتخزين الصفحة ساعة (s-maxage=3600). نمط مفيد لصفحات HTML تريد خدمتها من الحافة مع إمكانية إبطالها مركزيًا عند التحديث.
كيف تختار مدّة الكاش (TTL) لكل نوع أصل؟
اختيار TTL هو موازنة بين الحداثة والأداء: مدّة أطول تعني أداء أفضل وحملًا أقل، لكنها تزيد احتمال عرض محتوى قديم. القاعدة الذهبية: اربط المدّة بمعدّل تغيّر المحتوى.
| نوع الأصل | TTL مقترح | الاستراتيجية |
|---|---|---|
| CSS / JS (مع hash) | سنة (max-age=31536000, immutable) | كسر الكاش بتغيير اسم الملف |
| صور وخطوط ثابتة | شهر – سنة | طويلة لأنها نادرة التغيّر |
| HTML لصفحة مقال | دقائق – ساعات | قصيرة + إبطال عند التحديث |
| صفحة رئيسية متغيّرة | دقائق | قصيرة لأنها تتحدّث كثيرًا |
| استجابات API عامة | ثوانٍ – دقائق | حسب حساسية البيانات للزمن |
| محتوى شخصي/سلة | لا تخزّن (no-store/private) | يختلف لكل مستخدم |
كسر الكاش بالـHash (Cache Busting)
السرّ في إعطاء الأصول الثابتة مدّة سنة كاملة دون خوف من المحتوى القديم هو تضمين بصمة (hash) في اسم الملف: app.4f8a2c.js. عند تغيير الملف، يتغيّر الـhash فيصبح الاسم جديدًا تمامًا (app.9b1e7d.js)، والمتصفّح يعتبره موردًا مختلفًا فيُنزّله فورًا. النسخة القديمة تبقى في الكاش لكن لا أحد يطلبها. هكذا تجمع بين أطول كاش ممكن وتحديث فوري عند التغيير. أدوات البناء الحديثة تولّد هذه البصمات تلقائيًا.
هذا النمط لا ينطبق على HTML نفسه (رابط الصفحة ثابت لا يحمل hash)، لذلك تبقى مدّة HTML قصيرة مع الاعتماد على الإبطال الصريح عند التحديث.
لماذا إبطال الكاش من أصعب المشاكل؟
تُنسَب مقولة شهيرة في علوم الحاسوب إلى أن "أصعب مشكلتين هما تسمية الأشياء وإبطال الكاش". السبب أن الإبطال يتطلّب معرفة متى بالضبط أصبحت نسخة مخزّنة قديمة، عبر طبقات متعدّدة، دون إبطال زائد (يضيّع الفائدة) ولا ناقص (يُبقي محتوى قديمًا).
طرق الإبطال الرئيسية:
| الطريقة | كيف تعمل | متى تستخدمها |
|---|---|---|
| انتهاء TTL | تنتهي النسخة تلقائيًا بعد مدّة | للمحتوى المتوقّع تغيّره دوريًا |
| الإبطال الصريح (Purge) | حذف مفتاح محدّد فور التغيير | عند تحرير/نشر محتوى |
| إبطال بالوسم (Tag) | حذف كل ما يحمل وسمًا معينًا | لإبطال مجموعة مرتبطة دفعة واحدة |
| إبطال شامل (Flush) | تفريغ الكاش بالكامل | حلّ أخير، يسبّب موجة إخفاقات |
أفضل ممارسة هي الإبطال المُوجَّه بالأحداث: عند نشر مقال، أبطل صفحة المقال والصفحات المرتبطة (الرئيسية، صفحة التصنيف، خلاصة RSS) فقط، لا الكاش كلّه. الإبطال الشامل المتكرّر يُفرغ الكاش باستمرار فتفقد فائدته ويتعرّض الخادم لموجات حمل (Cache Stampede) عند إعادة بناء كل شيء دفعة واحدة.
متى لا يجب استخدام الكاش؟
الكاش أداة قوية لكنها ليست دائمًا مناسبة. القاعدة: لا تخزّن ما يختلف لكل مستخدم أو ما يجب أن يكون لحظيًا.
أمثلة على محتوى لا يُخزَّن كصفحة كاملة:
- لوحات التحكّم والحسابات: كل مستخدم يرى بياناته الخاصّة.
- سلة الشراء وصفحة الدفع: تتغيّر باستمرار وحسّاسة.
- صفحات تتطلّب تسجيل دخول: قد تسرّب نسخة مخزّنة بيانات مستخدم لآخر — خطر أمني حقيقي.
- نتائج بحث وفلاتر شخصية: تركيبات لا نهائية، معدّل إصابة منخفض.
- بيانات مالية أو مخزون لحظي: الحداثة أهم من الأداء.
للمحتوى الشخصي، الحلّ ليس إلغاء الكاش بل اختيار الطبقة الصحيحة: استخدم كاش الكائنات للأجزاء المشتركة المكلفة، احقن الأجزاء الشخصية بعد التحميل، واضبط Cache-Control: private أو no-store للاستجابات الحسّاسة حتى لا يخزّنها أي وسيط مشترك.
كيف يختلف الكاش بين بيئات الاستضافة؟
التحكّم في الكاش يعتمد بشدّة على نوع الاستضافة، لأن بعض الطبقات تحتاج صلاحيات على مستوى الخادم لا تتوفّر في كل البيئات.
| البيئة | كاش المتصفّح | كاش الصفحة | كاش الكائنات | OPcache / مستوى الخادم |
|---|---|---|---|---|
| استضافة مشتركة | متاح (رؤوس) | عبر إضافة غالبًا | محدود/غير متاح أحيانًا | يُديره المزوّد، تحكّم ضعيف |
| VPS | تحكّم كامل | تحكّم كامل | Redis/Memcached بتثبيتك | تحكّم كامل بالإعدادات |
| استضافة مُدارة | مُهيّأ مسبقًا | مدمج ومُحسَّن | مُفعّل غالبًا (Redis) | مُحسَّن من المزوّد |
| LiteSpeed / خادم متقدّم | مدمج | كاش على مستوى الخادم سريع | متكامل | مُحسَّن افتراضيًا |
على الاستضافة المشتركة، تعتمد غالبًا على إضافات الكاش لأن صلاحيات الخادم محدودة، وقد يكون كاش الكائنات غير متاح. على VPS تملك كل شيء لكن مسؤولية الإعداد عليك. الاستضافة المُدارة والخوادم المتقدّمة مثل LiteSpeed تقدّم كاشًا على مستوى الخادم أسرع من كاش الإضافات لأنه يعمل قبل تحميل PHP أصلًا.
النقطة الجوهرية: الكاش على مستوى الخادم (LiteSpeed Cache، Nginx FastCGI Cache) عادةً أسرع وأكثر كفاءة من الكاش داخل التطبيق، لأنه يعترض الطلب مبكرًا. توفّر هذه الطبقة يعتمد على بيئة الاستضافة التي تختارها.
ما الأدوات والإضافات لكل بيئة؟
| البيئة / المنصّة | أداة الكاش الشائعة | النوع الذي تغطّيه |
|---|---|---|
| ووردبريس (عام) | WP Super Cache, W3 Total Cache | كاش صفحة + متصفّح + كائنات |
| ووردبريس + LiteSpeed | LiteSpeed Cache | كاش خادم + صفحة + كائنات |
| كاش الكائنات | Redis Object Cache, Memcached | كاش الكائنات |
| Nginx | FastCGI Cache / proxy_cache | كاش صفحة على مستوى الخادم |
| تطبيق مخصّص | Redis / Varnish | كائنات / صفحة عكسية |
| طبقة CDN | Cloudflare, Fastly, إلخ | كاش الحافة |
نصيحة الخبير: لا تجمع أكثر من إضافة كاش صفحة واحدة. تشغيل إضافتين تديران كاش الصفحة معًا يسبّب تعارضات وملفات تالفة وسلوكًا غير متوقّع. اختر أداة واحدة شاملة لكل طبقة، ودع كاش الكائنات (Redis) منفصلًا عن كاش الصفحة دون تعارض.
أخطاء شائعة
هذه الأخطاء تتكرّر كثيرًا وتُفقِد الكاش قيمته أو تسبّب أعطالًا:
- مدّة طويلة على HTML بلا إبطال: المحتوى يبقى قديمًا أيامًا. اجعل HTML قصير المدّة مع إبطال عند التحديث.
- مدّة قصيرة على الأصول الثابتة: هدر إذ تُعاد التنزيلات بلا داعٍ. استخدم سنة + hash للأصول الثابتة.
- تخزين صفحات مسجّلي الدخول: خطر تسريب بيانات بين المستخدمين. استثنِ هذه الصفحات صراحةً.
no-cacheبدلno-store:no-cacheيعني "تحقّق" لا "لا تخزّن"؛ للبيانات الحسّاسة استخدمno-store.- نسيان كسر الكاش بالـhash: تحديثات CSS/JS لا تصل للزوار. اعتمد بصمات في أسماء الملفات.
- تشغيل إضافتي كاش صفحة: تعارض وملفات تالفة. أداة واحدة فقط لكل طبقة.
- عدم تفريغ OPcache بعد النشر: الكود الجديد لا يُنفَّذ. أعد التحقّق أو فرّغ OPcache عند النشر.
Varyخاطئ أو ناقص: خلط نسخ مختلفة (مثل المضغوطة وغير المضغوطة). اضبطVaryبدقّة.
مشاكل الكاش وحلولها
عند مواجهة سلوك غريب، هذا الجدول التشخيصي يربط العَرَض بالسبب والحلّ:
| المشكلة | السبب المحتمل | الحلّ |
|---|---|---|
| الكاش القديم (Stale) | TTL طويل أو إبطال لم يحدث | أبطل النسخة صراحةً أو قصّر المدّة |
| المحتوى لا يتحدّث بعد التعديل | كاش صفحة/CDN لم يُبطَل | فرّغ كاش الصفحة وأبطل على CDN (Purge) |
| تغييرات التصميم لا تظهر | كاش متصفّح للـCSS/JS القديم | اعتمد hash في أسماء الملفات |
| صفحة مستخدم تظهر لمستخدم آخر | تخزين صفحة شخصية بالخطأ | استثنِ صفحات الدخول، اضبط private |
| الكود الجديد لا يعمل بعد النشر | OPcache يحمل البايت كود القديم | فرّغ OPcache / أعد تشغيل PHP-FPM |
| تعارض بعد تثبيت إضافة كاش | إضافتا كاش صفحة معًا | أبقِ واحدة فقط واحذف الأخرى |
| موجة بطء دورية | انتهاء كاش جماعي (Stampede) | استخدم إبطالًا متدرّجًا وأقفال إعادة بناء |
الكاش القديم (Stale Content)
أكثر الشكاوى شيوعًا: "عدّلت المحتوى لكن الزوار يرون القديم". تتبّع الطبقات من الأقرب للزائر: امسح كاش المتصفّح (أو جرّب نافذة خاصّة)، فرّغ كاش الصفحة على الخادم، ثم أبطل على CDN. غالبًا تكون إحدى الطبقات لم تُبطَل. الحلّ الجذري هو ربط النشر بإبطال تلقائي لكل الطبقات المتأثّرة.
كاش صفحات مسجّلي الدخول
إذا رأى مستخدم بيانات مستخدم آخر، فهذا غالبًا تخزين صفحة شخصية كنسخة عامة. تأكّد أن إضافة/طبقة الكاش تستثني الصفحات التي تحمل كوكي تسجيل دخول، وأن الاستجابات الشخصية تحمل Cache-Control: private. هذه ليست مشكلة أداء بل ثغرة خصوصية يجب علاجها فورًا.
تعارض إضافتي كاش
تثبيت إضافتي كاش صفحة معًا (مثل تشغيل إضافة كاش عامة فوق كاش LiteSpeed على مستوى الخادم) يسبّب تكرارًا وتعارضًا. القاعدة: طبقة كاش صفحة واحدة فقط. إن كان خادمك يقدّم كاشًا على مستواه، استخدم إضافة الكاش المتوافقة معه وعطّل أي كاش صفحة آخر، مع إبقاء كاش الكائنات (Redis) فعّالًا منفصلًا.
الخلاصة
الكاش ليس زرًّا واحدًا بل منظومة طبقات متعاونة: كاش المتصفّح يقرّب الملفات من الزائر، كاش الصفحة يتخطّى توليد HTML، كاش الكائنات يخفّف قاعدة البيانات، OPcache يسرّع تنفيذ الكود، والـCDN يقرّب المحتوى جغرافيًا. كل طبقة تحلّ مشكلة محدّدة، والإعداد الصحيح يجمعها دون تعارض.
ابدأ بالأساسيات عالية الأثر: رؤوس كاش صحيحة للأصول الثابتة (سنة + hash)، كاش صفحة للمحتوى العام، وCDN أمام موقعك. ثم أضف كاش الكائنات وOPcache على مستوى الخادم إن كانت بيئتك تتيحهما. وتذكّر أن الجزء الأصعب دائمًا هو الإبطال: اربطه بالأحداث، أبطل بدقّة لا بشمول، واستثنِ المحتوى الشخصي. بهذا تحصل على سرعة دائمة دون مفاجآت المحتوى القديم. كل هذا جزء من صورة أوسع تجدها في دليل تسريع موقعك.
جاهز لإطلاق موقعك على استضافة سريعة؟
خطط استضافة wpressly على أقراص NVMe مع SSL مجاني ودعم عربي — اختر الخطة المناسبة لحجمك وانطلق اليوم.
اكتشف خطط الاستضافةالأسئلة الشائعة
ما الفرق بين كاش الصفحة وكاش المتصفّح؟ كاش الصفحة يعمل على الخادم ويخزّن HTML النهائي ليُخدَم لكل الزوار دون إعادة توليد. كاش المتصفّح يعمل على جهاز الزائر ويخزّن الملفات الثابتة (CSS/JS/صور) لتجنّب إعادة تنزيلها في الزيارات التالية. الأول يقلّل عمل الخادم، والثاني يقلّل حركة الشبكة للزائر نفسه.
هل يحلّ الـCDN محلّ كاش الخادم؟ لا، فهما يكمّلان بعضهما. كاش الخادم (صفحة/كائنات) يسرّع توليد المحتوى على الأصل، بينما الـCDN يسرّع توصيله للزائر من أقرب نقطة جغرافية. أفضل أداء يأتي من تشغيلهما معًا: محتوى يُولَّد بسرعة من الأصل ويُوزَّع بسرعة من الحافة.
ما معدّل الإصابة الجيّد للكاش؟ لا توجد قيمة مطلقة، لكن عمومًا كلما اقترب معدّل الإصابة من 90٪ فأعلى كان الكاش يعمل جيّدًا للأصول الثابتة والمحتوى العام. معدّل منخفض قد يعني مدّة قصيرة جدًا، أو محتوى شخصيًا يُخزَّن بلا فائدة، أو مفاتيح كاش مجزّأة أكثر من اللازم.
لماذا لا تظهر تعديلاتي رغم حفظها؟ غالبًا لأن إحدى طبقات الكاش لم تُبطَل بعد التحديث. تتبّع الطبقات من الأقرب: كاش المتصفّح، ثم كاش الصفحة على الخادم، ثم الـCDN. جرّب نافذة تصفّح خاصّة لاستبعاد كاش المتصفّح، ثم فرّغ كاش الصفحة وأبطل على CDN.
هل يمكن تخزين صفحات تتطلّب تسجيل دخول؟
ليس كصفحة كاملة عامة، لأن ذلك قد يسرّب بيانات مستخدم لآخر. استثنِ هذه الصفحات من كاش الصفحة، واضبط Cache-Control: private، واستخدم كاش الكائنات للأجزاء المشتركة المكلفة فقط. الأجزاء الشخصية تُحقَن بعد التحميل أو تُجلَب ديناميكيًا.
ما الفرق بين no-cache وno-store؟
no-cache لا يعني منع التخزين، بل يعني أن المتصفّح يجب أن يتحقّق من الخادم قبل استخدام النسخة المخزّنة. أما no-store فيمنع التخزين نهائيًا ويُستخدم للبيانات الحسّاسة التي يجب ألّا تُحفَظ في أي مكان.
كم مدّة الكاش المناسبة للصور وملفات CSS وJS؟
الأصول الثابتة التي تحمل بصمة (hash) في اسمها يمكن تخزينها سنة كاملة مع immutable، لأن أي تغيير ينتج اسمًا جديدًا يكسر الكاش تلقائيًا. أما HTML فيبقى قصير المدّة (دقائق إلى ساعات) مع الاعتماد على الإبطال الصريح عند التحديث.
هل أحتاج كاش الكائنات (Redis) لموقع صغير؟ ليس دائمًا. المواقع الصغيرة العامة تستفيد أكثر من كاش الصفحة الذي يتخطّى المعالجة كلّها. كاش الكائنات يصبح مهمًّا للمواقع الديناميكية ذات الاستعلامات المتكرّرة المكلفة أو الصفحات التي لا يمكن تخزينها كصفحة كاملة. ابدأ بكاش الصفحة وأضف Redis عند الحاجة.
هل تشغيل إضافتي كاش يحسّن الأداء؟ لا، بل يضرّه غالبًا. إضافتان تديران كاش الصفحة معًا تتعارضان وتنتجان ملفات تالفة وسلوكًا غير متوقّع. استخدم أداة كاش صفحة واحدة شاملة، ويمكن أن يعمل معها كاش الكائنات (Redis) بشكل منفصل دون تعارض.