کش خود را دوست داشته باشید ❤️

کاربرانی که برای بار دوم سایت شما را بارگذاری می کنند از کش HTTP خود استفاده می کنند، بنابراین مطمئن شوید که به خوبی کار می کند.

این پست همراهی است برای ویدیوی حافظه پنهان خود را دوست داشته باشید ، بخشی از محتوای توسعه‌یافته در Chrome Dev Summit 2020. حتماً این ویدیو را ببینید:

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

در این پست، من در مورد یک پیش‌فرض معقول و مدرن برای کش صحبت می‌کنم – پیش‌فرض که در واقع هیچ کش‌سازی را انجام نمی‌دهد. اما این فقط پیش‌فرض است، و البته جزئی‌تر از «خاموش کردن» است. ادامه مطلب

اهداف

هنگامی که یک سایت برای بار دوم بارگذاری می شود، شما دو هدف دارید:

  1. اطمینان حاصل کنید که کاربران شما به‌روزترین نسخه موجود را دریافت می‌کنند—اگر چیزی را تغییر داده‌اید، باید به سرعت منعکس شود.
  2. شماره 1 را در حالی که تا حد امکان از شبکه واکشی می کنید، انجام دهید

در مفهوم گسترده، شما فقط می خواهید کوچکترین تغییر را برای مشتریان خود ارسال کنید که آنها سایت شما را دوباره بارگذاری کنند. و ساختار سایت خود برای اطمینان از کارآمدترین توزیع هر تغییری چالش برانگیز است (اطلاعات بیشتر در مورد آن در زیر و در ویدیو).

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

پس زمینه

به عنوان توسعه دهندگان وب، همه ما به ایده داشتن یک "کش قدیمی" عادت کرده ایم. اما ما تقریباً به طور غریزی ابزارهای موجود برای حل این مشکل را می دانیم: یک "بازسازی سخت" انجام دهید یا یک پنجره ناشناس باز کنید یا از ترکیبی از ابزارهای توسعه دهنده مرورگر خود برای پاک کردن داده های سایت استفاده کنید.

کاربران معمولی در اینترنت چنین تجملی را ندارند. بنابراین در حالی که ما برخی از اهداف اصلی را داریم که اطمینان حاصل کنیم کاربرانمان با بار دوم خود اوقات خوبی را سپری می کنند، همچنین بسیار مهم است که مطمئن شویم زمان بدی را سپری نمی کنند یا گیر نمی کنند. (اگر مایلید در مورد نحوه گیرکردن سایت web.dev/live صحبت های من را بشنوید، ویدیو را ببینید!)

برای کمی پیش‌زمینه، یک دلیل واقعاً متداول برای «حافظه پنهان قدیمی» در واقع پیش‌فرض سال ۱۹۹۹ برای ذخیره‌سازی پنهان است. این هدر Last-Modified است:

نمودار نشان می دهد که چه مدت دارایی های مختلف توسط مرورگر کاربر ذخیره می شوند
دارایی‌های تولید شده در زمان‌های مختلف (به رنگ خاکستری) برای زمان‌های مختلف ذخیره می‌شوند، بنابراین بار دوم می‌تواند ترکیبی از دارایی‌های ذخیره‌شده و تازه را دریافت کند.

هر فایلی که بارگیری می‌کنید 10 درصد بیشتر از طول عمر فعلی خود، همانطور که مرورگر شما آن را می‌بیند، نگهداری می‌شود. به عنوان مثال، اگر index.html یک ماه پیش ایجاد شده باشد، برای حدود سه روز دیگر توسط مرورگر شما ذخیره می شود.

این یک ایده خوب در گذشته بود، اما با توجه به ماهیت کاملاً یکپارچه وب‌سایت‌های امروزی، این رفتار پیش‌فرض به این معنی است که می‌توان به حالتی رسید که کاربر فایل‌هایی را برای نسخه‌های مختلف وب‌سایت شما طراحی کرده است (مثلاً JS از انتشار روز سه‌شنبه و CSS از انتشار جمعه)، همه به این دلیل است که آن فایل‌ها دقیقاً در همان زمان به‌روزرسانی نشدند.

مسیر پر نور

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

می توانید میزبان وب خود را برای پاسخ به درخواست های وب با این هدر پیکربندی کنید:

Cache-Control: max-age=0,must-revalidate,public

