واکشی منابع از طریق شبکه هم کند و هم گران است:
- پاسخ های بزرگ نیاز به رفت و برگشت های زیادی بین مرورگر و سرور دارند.
- صفحه شما تا زمانی که تمام منابع حیاتی آن به طور کامل دانلود نشوند بارگیری نمی شود.
- اگر شخصی با یک طرح داده تلفن همراه محدود به سایت شما دسترسی پیدا کند، هر درخواست شبکه غیر ضروری پول او را هدر می دهد.
چگونه می توانید از درخواست های غیر ضروری شبکه جلوگیری کنید؟ حافظه پنهان HTTP مرورگر اولین خط دفاعی شماست. این لزوماً قدرتمندترین یا منعطف ترین رویکرد نیست و شما کنترل محدودی بر طول عمر پاسخ های حافظه پنهان دارید، اما مؤثر است، در همه مرورگرها پشتیبانی می شود و به کار زیادی نیاز ندارد.
این راهنما به شما اصول اولیه اجرای موثر حافظه پنهان HTTP را نشان می دهد.
سازگاری با مرورگر
در واقع یک API به نام HTTP Cache وجود ندارد. این نام عمومی مجموعهای از APIهای پلتفرم وب است. این API ها در همه مرورگرها پشتیبانی می شوند:
Cache-Control
ETag
Last-Modified
نحوه عملکرد کش HTTP
تمام درخواستهای HTTP که مرورگر میکند ابتدا به حافظه پنهان مرورگر هدایت میشوند تا بررسی شود که آیا یک پاسخ ذخیرهشده معتبر وجود دارد که میتواند برای انجام درخواست استفاده شود. اگر مطابقت وجود داشته باشد، پاسخ از حافظه پنهان خوانده میشود، که هم تأخیر شبکه و هم هزینههای دادهای که انتقال متحمل میشود را حذف میکند.
رفتار حافظه پنهان HTTP توسط ترکیبی از سرصفحههای درخواست و سرصفحههای پاسخ کنترل میشود. در یک سناریوی ایده آل، هم بر کد برنامه وب خود (که سرصفحه های درخواست را تعیین می کند) و هم بر پیکربندی وب سرور خود (که هدرهای پاسخ را تعیین می کند) کنترل خواهید داشت.
برای یک مرور مفهومی عمیق تر، به مقاله HTTP Caching 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 های نسخه شده
فرض کنید سرور شما به مرورگرها دستور می دهد که یک فایل CSS را به مدت 1 سال کش کنند ( Cache-Control: max-age=31536000
) اما طراح شما یک به روز رسانی اضطراری ایجاد کرده است که باید فوراً آن را اجرا کنید. چگونه به مرورگرها اطلاع میدهید که کپی ذخیره شده «بیات شده» فایل را بهروزرسانی کنند؟ شما نمی توانید، حداقل بدون تغییر URL منبع.
پس از اینکه مرورگر پاسخ را در حافظه پنهان ذخیره کرد، از نسخه ذخیره شده تا زمانی استفاده می شود که دیگر تازه نباشد، همانطور که با max-age
تعیین می شود یا expires
، یا تا زمانی که به دلایل دیگری از حافظه پنهان خارج شود - به عنوان مثال، کاربر حافظه پنهان مرورگر خود را پاک می کند. در نتیجه، کاربران مختلف ممکن است هنگام ساخت صفحه از نسخههای مختلف فایل استفاده کنند: کاربرانی که به تازگی منبع را واکشی کردهاند از نسخه جدید استفاده میکنند، در حالی که کاربرانی که نسخه قبلی (اما هنوز معتبر) را در حافظه پنهان ذخیره کردهاند، از نسخه قدیمیتر آن استفاده میکنند. پاسخ
چگونه میتوانید بهترین هر دو جهان را به دست آورید: حافظه پنهان سمت مشتری و بهروزرسانیهای سریع؟ شما URL منبع را تغییر میدهید و کاربر را مجبور میکنید تا پاسخ جدید را هر زمان که محتوای آن تغییر کرد دانلود کند. معمولاً، این کار را با جاسازی اثر انگشت فایل یا شماره نسخه در نام فایل آن انجام میدهید - به عنوان مثال style.x234dff.css
.
هنگام پاسخ به درخواستهایی برای نشانیهای اینترنتی که حاوی اطلاعات « اثر انگشت » یا نسخهسازی هستند و محتوای آنها هرگز تغییر نمیکند، Cache-Control: max-age=31536000
به پاسخهای خود اضافه کنید.
تنظیم این مقدار به مرورگر میگوید که وقتی نیاز به بارگیری همان URL در هر زمان در یک سال آینده داشته باشد (31536000 ثانیه؛ حداکثر مقدار پشتیبانی شده)، میتواند بلافاصله از مقدار موجود در حافظه پنهان HTTP استفاده کند، بدون اینکه نیازی به درخواست شبکه داشته باشد. وب سرور شما اصلا این عالی است—شما فوراً قابلیت اطمینان و سرعتی را که از اجتناب از شبکه به دست می آید به دست آورده اید!
ابزارهای ساخت مانند بسته وب میتوانند فرآیند اختصاص اثر انگشت هش به URL دارایی شما را خودکار کنند .
اعتبار سنجی مجدد سرور برای URL های بدون نسخه
متأسفانه، همه URL هایی که بارگیری می کنید نسخه بندی نشده اند. شاید نتوانید یک مرحله ساخت را قبل از استقرار برنامه وب خود اضافه کنید، بنابراین نمی توانید هش را به URL دارایی خود اضافه کنید. و هر برنامه وب به فایلهای HTML نیاز دارد—این فایلها (تقریباً!) هرگز شامل اطلاعات نسخهسازی نمیشوند، زیرا هیچکس زحمت استفاده از برنامه وب شما را به خود نمیدهد اگر به خاطر داشته باشد که URL بازدیدکننده https://example.com/index.34def12.html
است. 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
نیز می تواند کمک کننده باشد. همانطور که در سرصفحههای Response ذکر شد، ETag
و Last-Modified
هر دو هدف یکسانی را دنبال میکنند: تعیین اینکه آیا مرورگر نیاز به بارگیری مجدد یک فایل کش که منقضی شده است یا خیر. توصیه می کنیم از ETag
استفاده کنید زیرا دقیق تر است.
فرض کنید 120 ثانیه از واکشی اولیه گذشته است و مرورگر درخواست جدیدی را برای همان منبع آغاز کرده است. ابتدا مرورگر حافظه پنهان HTTP را بررسی می کند و پاسخ قبلی را پیدا می کند. متأسفانه، مرورگر نمی تواند از پاسخ قبلی استفاده کند زیرا پاسخ اکنون منقضی شده است. در این مرحله، مرورگر می تواند یک درخواست جدید ارسال کند و پاسخ کامل جدید را دریافت کند. با این حال، این ناکارآمد است زیرا اگر منبع تغییر نکرده باشد، دلیلی برای دانلود همان اطلاعاتی که از قبل در حافظه پنهان وجود دارد وجود ندارد!
این مشکلی است که توکن های اعتبارسنجی، همانطور که در هدر ETag
مشخص شده است، برای حل آن طراحی شده اند. سرور یک توکن دلخواه را تولید و برمی گرداند که معمولاً هش یا اثر انگشت دیگری از محتویات فایل است. مرورگر نیازی به دانستن نحوه ایجاد اثر انگشت ندارد. فقط باید در درخواست بعدی آن را به سرور ارسال کند. اگر اثر انگشت همچنان یکسان است، منبع تغییر نکرده است و مرورگر میتواند از دانلود صرفنظر کند.
تنظیم ETag
یا Last-Modified
، درخواست اعتبارسنجی مجدد را بسیار کارآمدتر می کند و به آن اجازه می دهد سرصفحه های درخواست If-Modified-Since
یا If-None-Match
ذکر شده در سرصفحه های درخواست را فعال کند.
وقتی یک سرور وب با پیکربندی مناسب آن سرصفحههای درخواست ورودی را میبیند، میتواند تأیید کند که آیا نسخه منبعی که مرورگر از قبل در حافظه پنهان HTTP خود دارد با آخرین نسخه در سرور وب مطابقت دارد یا خیر. اگر مطابقت وجود داشته باشد، سرور میتواند با یک پاسخ HTTP 304 Not Modified
پاسخ دهد، که معادل «هی، به استفاده از آنچه قبلاً دریافت کردهای ادامه بده!» هنگام ارسال این نوع پاسخ، دادههای بسیار کمی برای انتقال وجود دارد، بنابراین معمولاً سریعتر از ارسال نسخهای از منبع واقعی درخواستی است.
خلاصه
حافظه پنهان HTTP یک راه موثر برای بهبود عملکرد بار است زیرا درخواست های غیر ضروری شبکه را کاهش می دهد. در همه مرورگرها پشتیبانی میشود و راهاندازی آن به کار زیادی نیاز ندارد.
پیکربندیهای Cache-Control
زیر شروع خوبی هستند:
-
Cache-Control: no-cache
برای منابعی که باید قبل از هر استفاده مجدداً با سرور تأیید شوند. -
Cache-Control: no-store
برای منابعی که هرگز نباید کش شوند. -
Cache-Control: max-age=31536000
برای منابع نسخه شده.
و سربرگ ETag
یا Last-Modified
می تواند به شما کمک کند تا منابع حافظه نهان منقضی شده را مجدداً اعتبارسنجی کنید.
بیشتر بدانید
اگر میخواهید فراتر از اصول اولیه استفاده از هدر Cache-Control
بروید، بهترین شیوههای ذخیرهسازی جیک آرچیبالد و راهنمای گچهای حداکثر سن را بررسی کنید.
برای راهنمایی در مورد نحوه بهینه سازی استفاده از حافظه پنهان برای بازدیدکنندگان بازگشتی، به Love your cache مراجعه کنید.
ضمیمه: نکات بیشتر
اگر زمان بیشتری دارید، در اینجا روشهای دیگری وجود دارد که میتوانید استفاده از حافظه پنهان HTTP را بهینه کنید:
- از URL های ثابت استفاده کنید. اگر محتوای یکسانی را در URL های مختلف ارائه دهید، آن محتوا چندین بار واکشی و ذخیره می شود.
- ریزش را به حداقل برسانید. اگر بخشی از یک منبع (مانند یک فایل CSS) اغلب بهروزرسانی میشود، در حالی که بقیه فایل بهروزرسانی نمیشود (مانند کد کتابخانه)، کدهایی که اغلب بهروزرسانی میشوند را به یک فایل جداگانه تقسیم کنید و از یک استراتژی ذخیره موقت کوتاه مدت برای موارد مکرر استفاده کنید. به روز رسانی کد و یک استراتژی طولانی مدت ذخیره برای کد که اغلب تغییر نمی کند.
- اگر درجه ای از کهنگی در خط مشی
Cache-Control
شما قابل قبول است، دستورالعمل جدیدstale-while-revalidate
را بررسی کنید.
پیوست: فلوچارت Cache-Control
ضمیمه: نمونه های Cache-Control
مقدار Cache-Control | توضیح |
---|---|
max-age=86400 | پاسخ را می توان تا 1 روز (60 ثانیه در 60 دقیقه در 24 ساعت) توسط مرورگرها و حافظه های پنهان واسطه ذخیره کرد. |
private, max-age=600 | پاسخ را می توان توسط مرورگر (اما نه حافظه پنهان) تا 10 دقیقه (60 ثانیه در 10 دقیقه) در حافظه پنهان نگه داشت. |
public, max-age=31536000 | پاسخ را می توان توسط هر کش به مدت 1 سال ذخیره کرد. |
no-store | پاسخ مجاز به ذخیره سازی در حافظه پنهان نیست و باید در هر درخواست به طور کامل واکشی شود. |