کش مرورگر را پاک کردی ولی تغییرات سایت هنوز دیده نمی شه؟
فایل CSS رو عوض کردی و هنوز نسخه قدیمی رو می بینی؟ کش مرورگر فقط یکی از چند لایه ای هست که نسخه قدیمی رو نگه می دارن؛ با هم می بینیم تغییرت دقیقاً کجا گیر کرده.

فایل CSS رو عوض کردی، ذخیره کردی، صفحه رو رفرش کردی و هنوز همون نسخه قدیمی رو می بینی. اولین حدس معمولاً کش مرورگره. ولی کش مرورگر فقط یکی از چند جاییه که نسخه قدیمی می تونه بمونه. کش وب سرور، افزونه کش، CDN و هدرهای Cache-Control هم همین کار رو می کنن. پاک کردن کش مرورگر فقط لایه ای رو تازه می کنه که روی دستگاه خودته. اینجا باورهای رایج رو یکی یکی بررسی می کنیم تا ببینی تغییرت دقیقاً کجا گیر کرده.
باور اول: «تغییرم دیده نمی شه، پس کش مرورگرم پره»
یه صفحه تا برسه به چشم کاربر، از چند ایستگاه رد می شه. هر ایستگاه می تونه یه کپی نگه داره: کش اپلیکیشن یا افزونه، کش وب سرور، CDN و آخرش خود مرورگر.
دلیلش ساده ست: کش برای کم کردن درخواست و بالا بردن سرعت ساخته شده و هر لایه مستقل از بقیه کار می کنه. وقتی فایل رو روی سرور عوض می کنی، هیچ پیامی به لایه های دیگه نمی رسه که «نسخه جدید اومده».
یه تشبیه بزنم. رستورانی منوی جدید چاپ کرده، ولی منوی قدیمی هنوز روی میزهای یه شعبه، توی انبار پخش و توی کیف پیک هاست. خالی کردن کشوی میز خودت فقط منوی دست خودت رو عوض می کنه. اول باید بدونی منوی قدیمی کجا مونده.
نقشه لایه ها
- مرورگر: فایل ها رو روی دستگاه کاربر نگه می داره و بسته به هدرها تا مدتی از سرور نمی پرسه.
- CDN: کپی فایل ها رو در نقطه های نزدیک به کاربر نگه می داره.
- کش صفحه روی سرور یا افزونه: خروجی آماده HTML رو ذخیره می کنه تا هر بار از برنامه و دیتابیس ساخته نشه.
- کش آبجکت و OPcache: نتیجه کوئری ها و کد کامپایل شده PHP رو نگه می دارن.

