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