این اساسا می گوید؛ این فایل به هیچ وجه معتبر است، و قبل از اینکه بتوانید دوباره از آن استفاده کنید، باید آن را از شبکه تأیید کنید (در غیر این صورت فقط "پیشنهاد شده" است).

این فرآیند اعتبارسنجی از نظر بایت های منتقل شده نسبتاً ارزان است - اگر یک فایل تصویری بزرگ تغییر نکرده باشد، مرورگر شما یک پاسخ کوچک 304 دریافت می کند - اما هزینه آن تاخیر است زیرا کاربر همچنان باید برای اطلاع از این موضوع به شبکه برود. و این نقطه ضعف اصلی این رویکرد است. این می تواند برای افرادی که دارای اتصالات سریع در جهان اول هستند، و در جایی که CDN انتخابی شما پوشش عالی دارد، بسیار خوب کار می کند، اما برای افرادی که ممکن است در اتصالات تلفن همراه کندتر یا از زیرساخت ضعیف استفاده کنند، نه.

صرف نظر از این، این یک رویکرد مدرن است که پیش‌فرض روی CDN محبوب، Netlify است ، اما تقریباً روی هر CDN قابل پیکربندی است. برای میزبانی Firebase، می توانید این هدر را در بخش میزبانی فایل firebase.json خود قرار دهید:

