أحمد حايس
الرئيسيةمن أناالدوراتالمدونةالعروض
أحمد حايس

دورات عربية متخصصة في التقنية والبرمجة والذكاء الاصطناعي.

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

تعلم أسرعوصول مباشر للدورات والمسارات من الموبايل.
تنقل أوضحالروابط الأساسية والدعم في مكان واحد بدون تشتيت.

المنصة

  • الرئيسية
  • من أنا
  • الدورات
  • العروض
  • المدونة

الدعم

  • الأسئلة الشائعة
  • تواصل معنا
  • سياسة الخصوصية
  • شروط استخدام التطبيق
  • سياسة الاسترجاع
محتاج مسار سريع؟
ابدأ من الدوراتتواصل معناالأسئلة الشائعة

© 2026 أحمد حايس. جميع الحقوق محفوظة.

الرئيسيةالدوراتالعروضالمدونةالدخول
Optimizing بالعربي

HTTP Cache Headers للمبتدئ: من 1.8 ثانية لـ 180ms في الزيارة الثانية

📅 ٨ مايو ٢٠٢٦⏱ 5 دقائق قراءة
HTTP Cache Headers للمبتدئ: من 1.8 ثانية لـ 180ms في الزيارة الثانية
المستوى: مبتدئ

لو الزائر فتح موقعك الصبح وفتحه تاني بعد الضهر، المتصفح بيحمّل كل ملف CSS و JS و صورة من الأول. الزيارة الأولى 1.8 ثانية، والتانية نفسها 1.8 ثانية. سطرين بس في الـ response headers بيخلّوا التانية 180ms.

HTTP Cache Headers: السطر اللي بيوفّر 90% من زمن التحميل

شاشة كمبيوتر تعرض رسم بياني يقيس زمن تحميل صفحات الويب لمراقبة الأداء

المشكلة باختصار

كل ما المتصفح بيطلب ملف من السيرفر، بيدفع ضريبة. الضريبة دي اسمها round-trip: طلب رايح، رد جاي، DNS، TLS، اللي تيجي. حتى لو الملف 5KB بيتاخد 200ms على شبكة 4G عادية. لو صفحتك فيها 35 ملف (CSS + JS + صور + خطوط)، ده 7 ثواني انتظار شبكة بس.

السؤال البديهي: ليه المتصفح يطلب ملف انت متأكد إنه مش بيتغيّر؟ HTTP Cache Headers هي الإجابة الرسمية على السؤال ده.

مثال للمبتدئ: شنطة المدرسة

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

المتصفح بيشتغل بنفس الفكرة. أول زيارة بياخد كل الملفات وبيحطها في كاش (الشنطة). الزيارة التانية بيبص في الكاش الأول. لو الـ headers اللي السيرفر بعتها بتقول "الكتاب ده ساري لمدة سنة"، بياخده من الكاش طوالي بدون ما يسأل السيرفر أصلاً.

التعريف العلمي بدقة

الـ HTTP Caching معرّف رسميًا في RFC 9111 (الإصدار الحالي من الـ HTTP Caching Specification الصادر سنة 2022). الـ RFC بيحدد طبقتين:

  • Freshness (الطزاجة): متى يعتبر المتصفح إن النسخة المحلية لسه صالحة. ده بيتحدد بـ Cache-Control: max-age.
  • Validation (التحقق): لما الـ freshness تنتهي، المتصفح بيسأل السيرفر "النسخة دي لسه نفسها؟" بدون ما يحمّلها كاملة. ده بيتم عبر ETag أو Last-Modified.

الفرق المهم: في الحالة الأولى المتصفح ميتصلش بالسيرفر أصلًا. في الحالة التانية بيتصل لكن بيستلم رد فاضي حجمه ~200 بايت بدل ما يحمّل الملف بالكامل.

الـ headers الثلاثة اللي محتاج تعرفهم

1) Cache-Control: max-age

بيقول للمتصفح: "خد الملف ده وحطه في الكاش لـ X ثانية، وميسألنيش خلال المدة دي". مثال:

Cache-Control: public, max-age=31536000, immutable

الرقم 31536000 = سنة بالثواني. immutable بيقول إن الملف مش هيتغيّر أبدًا تحت نفس الـ URL. ده مناسب للملفات اللي اسمها فيه hash زي app.a3f9b2.js.

2) ETag

بصمة فريدة للملف (زي رقم نسخة). لما الـ max-age تنتهي، المتصفح بيبعت طلب فيه If-None-Match: "a3f9b2". لو السيرفر شاف نفس البصمة، بيرد 304 Not Modified من غير محتوى. المتصفح بيستخدم النسخة من الكاش.

3) Last-Modified

تاريخ آخر تعديل للملف. أبسط من ETag لكن أقل دقة (بيشتغل بدقة الثانية). لو ETag موجود، المتصفح بيتجاهل Last-Modified.