باور دوم: «پاک کردن کش مرورگر مشکل رو برای همه حل می کنه»
نه، نمی کنه. Ctrl+F5 و پاک کردن تاریخچه فقط روی دستگاه خودت اثر دارن. مشتری ای که تو شهر دیگه ای نشسته همون چیزی رو می گیره که CDN یا سرور بهش می ده.
این کارها فقط درخواست تو رو بدون تکیه به کپی محلی می فرستن. اگه CDN یا کش سرور هنوز نسخه قدیمی رو داشته باشه، همون رو دوباره تحویل می گیری. برای همین بعد از هارد ریفرش هم ممکنه چیزی عوض نشه.
سه آزمون سریع قبل از هر چیز
- سایت رو تو پنجره ناشناس باز کن. این طوری کش و کوکی های قبلی دخالت نمی کنن.
- از موبایل و با داده همراه باز کن، نه با وای فای خودت. مسیر شبکه و اپراتور فرق می کنه.
- هدرهای پاسخ رو با curl ببین:
curl -I https://example.ir/assets/style.css
تو خروجی دنبال این ها بگرد: cache-control، age، etag، last-modified. هدرهایی مثل x-cache یا cf-cache-status هم بسته به CDN ممکنه باشن. اگه age عدد بزرگی نشون بده، یعنی پاسخ از یه کش میانی اومده و مدتیه همون کپی رو نگه داشته. این مدرک خیلی بهتر از حدس زدنه.
اگه تغییر تو ناشناس و روی موبایل هم دیده نمی شه، مشکل از کش مرورگر تو نیست. اشتباه رایج اینه که آدم هی کش مرورگر رو پاک کنه و سراغ این بررسی ها نره.
باور سوم: «CDN و کش سرور فقط سرعت رو بالا می برن و به تغییرات کاری ندارن»
دارن، و بیشترین دردسر هم از همین جاست.
CDN هر فایل رو تا پایان مدت اعتبارش نگه می داره. بعد از انتشار نسخه جدید یا باید صبر کنی، یا از پنل CDN پاکسازی (purge) رو بزنی. بعضی CDN ها فقط فایل های ثابت رو کش می کنن و بعضی HTML رو هم. تنظیم پیش فرض سرویسی که استفاده می کنی رو یه بار بخون. اگه پاکسازی رو فقط برای یه آدرس زدی و فایل های وابسته رو نه، ترکیب قدیمی و جدید صفحه رو نیمه خراب نشون می ده.
کش صفحه روی سرور یا افزونه (مثلاً تو وردپرس) HTML آماده نگه می داره. تو قالب یه چیزی عوض کردی، ولی صفحه ها هنوز از روی خروجی ذخیره شده بالا میان. اینجا باید کش صفحه رو خالی کنی، نه مرورگر رو.
OPcache مخصوص کد PHP هست. بسته به تنظیمش (opcache.validate_timestamps و opcache.revalidate_freq) ممکنه تغییر فایل PHP چند ثانیه یا بیشتر دیر دیده بشه. روی سرورهایی که اعتبارسنجی زمانی خاموشه، بعد از انتشار باید php-fpm رو reload کنی.
گاهی هم مشکل اصلاً کش نیست. مثلاً تنظیمات جدید وب سرور بعد از انتشار بارگذاری نشده و فایل هایی که باید برسن، خطای ۴۰۴ می دن. ظاهرش شبیه «تغییرم اعمال نشده» ـه، ولی علتش یه لایه پایین تره. بهتره purge و reload جزو مراحل ثابت هر انتشار باشن. اگه انتشارت دستی نیست و می خوای این مرحله ها خودکار بشن، استقرار خودکار سایت با CI/CD نشون می ده این کارها رو کجای pipeline بذاری.
یه نکته برای فروشگاه های ایرانی: اگه از درگاه پرداخت استفاده می کنی، صفحه سبد خرید، تسویه حساب و بازگشت از درگاه نباید کش بشن. کش شدنشون ممکنه باعث بشه کاربر وضعیت پرداخت یکی دیگه رو ببینه یا سفارشش ثبت نشده به نظر برسه. اگه با چنین علامتی روبه رو شدی، سفارش ثبت نمی شه؛ مشکل بازگشت از درگاه پرداخت رو هم نگاه کن.
باور چهارم: «Cache-Control یه هدر فنیه و به من ربطی نداره»
ربط داره. این هدر تعیین می کنه هر لایه چقدر کپی رو نگه داره. اگه تنظیمش نکنی، مرورگر و CDN با حدس خودشون تصمیم می گیرن و نتیجه قابل پیش بینی نیست. دستورهای مهمش این ها هستن:
| دستور | معنی واقعی | کجا به کار می آد |
|---|---|---|
max-age=N | مرورگر تا N ثانیه بدون پرسیدن از سرور از کپی استفاده کنه | فایل های ثابت |
s-maxage=N | مثل بالا، ولی فقط برای کش های مشترک مثل CDN | وقتی CDN و مرورگر باید رفتار جدا داشته باشن |
no-cache | ذخیره می شه، ولی قبل از استفاده باید از سرور تایید بگیره | صفحه های HTML |
no-store | اصلاً ذخیره نشه | سبد خرید، پنل کاربر، صفحه های حساس |
private | فقط کش مرورگر خود کاربر، نه CDN | محتوای مخصوص هر کاربر |
immutable | تا پایان max-age حتی با رفرش معمولی نپرس (در مرورگرهایی که پشتیبانی می کنن) | فایل هایی که نامشون نسخه دار شده |
یه سوءتفاهم رایج: خیلی ها فکر می کنن no-cache یعنی «ذخیره نکن». در حالی که یعنی «ذخیره کن، ولی قبل از استفاده تایید بگیر». اونی که جلوی ذخیره رو می گیره no-store هست.
تنظیم نمونه تو Nginx
# فایل های ثابت با نام نسخه دار
location ~* \.(css|js|woff2|webp|png|jpg|svg)$ {
add_header Cache-Control "public, max-age=31536000, immutable";
}
# صفحه های HTML
location ~* \.html$ {
add_header Cache-Control "no-cache";
}
بعدش تنظیمات رو بررسی و بارگذاری کن:
sudo nginx -t && sudo systemctl reload nginx
دو تا گیر مهم هست. اول اینکه اگه داخل یه location خودت add_header گذاشتی، هدرهای سطح بالاتر به اون بلوک نمی رسن و باید دوباره بنویسیشون. دوم اینکه immutable با max-age یک ساله فقط وقتی امنه که نام فایل با هر تغییر عوض بشه. وگرنه کاربر تا یک سال نسخه قدیمی رو نگه می داره و رفرش هم کمکی نمی کنه.
اگه روی هاست اشتراکی با cPanel هستی و به تنظیمات وب سرور دسترسی نداری، همین کار با .htaccess و ماژول های mod_headers یا mod_expires شدنیه، به شرطی که روی هاستت فعال باشن.
باور پنجم: «برای دیده شدن تغییرات، زمان کش رو کوتاه کن»
جواب می ده، ولی هزینه داره. کوتاه کردن max-age برای همه چیز یعنی هر بازدید، کاربر دوباره همه فایل ها رو می گیره. نتیجه اش بار بیشتر روی سرور و سرعت کمتره، مخصوصاً تو ساعت های اوج ترافیک یا برای کاربری که اینترنت موبایلش ضعیفه.
راه بهتر اینه که فایل ثابت رو نسخه دار کنی. به جای style.css از style.8f3a1c.css استفاده کن، که بخش وسطش هش محتواست. با هر تغییر، نام عوض می شه و مرورگر و CDN اون رو یه فایل جدید می بینن. نسخه قدیمی هم می مونه تا خودش از کش بیفته و دیگه کسی سراغش نمیاد. ابزارهای بیلد مثل Vite و webpack معمولاً با یه تنظیم ساده همین کار رو برات انجام می دن.