"headers": [
  // Be sure to put this last, to not override other headers
  {
    "source": "**",
    "headers": [ {
      "key": "Cache-Control",
      "value": "max-age=0,must-revalidate,public"
    }
  }
]

بنابراین در حالی که من هنوز این را به عنوان یک پیش‌فرض معقول پیشنهاد می‌کنم، فقط همین است—پیش‌فرض! برای اطلاع از نحوه ورود و ارتقای پیش فرض ها به ادامه مطلب بروید.

URL های اثر انگشتی

با گنجاندن هش از محتوای فایل به نام دارایی‌ها، تصاویر و غیره که در سایت شما ارائه می‌شود، می‌توانید اطمینان حاصل کنید که این فایل‌ها همیشه محتوای منحصربه‌فردی دارند—به عنوان مثال، فایل‌هایی با نام sitecode.af12de.js ایجاد می‌شوند. هنگامی که سرور شما به درخواست‌های این فایل‌ها پاسخ می‌دهد، می‌توانید با خیال راحت به مرورگرهای کاربر نهایی خود دستور دهید تا با پیکربندی آنها با این هدر، آنها را برای مدت طولانی در حافظه پنهان نگه دارند:

Cache-Control: max-age=31536000,immutable

این مقدار یک سال، در ثانیه است. و با توجه به مشخصات، این به طور موثر برابر با "برای همیشه" است.

نکته مهم این است که این هش ها را با دست تولید نکنید - این کار دستی بیش از حد است! برای کمک به شما می توانید از ابزارهایی مانند Webpack، Rollup و غیره استفاده کنید. حتماً در مورد آنها در گزارش ابزار بیشتر بخوانید.

به یاد داشته باشید که فقط جاوا اسکریپت نیست که می تواند از URL های اثر انگشت بهره مند شود. دارایی هایی مانند آیکون ها، CSS و سایر فایل های داده غیرقابل تغییر نیز می توانند به این صورت نامگذاری شوند. (و حتماً ویدیوی بالا را تماشا کنید تا کمی بیشتر در مورد تقسیم کد بیاموزید، که به شما امکان می دهد هر زمان که سایت شما تغییر می کند کد کمتری ارسال کنید.)

صرف نظر از اینکه سایت شما چگونه به ذخیره سازی نزدیک می شود، این نوع فایل های اثرانگشتی برای هر سایتی که ممکن است بسازید بسیار ارزشمند هستند. اکثر سایت ها در هر نسخه تغییر نمی کنند.

البته، ما نمی‌توانیم صفحات «دوستانه» و کاربرپسند خود را به این شکل تغییر نام دهیم: تغییر نام فایل index.html به index.abcd12.html — این غیر ممکن است، شما نمی‌توانید هر بار به کاربران بگویید که به یک URL جدید بروند. آنها سایت شما را بارگذاری می کنند! این نشانی‌های اینترنتی «دوستانه» را نمی‌توان به این روش تغییر نام داد و در حافظه پنهان ذخیره کرد، که من را به یک حد وسط احتمالی هدایت می‌کند.

حد وسط

بدیهی است که در مورد حافظه پنهان، جایی برای حد وسط وجود دارد. من دو گزینه افراطی ارائه کرده ام. cache never , یا cache forever . و تعدادی فایل وجود خواهد داشت که ممکن است بخواهید برای مدتی در حافظه پنهان نگهداری کنید، مانند URL های "دوستانه" که در بالا ذکر کردم.

اگر می‌خواهید این URL‌های «دوستانه» و HTML آن‌ها را در حافظه پنهان نگه دارید، ارزش این را دارد که به چه وابستگی‌هایی در آن‌ها بپردازید، چگونه ممکن است در حافظه پنهان ذخیره شوند و چگونه ذخیره کردن URL‌های آن‌ها برای مدتی ممکن است روی شما تأثیر بگذارد. بیایید به یک صفحه HTML که شامل تصویری مانند این است نگاه کنیم:

<img src="/images/foo.jpeg" loading="lazy" />

اگر سایت خود را با حذف یا تغییر این تصویر با بارگذاری تنبل به‌روزرسانی یا تغییر دهید، کاربرانی که نسخه ذخیره‌شده HTML شما را مشاهده می‌کنند ممکن است تصویری نادرست یا گم شده دریافت کنند—زیرا آنها هنوز تصویر اصلی /images/foo.jpeg را در حافظه پنهان ذخیره کرده‌اند. دوباره به سایت خود مراجعه کنید

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

به طور کلی، بیشتر راهنماهای موجود در مورد ذخیره سازی در مورد این نوع تنظیمات صحبت می کنند - آیا می خواهید برای یک ساعت، چند ساعت و غیره حافظه پنهان داشته باشید. برای تنظیم این نوع حافظه نهان، از یک هدر مانند این استفاده کنید (که به مدت 3600 ثانیه یا یک ساعت ذخیره می شود):

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

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

گزینه های غیر HTML

به غیر از HTML، برخی از گزینه های دیگر برای فایل هایی که در حد وسط زندگی می کنند عبارتند از:

  • به طور کلی، به دنبال دارایی هایی باشید که بر دیگران تأثیری ندارند

    • به عنوان مثال: از CSS اجتناب کنید، زیرا باعث تغییر در نحوه رندر HTML شما می شود
  • تصاویر بزرگ که به عنوان بخشی از مقالات به موقع استفاده می شود

    • کاربران شما احتمالاً قصد ندارند از هیچ مقاله ای بیش از چند بار بازدید کنند، بنابراین عکس ها یا تصاویر قهرمان را برای همیشه ذخیره نکنید و فضای ذخیره سازی را هدر ندهید.
  • دارایی که نمایانگر چیزی است که خودش مادام العمر دارد

    • داده‌های JSON درباره آب‌وهوا ممکن است فقط هر ساعت یک‌بار منتشر شود، بنابراین می‌توانید نتیجه قبلی را برای یک ساعت در حافظه پنهان ذخیره کنید—در پنجره شما تغییر نمی‌کند.
    • ساخت‌های یک پروژه منبع باز ممکن است دارای نرخ محدود باشند، بنابراین تصویر وضعیت ساخت را در حافظه پنهان نگه دارید تا زمانی که امکان تغییر وضعیت وجود داشته باشد.

خلاصه

وقتی کاربران برای بار دوم سایت شما را بارگذاری می‌کنند، شما قبلاً رای اعتماد داشته‌اید—آنها می‌خواهند برگردند و چیزهای بیشتری را که شما ارائه می‌دهید دریافت کنند. در این مرحله، همیشه فقط به کاهش زمان بارگذاری مربوط نمی‌شود، و شما مجموعه‌ای از گزینه‌ها در دسترس دارید تا مطمئن شوید که مرورگر شما فقط کارهایی را که برای ارائه یک تجربه سریع و به‌روز نیاز دارد، انجام می‌دهد.

حافظه پنهان مفهوم جدیدی در وب نیست، اما شاید به یک پیش‌فرض معقول نیاز داشته باشد – در صورت نیاز به استراتژی‌های ذخیره سازی بهتر در حافظه پنهان استفاده کنید و قویاً انتخاب کنید. با تشکر برای خواندن!

همچنین ببینید

برای راهنمایی کلی در مورد حافظه پنهان HTTP، از درخواست‌های غیرضروری شبکه با کش HTTP جلوگیری کنید .