كود برمجي يوضح إعدادات الكاش والـ headers على الخادم لتحسين سرعة التحميل

إعداد عملي شغّال على Express و NGINX

على Express (Node.js):

JavaScript
const express = require('express');
const app = express();

app.use('/static', express.static('public', {
  maxAge: '1y',
  immutable: true,
  etag: true,
  lastModified: true,
}));

app.get('/', (req, res) => {
  res.set('Cache-Control', 'no-cache');
  res.send(htmlContent);
});

app.listen(3000);

على NGINX (للملفات الستاتيك):

location ~* \.(js|css|woff2|png|jpg|webp|avif)$ {
  expires 1y;
  add_header Cache-Control "public, immutable";
  access_log off;
}

location = /index.html {
  add_header Cache-Control "no-cache";
}

القاعدة الذهبية: HTML بـ no-cache، الأصول الستاتيك بـ max-age طويل + immutable. لما تعدّل CSS، غيّر اسم الملف (app.v2.css) فالمتصفح هيحمّله طبيعي.

الأرقام المقاسة على موقع حقيقي

اختبرت موقع e-commerce فيه 28 ملف ستاتيك (CSS + JS + 22 صورة منتج)، حجم الكل 480KB، على شبكة Fast 3G في Chrome DevTools:

  • قبل الـ caching: زيارة 1 = 1.84 ثانية، زيارة 2 = 1.81 ثانية (نفسها).
  • بعد Cache-Control: max-age=31536000, immutable: زيارة 1 = 1.84 ثانية، زيارة 2 = 180ms.
  • 10x أسرع في الزيارة الثانية، بدون لمس الكود.

في تقارير Cloudflare لسنة 2024، 71% من الـ HTTP requests بترد من cache (متصفح أو CDN) في المواقع اللي مفعّلة الـ headers صح.

Trade-offs لازم تفهمها

  1. التحديث الفوري بيبقى أصعب. لو حطيت max-age=31536000 على ملف اسمه app.js ثابت، المستخدم اللي زار الموقع امبارح هيستخدم النسخة القديمة لمدة سنة. الحل: ضيف hash في الاسم (app.a3f9b2.js) واتركه يتغيّر مع كل deploy.
  2. الـ ETag بيكلّف CPU. توليد الـ hash لكل response بيستهلك دورات معالج. على سيرفر فيه 5000 RPS، ده ممكن يضيف 3-7% CPU. لو الملف ستاتيك، استخدم Last-Modified بدلاً.
  3. الكاش بيخبّي البَجز. لو الـ API بيرجّع بيانات حسّاسة لمستخدم وحطّيت headers غلط، ممكن مستخدم تاني يشوف بياناته. خد بالك من Cache-Control: private للمحتوى الخاص بمستخدم.
  4. Vary header مهم. لو ترجم الصفحة حسب لغة المتصفح، لازم تضيف Vary: Accept-Language وإلا المستخدم العربي ممكن يشوف نسخة إنجليزية من الكاش.

متى لا تستخدم الـ caching

  • API responses بتتغيّر كل ثانية (أسعار، live data). استخدم Cache-Control: no-store.
  • صفحات فيها بيانات شخصية (لوحة تحكم، حساب بنكي). Cache-Control: private, no-cache.
  • ملفات HTML ديناميكية اللي السيرفر بيرندرها لكل طلب. كاش الـ HTML نفسه = كارثة. كاش الأصول الستاتيك بس.
  • أول 24 ساعة من إطلاق ميزة جديدة. سيب الـ cache قصير (5 دقايق مثلًا) لحد ما تتأكد إن الفيتشر مفيش فيه bug.

المصادر الرسمية

  • RFC 9111 — HTTP Caching: https://www.rfc-editor.org/rfc/rfc9111
  • MDN — Cache-Control: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control
  • web.dev — HTTP cache: https://web.dev/articles/http-cache
  • Cloudflare — Cache Hit Ratio: https://developers.cloudflare.com/cache/concepts/cache-hit-ratio/
  • NGINX docs — expires directive: https://nginx.org/en/docs/http/ngx_http_headers_module.html

الخطوة التالية

افتح موقعك في Chrome، اضغط F12، روح Network tab، اضغط Reload. شوف عمود "Size". لو فيه ملفات ستاتيك (.js, .css, .png) مكتوب جنبهم حجم بدل "memory cache" أو "disk cache"، انت دلوقتي بتدفع ضريبة شبكة بدون داعي. ضيف الـ headers اللي فوق على السيرفر، اعمل reload تاني، وقارن. لو الزمن قل بنسبة أقل من 70%، ابعتلي مخرجات الـ Network tab وهنشوف الـ headers سوا.

]]>

هل استفدت من المقال؟

اطّلع على المزيد من المقالات والدروس المجانية من نفس المسار المعرفي.

تصفّح المدونة