از درخواست‌های غیرضروری شبکه با کش HTTP جلوگیری کنید

ایلیا گریگوریک
ایلیا گریگوریک
جف پوسنیک
جف پوسنیک

واکشی منابع از طریق شبکه هم کند و هم گران است:

  • پاسخ های بزرگ نیاز به رفت و برگشت های زیادی بین مرورگر و سرور دارند.
  • صفحه شما تا زمانی که تمام منابع حیاتی آن به طور کامل دانلود نشوند بارگیری نمی شود.
  • اگر شخصی با یک طرح داده تلفن همراه محدود به سایت شما دسترسی پیدا کند، هر درخواست شبکه غیر ضروری پول او را هدر می دهد.

چگونه می توانید از درخواست های غیر ضروری شبکه جلوگیری کنید؟ حافظه پنهان HTTP مرورگر اولین خط دفاعی شماست. این لزوماً قدرتمندترین یا منعطف ترین رویکرد نیست و شما کنترل محدودی بر طول عمر پاسخ های حافظه پنهان دارید، اما مؤثر است، در همه مرورگرها پشتیبانی می شود و به کار زیادی نیاز ندارد.

این راهنما به شما اصول اولیه اجرای موثر حافظه پنهان HTTP را نشان می دهد.

سازگاری مرورگر

در واقع یک API به نام HTTP Cache وجود ندارد. این نام عمومی مجموعه‌ای از APIهای پلتفرم وب است. این API ها در همه مرورگرها پشتیبانی می شوند:

نحوه عملکرد کش HTTP

تمام درخواست‌های HTTP که مرورگر می‌کند ابتدا به حافظه پنهان مرورگر هدایت می‌شوند تا بررسی شود که آیا یک پاسخ ذخیره‌شده معتبر وجود دارد که می‌تواند برای انجام درخواست استفاده شود. اگر مطابقت وجود داشته باشد، پاسخ از حافظه پنهان خوانده می‌شود، که هم تأخیر شبکه و هم هزینه‌های داده‌ای که انتقال متحمل می‌شود را حذف می‌کند.

رفتار حافظه پنهان HTTP توسط ترکیبی از سرصفحه‌های درخواست و سرصفحه‌های پاسخ کنترل می‌شود. در یک سناریوی ایده آل، هم بر کد برنامه وب خود (که سرصفحه های درخواست را تعیین می کند) و هم بر پیکربندی وب سرور خود (که هدرهای پاسخ را تعیین می کند) کنترل خواهید داشت.

مقاله MDN's HTTP Caching را برای یک نمای کلی مفهومی عمیق تر بررسی کنید.

سرصفحه های درخواست: به پیش فرض ها پایبند باشید (معمولا)

در حالی که تعدادی سرصفحه مهم وجود دارد که باید در درخواست‌های خروجی برنامه وب شما گنجانده شود، مرورگر تقریباً همیشه مراقب تنظیم آنها از طرف شما هنگام درخواست است. هدرهای درخواستی که بر بررسی تازگی تأثیر می گذارند، مانند 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 های نسخه شده

چگونه 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 رویکرد توصیه شده است زیرا دقیق تر است.

مثال ETag

فرض کنید 120 ثانیه از واکشی اولیه گذشته است و مرورگر درخواست جدیدی را برای همان منبع آغاز کرده است. ابتدا مرورگر حافظه پنهان HTTP را بررسی می کند و پاسخ قبلی را پیدا می کند. متأسفانه، مرورگر نمی تواند از پاسخ قبلی استفاده کند زیرا پاسخ اکنون منقضی شده است. در این مرحله، مرورگر می تواند یک درخواست جدید ارسال کند و پاسخ کامل جدید را دریافت کند. با این حال، این ناکارآمد است زیرا اگر منبع تغییر نکرده باشد، دلیلی برای دانلود همان اطلاعاتی که از قبل در حافظه پنهان وجود دارد وجود ندارد! این مشکلی است که توکن های اعتبارسنجی، همانطور که در هدر ETag مشخص شده است، برای حل آن طراحی شده اند. سرور یک توکن دلخواه را تولید و برمی گرداند که معمولاً هش یا اثر انگشت دیگری از محتویات فایل است. مرورگر نیازی به دانستن نحوه ایجاد اثر انگشت ندارد. فقط باید در درخواست بعدی آن را به سرور ارسال کند. اگر اثر انگشت همچنان یکسان است، منبع تغییر نکرده است و مرورگر می‌تواند از دانلود صرفنظر کند.

با تنظیم ETag یا Last-Modified ، در نهایت درخواست اعتبارسنجی مجدد را بسیار کارآمدتر خواهید کرد. آنها در نهایت سرصفحه های درخواست If-Modified-Since یا If-None-Match را فعال می کنند که در سرصفحه های درخواست ذکر شده اند.

وقتی یک سرور وب با پیکربندی مناسب آن سرصفحه‌های درخواست ورودی را می‌بیند، می‌تواند تأیید کند که آیا نسخه منبعی که مرورگر از قبل در حافظه پنهان HTTP خود دارد با آخرین نسخه در سرور وب مطابقت دارد یا خیر. اگر مطابقت وجود داشته باشد، سرور می‌تواند با یک پاسخ HTTP 304 Not Modified پاسخ دهد، که معادل «هی، به استفاده از آنچه قبلاً دریافت کرده‌ای ادامه بده!» هنگام ارسال این نوع پاسخ، داده‌های بسیار کمی برای انتقال وجود دارد، بنابراین معمولاً سریع‌تر از ارسال نسخه‌ای از منبع واقعی درخواستی است.

نموداری از مشتری که درخواست یک منبع می کند و سرور با هدر 304 پاسخ می دهد.
مرورگر /file از سرور درخواست می‌کند و شامل سرصفحه If-None-Match تا به سرور دستور دهد فقط در صورتی که ETag فایل روی سرور با مقدار If-None-Match مرورگر مطابقت نداشته باشد، فایل کامل را برگرداند. در این مورد، 2 مقدار مطابقت دارند، بنابراین سرور یک پاسخ 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 هستید، بهترین شیوه های ذخیره سازی و راهنمای گچاهای حداکثر سنی جیک آرچیبالد را بررسی کنید.

برای راهنمایی در مورد نحوه بهینه سازی استفاده از حافظه پنهان برای بازدیدکنندگان بازگشتی، به 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 پاسخ مجاز به ذخیره سازی در حافظه پنهان نیست و باید در هر درخواست به طور کامل واکشی شود.