اگه به جای هش از ?v=2 استفاده می کنی، حواست باشه بعضی تنظیمات CDN پارامتر کوئری رو نادیده می گیرن. پس تست کن که واقعاً فایل جدید گرفته می شه. HTML هم باید no-cache بمونه تا همیشه به فایل های نسخه دار جدید اشاره کنه.
این الگو فقط مشکل تازگی تغییرات رو حل نمی کنه، سرعت رو هم بهتر می کنه. اگه می خوای کل زنجیره (هدرها، CDN و بیلد) رو با هم مرور کنیم، بهینه سازی سرعت دقیقاً همین کاره.
از بیرون شروع کن، بعد برو داخل
وقتی می بینی تغییرت دیده نمی شه، به این ترتیب جلو برو:
- تو پنجره ناشناس و از موبایل با داده همراه باز کن. اگه تغییر اونجا هست، مشکل فقط کش مرورگر خودته.
- با
curl -Iهدرهای فایل یا صفحه رو ببین وageوcache-controlرو بخون. - اگه
ageبزرگه یا نشونه ای از cache hit دیدی، CDN رو purge کن. - کش صفحه افزونه یا اپلیکیشن رو خالی کن.
- اگه کد PHP عوض شده، php-fpm رو reload کن یا OPcache رو ریست کن.
- اگه تنظیمات وب سرور رو عوض کردی،
nginx -tبزن و بعد reload کن. - فقط در آخر کش مرورگر رو پاک کن.
این ترتیب جلوی خیلی از «پاک کردم، درست نشد» ها رو می گیره. مهم تر اینکه هر مرحله بهت می گه مشکل تو کدوم لایه بوده و دفعه بعد سریع تر پیداش می کنی. بعد از چند بار تکرار می بینی بیشتر مشکل ها از دو سه جای مشخص میان.
سوالات متداول
اگه کش مرورگر رو پاک کنم به سئو آسیب می زنه؟
نه. کش مرورگر روی دستگاه خودته و ربطی به ایندکس شدن سایتت تو گوگل نداره. ولی تنظیم درست Cache-Control به سرعت سایت کمک می کنه، و سرعت روی تجربه کاربر و سئو اثر می ذاره.
چرا بعضی کاربرها تغییر رو می بینن و بعضی نه؟
چون هر کاربر ممکنه از یه نقطه CDN، یه کش مرورگر یا یه مسیر شبکه متفاوت جواب بگیره. اگه فقط بخشی از CDN پاکسازی شده یا max-age فایل های بعضی کاربرها هنوز تموم نشده، نتیجه فرق می کنه. از age و هدرهای CDN تو خروجی curl می تونی سرنخ بگیری.
برای HTML چه Cache-Control ای بذارم؟
معمولاً no-cache کافیه. مرورگر کپی رو نگه می داره ولی هر بار با ETag یا Last-Modified از سرور می پرسه. اگه صفحه ها کاملاً شخصی هستن (پنل کاربر، سبد خرید)، no-store یا private مناسب تره.
آیا بعد از هر انتشار باید CDN رو purge کنم؟
اگه فایل هات نسخه دار هستن، فقط HTML ها عوض می شن. اگه CDN صفحه های HTML رو هم کش می کنه، همونا رو purge کن؛ وگرنه معمولاً به پاکسازی کامل نیازی نیست. اگه نام فایل ها ثابته، باید فایل های تغییر کرده رو purge کنی. بهتره این مرحله تو فرایند انتشار خودکار باشه و به یادآوری دستی تکیه نکنی.
جمع بندی: اول لایه رو پیدا کن، بعد پاک کن
کش مرورگر فقط یه ایستگاه از مسیره. قبل از هر پاکسازی، با ناشناس، موبایل و curl -I معلوم کن نسخه قدیمی کجا مونده. بعد برای فایل های ثابت نام نسخه دار و max-age بلند بذار و برای HTML از no-cache استفاده کن. بعد از هر تغییر تو تنظیمات سرور هم nginx -t بزن و reload کن.
اگه سرور، CDN و فرایند انتشارت رو خودت مدیریت نمی کنی و نمی خوای هر بار گیر کنی، تیم مدیریت و امن سازی سرور ما این لایه ها رو برات مرتب می کنه.


