Збереження змін стилів у кеші. Найкращі практики кешування. Метод альтернативного кешування для.htaccess

Головна / Google Play

Іноді буває необхідно забороняти браузеру кешувати сторінку, оскільки інформація на ній оновлюється щоразу. Це може бути генерація даних відповідно вибраним фільтрам або інший контент, який щоразу створюється по-новому. Одним словом, бувають моменти, коли необхідно заборонити підступну програму кешувати сторінку. Сьогодні ми дізнаємося, як реалізувати це різними способами, з допомогою PHPабо HTML або .htaccess.

Заборона кешування сторінки на HTML

Зробити це можна за допомогою мета тегів. Зараз ми розберемо різні варіанти заборони кешування.

Заборона на кешування браузером та проксі-сервером

Заборона кешування сторінки, лише браузером

Установка кешування на певний часдля браузера

За допомогою коду нижче ми можемо повідомити браузеру, скільки зберігати документ у кеші. Після цього кеш буде оновлено.

Установка кешування на певний час для проксі-сервера

Практично те ж саме, що і в попередньому коді, тільки вказівка ​​стоїть конкретно для проксі-сервера.

Заборонити кешування сторінки за допомогою PHP

Практично, все те саме, що у випадку з HTML, тільки інформацію виводитимемо через header заголовки. Ось як реалізувати абсолютну заборону на кеш:

", date("H:i:s"), ""; ?>

Також можна дозволяти кешувати на певний час. Наприклад, дозволимо кешування лише на 1 годину.

", date("H:i:s"), ""; ?>

Заборонити кешування сторінки за допомогою.htaccess

Для простоти реалізації ідеї, можна все зробити на рівні конфігурацій сервера Apache. Перед цим, нам потрібно переконатися, що необхідні модулі знаходяться в робочому стані. Відкриваємо конфігураційний файл Apache та спостерігаємо наступну картину:

LoadModule expires_module modules/mod_expires.so LoadModule headers_module modules/mod_headers.so ... AddModule mod_expires.c AddModule mod_headers.c

Тепер у файлі.htaccess, що забороняємо кешувати виведені дані. Як відомо, .htaccess файл буде поширюватися на директорію, у якій лежить, і всі субдиректорії.

# Заголовок Cache-Control Header append Cache-Control "no-store, no-cache, must-revalidate"# Заголовок Expires ExpiresActive On ExpiresDefault "now"

Важливо зауважити, що повна заборона кешування підвищує навантаження на сервер. Тому грайтеся з цим обережно! А краще встановіть певний час, на який можна кешувати документи. Наприклад, встановимо кешування на 1 годину:

# Заголовок Cache-Control Header append Cache-Control "public"# Заголовок Expires ExpiresActive On ExpiresDefault "access plus 1 hours"

Висновок

При зміні сайтів ми часто стикаємося з тим, що вміст сторінок, css-файлів і скриптів (.js) кешується браузером і залишається незмінним досить довгий час. Це призводить до того, що для того, щоб внесені зміни відобразились у всіх браузерах, потрібно привчати клієнтів до складних комбінацій F5 або Ctrl+F5. І час від часу стежити, щоб вони натискалися.

Процес досить нудний та незручний. Можна звичайно вийти із ситуації, перейменовуючи щоразу файли, але знову ж таки незручно.

Однак є спосіб, який дозволить залишитися при колишніх іменах, і скидати кешування.css або.js файлів у той момент, коли це буде потрібно нам. І назавжди забути про Ctrl+F5.

Суть полягає в тому, що ми приписуватимемо до наших.css або.js файлів в кінці псевдопараметр, який змінюватимемо час від часу, тим самим скидаючи кеш у браузері.

Таким чином, запис у вихідному коді тепер виглядатиме так:

Де 186485 - довільна комбінація, яка виведе той самий файл, але браузер інтерпретує його як новий завдяки псевдопараметру ?186485

Тепер, щоб щоразу не змінювати всі входження нашого параметра, поставимо його у php-файл, який підключимо до всіх потрібних нам місць:

">

Вміст файлу param.php може бути довільним:

Готово! Тепер при зміні файлу param.phpкешування файлів скидатиметься.

А що у Joomla?

Тут за нас уже все продумали розробники, і нам лише слід дотримуватись прийнятого синтаксису:

JHtml::_("stylesheet", "template.css", array("version" => "auto", "relative" => true)); JHtml::_("script", "template.js", array("version" => "auto", "relative" => true));

Цей код підключить css файл template.css (або template.js для файлу зі скриптами) з папки вашого шаблону. Замість "version" => "auto" можна встановити будь-яке значення, наприклад "version" => "1.1" - на виході цей параметр слідуватиме при підключенні файлу, після знака питання.

Параметр relative => true означає, що система намагатиметься знайти вказаний файл у папці шаблону. Якщо вкажемо relative => false, потрібно буде вказати повний шлях до.css або.js файлу

Багато хто думає, що за промовчанням CSS файли, що підключаються через link або @import - не кешуються. Вимушений вас розчарувати. Саме css, винесені в окремий файл кешуються, причому дуже добре, я б сказав відмінно. Ця інформація достовірно перевірена як на 6 та вище та інших браузерах. Багатьма улюблена кешується такі файли з дикою швидкістю, отримує перше місце за цю справу. До речі, багато в чому саме цьому механізму Opera має у багатьох випадках істотну швидкість порівняно з іншими браузерами. Але відразу обмовлюся, що саме це «супер» кешування в Opera з нею злий жарти при використанні технології AJAX. В той час, як інші при використанні AJAX вносять зміни чики пуки, Opera бере старе. Але це пісня окремої теми.

Кешування CSS

АЛЕ! Бувають у деяких горе проблеми в цьому напрямку. Це пов'язано, як правило, з неправильним налаштованим сервером Apache, який видає не зовсім коректні заголовки. А за допомогою заголовка можна керувати кешуванням файлів. За замовчуванням, звичайно, кеш включений завжди. Але трапляються випадки, коли кешувати файли не потрібно. Для цього вже профі починають танці з бубнами з приводу HTTP заголовків. Але якщо ви повністю читаєте цю статтю, то вам ще дуже далеко до керування заголовками HTTP. Запевняю вас, що найближчим часом ви з таким завданням не зіткнетесь. І все ж, якщо ви цікаві до глибини душі, то коротко розповім як це відбувається.

  1. шле HTTP заголовок на WEB сервер - мовляв чуєш, солодкий перець, дай мені CSS файл, а то у мене є CSS, але останнім часом зміни таке те.
  2. А сервер говорить йому у відповідь, так солоденький, не було з того моменту жодних змін, бери і користуйся сміливо своїм стареньким CSS.
  3. Якщо ж CSS змінився, то браузер тупо оновлює CSS у кеш.

Ну а тепер якщо не втомив, то трохи наукової беліберди від деякого свого роду експерименту.

Відразу скажу нижній текст новачкам у WEB буде слабо зрозумілим. В основному це корисно тим, хто зіткнувся все-таки із завданнями відключення та включення кеш.

Усі експерименти проводились на реальному, платному. У хорошого хостера, який дозволяє змінювати структуру HTTP заголовків, не маючи параною, що його по HTTP заголовку зламають:)

Режими браузерів

Отже, будь-який браузер має 2 режими:

1. Режим за замовчуванням, що повертається заголовок:

Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0

2. Режим із включеним кешуванням, що повертається заголовок:

Cache-Control: private, max-age=10800, pre-check=10800

Далі описую поведінку браузерів

FireFox 3.5 і вище

У першомурежим міцно кешує зовнішні JavaScript файли і навіть не перевіряє їх оновлення, якщо тільки примусово не оновити сторінку. CSS перевіряється запитом із заголовком.

If-Modified-Since: "поточна дата" GMT If-None-Match: "свій код хеш"

CSS завантажується заново, тільки якщо він реально оновився.

У другомурежимі перестає оновлювати сторінку взагалі. Тобто, навіть якщо в базі даних ми змінили контент, що виводиться на сторінку - цього не відображає, навіть якщо примусово оновлювати, тому що відправляє запит:

GET / HTTP/1.1 Host: ххх.com If-Modified-Since: поточна дата GMT

і отримує відповідь:

HTTP/1.1 304 Not Modified

Internet Explorer 8 (IE8)

У першому Internet Explorer відправляє запити If-Modified-Since & If-None-Match і для JavaScript і для css, тобто вантажить JavaScript і CSS тільки якщо вони реально оновилися. Те саме якщо примусово оновити сторінку.

У другомурежимі Internet Explorer також надсилає запити If-Modified-Since & If-None-Match і для JavaScript, і для css. Але при цьому він навіть не намагається завантажити/оновити саму сторінку, тобто навіть не надсилає запит, тобто, ваші js/css оновляться, а шаблон і контент сторінки - ні. Оновлення контенту не допомагає навіть примусове оновлення сторінки.

Opera 10 і старше

У першомуУ режимі Опері, у першому режимі, оновлення js & CSS залежить від того, в яке значення виставлено опцію Check images в налаштуваннях. Якщо опція виставлена ​​у значення Always, то опера надсилає запити з If-Modified-Since & If-None-Match для перевірки оновлення js&css. Якщо виставлено значення, наприклад, 5 годин, то відповідно перевірятиметься раз на 5 годин або за примусовим оновленням сторінки.

У другомурежимі, Опера не перевіряє оновлення js & CSS (не робить GET-запитів), а так само не робить GET запит на саму сторінку, тобто ні оновлення js & css, ні оновлення контенту ми не побачимо, як в іншому та в інших браузерів. А ось із примусовим оновленням у Опери краще. На відміну від IE & FF, Опера явно вимагає вміст сторінки без If-Modified-Since & If-None-Match. Запити на оновлення js & CSS при примусовому поновленні йдуть вже з If-Modified-Since & If-None-Match.

Висновки

  1. Кешування, якщо точно не уявляти собі, як воно працює в різних браузерах і які наслідки - досить небезпечна річ.
  2. Кешування можна включати тільки якщо сторінка оновлюється рідко (тобто, якщо на сайті немає сторінок, які оновлюються в реальному часі) і навіть у цьому випадку обов'язково потрібно ставити обмеження на період обмеження кешування (наприклад, кілька годин або день)
  3. FireFox веде себе, на мій погляд, трохи розумніше за IE, тому що навіть при відключеному кешуванні не перевіряє постійно оновлення JavaScript, що виглядає логічно, адже JavaScript оновлюється дуже рідко.
  4. Опера дозволяє гнучко керувати оновленням зображень, JavaScript та CSS за допомогою налаштування Check images, що є плюс. Також Опера поводиться краще ніж IE & FF при включеному кешуванні і примусовому оновленні, оскільки, нагадаю, Опера у разі повністю оновлює вміст сторінки, а IE & FF - залишать вас у щасливому незнанні.

Успіхів вам і прибуткових сайтів.

  • htaccess кешування зберігає вміст веб-сторінки на локальному комп'ютері, коли користувач відвідує її;
  • Використання кешу браузера – веб-майстер дає вказівки браузерам як слід розглядати ресурси.

Коли браузер відображає веб-сторінку, він повинен завантажити логотип, файл файлу CSS та інші ресурси:

Кеш браузера "запам'ятовує" ресурси, які браузер вже завантажив. Коли відвідувач переходить на іншу сторінку сайту, логотип, файли CSS і т.д. не повинні завантажуватися знову, тому що браузер вже «запам'ятав» їх (зберіг). У цьому полягає причина, чому під час першого відвідування завантаження веб-сторінки займає більше часу, ніж за повторних.

Коли ви використовуєте кешування, файли веб-сторінки будуть збережені у кеші браузера. Сторінки будуть завантажуватись у рази швидше при повторних відвідуваннях. Також буде з іншими сторінками, які використовують лише ресурси.

Як увімкнути кешування в браузері

  • Змініть заголовки запиту ресурсів, щоб використати кешування;
  • Оптимізуйте свою стратегію кешування.

Зміна заголовків запиту

Для більшості людей єдиний спосіб кешування сайту htaccess полягає в тому, щоб додати код у файл .htaccess на веб-сервері.

Файл .htaccess контролює багато важливих параметрів для вашого сайту.

Кешування браузера через файл.htaccess

Наведений нижче код вказує браузеру, що саме кешувати і як довго це запам'ятовувати. Його слід додати на початок файлу .htaccess :

## EXPIRES CACHING ## ExpiresActive On ExpiresByType image/jpg "access 1 year" ExpiresByType image/jpeg "access 1 year" ExpiresByType image/gif "access 1 year" ExpiresByType image/png "access 1 year" ExpiresByType text/css "access 1 month" ExpiresBy html "access 1 month" ExpiresByType application/pdf "access 1 month" ExpiresByType text/x-javascript "access 1 month" ExpiresByType application/x-shockwave-flash "access 1 month" ExpiresByType image/x-icon "access 1 year" ExpiresDefault "access 1 month"## EXPIRES CACHING ##

Збережіть файл .htaccess і оновіть веб-сторінку.

Як встановити час кешування для різних типів файлів

У наведеному вище коді задано проміжки часу. Наприклад, 1 рік (1 рік) або 1 місяць (1 місяць). Вони пов'язані з типами файлів. Наведений вище код встановлює, що файли .jpg (зображення ) слід кешувати протягом року.

Якби ви хотіли змінити це, щоб і JPG зображення кешувалися протягом місяця, то ви просто замінили б «1 рік» на «1 місяць». Вказані вище значення кешування через htaccess є оптимальними для більшості веб-сторінок.

Метод альтернативного кешування для.htaccess

Описаний вище метод називається « Expires«, Він допомагає з кешуванням більшості новачків. Після того, як вам стане простіше працювати з кешування, можете спробувати інший метод кешування Cache-Control, який дає більше можливостей.

Можливо, що метод Expires не спрацює на вашому сервері, у цьому випадку ви, можливо, захочете спробувати використовувати Cache-Control .

Cache-Control

Цей метод дозволяє отримати більше контролю над кешуванням сторінок у браузері, але багато хто вважає, що простіше прописати всі налаштування один раз.

Приклад використання у файлі .htaccess:

# 1 Month for most static assets Header set Cache-Control "max-age=2592000, public"

Наведений вище код визначає заголовок Cache-Control залежно від типу файлу.

Як працює Cache-Control

Розглянемо згаданий вище рядок коду кешування у браузері htaccess :

# 1 Month for most static assets

Цей рядок – просто примітка. Файл .htaccess ігнорує рядки, що починаються із символу # . Ця примітка рекомендується, тому що у вас може бути кілька різних наборів даних як рішення для кешування файлів:

Згаданий вище рядок каже, що, якщо файл буде одним із цих типів, то ми зробимо щось з ним.»

Найважливіше в цьому рядку те, що в ньому перелічені різні типи файлів ( CSS, JS, JPEG, PNGі т.д. ) і що інструкції кешування слід застосовувати до цих типів файлів. Наприклад, якщо ви не бажаєте, щоб JPG файли кешувалися протягом зазначеного періоду часу, можете видалити « JPG«. Якщо ви хочете додати HTML, то потрібно в цьому рядку вказати HTML«:

Header set Cache-Control "max-age=2592000, public"

У зазначеному вище рядку встановлені фактичні заголовки та значення:

  • Частина « Header set Cache-Control» - Встановлює заголовок;
  • Змінна « max-age=2592000» - Вказує, скільки часу займе процес кешування (в секундах). У цьому випадку ми здійснюємо кешування протягом одного місяця (2592000) секунд;
  • Частина « public» повідомляє про те, що це є загальнодоступним.

Цей рядок кешування через htaccess закриває оператор та закінчує блок коду.

Загальна проблема кешування

Якщо ви складаєте список зображень, які будуть кешуватися протягом року і більше, пам'ятайте, що якщо ви вносите зміни до своїх сторінок, вони можуть бути не видно всім користувачам. Так як користувачі звернуться до файлів, що кешуються, а не до існуючих. Якщо є файл, який ви періодично редагуєте ( наприклад - файл CSS), то можна подолати проблему кешу за допомогою цифрового відбитка URL.

Цифровий відбиток URL

Отримання нового файлового ресурсу, що не кешується, можливе за наявності унікального імені. Наприклад, якщо файл CSS названий "main.css", то замість цього ми могли б назвати його "main_1.css". Наступного разу, коли ми змінимо його ім'я, ми можемо назвати файл "main_2.css". Це корисно для файлів, які періодично змінюються.

Правильно налаштоване кешування дає величезний виграш у продуктивності, заощаджує трафік і зменшує витрати на сервер, проте на багатьох сайтах кешування реалізовано невдало, що створює стан гонки, що призводить до розсинхронізації взаємопов'язаних ресурсів.

Переважна більшість найкращих практик кешування відноситься до одного з двох патернів:

Паттерн №1: незмінний контент та довгий max-age кешу

Cache-Control: max-age=31536000
  • Вміст URL не змінюється, отже…
  • Браузер або CDN можуть без проблем закешувати ресурс на рік
  • Закешований контент, який молодший за заданий max-age може використовуватися без консультації з сервером

Сторінка : Гей, мені потрібні "/script-v1.js", "/styles-v1.css" та "/cats-v1.jpg" 10:24

Кеш : У мене порожньо, як щодо тебе, Сервере? 10:24

Сервер : ОК, ось вони. До речі, Кеш, їх варто використати протягом року, не більше. 10:25

Кеш : Спс! 10:25

Сторінка : Ура! 10:25

Наступний день

Сторінка : Гей, мені потрібні "/script- v2.js" , "/styles- v2.css" та "/cats-v1.jpg" 08:14

Кеш : Картинка з котиками є, решти немає. Сервер? 08:14

Сервер : Легко – ось нові CSS & JS. Ще раз, Кеш: їхній термін придатності не більше року. 08:15

Кеш : Супер! 08:15

Сторінка : Дякую! 08:15

Кеш : Хм, я не користувався "/script-v1.js" & "/styles-v1.css" досить довго. Настав час їх видаляти. 12:32

Використовуючи цей патерн, ви ніколи не змінюєте контент певного URL, ви змінюєте сам URL:

У кожному URL є щось, що змінюється одночасно із контентом. Це може бути номер версії, модифікована дата або хеш контенту (цей варіант я вибрав для свого блогу).

У більшості серверних фреймворків є інструменти, що дозволяють легко робити подібні речі (у Django я використовую Manifest Static Files Storage); є також зовсім невеликі бібліотеки в Node.js, які вирішують ті самі завдання, наприклад, gulp-rev.

Однак цей патерн не підходить для речей на кшталт статей та записів у блогах. Їх URL не можна версіонувати, а вміст може змінитися. Серйозно, у мене часто бувають граматичні та пунктуаційні помилки, тому потрібна можливість швидкого оновлення вмісту.

Паттерн №2: контент, що змінюється, завжди проходить ревалідацію на сервері

Cache-Control: no-cache
  • Вміст URL зміниться, отже…
  • Будь-яка локальна закешована версія не може використовуватись без вказівки сервера.

Сторінка : Гей, мені потрібний вміст "/about/" та "/sw.js" 11:32

Кеш : Нічим не можу допомогти. Сервер? 11:32

Сервер : Є такі. Кеш, тримай їх при собі, але перед використанням питай у мене. 11:33

Кеш : Так точно! 11:33

Сторінка : Спс! 11:33

На наступний день

Сторінка : Гей, мені знову потрібний вміст "/about/" та "/sw.js" 09:46

Кеш : Хвилинку. Сервере, з моїми копіями все гаразд? Копія /about/ лежить з понеділка, а /sw.js вчорашня. 09:46

Сервер : "/sw.js" не змінювалася… 09:47

Кеш : Круто. Сторінка, тримай "/sw.js" . 09:47

Сервер : …але "/about/" у мене нової версії. Кеш, тримай її, але як і минулого разу, не забудь спочатку спитати мене. 09:47

Кеш : Зрозумів! 09:47

Сторінка : Чудово! 09:47

Примітка: no-cache не означає "не кешувати", тобто "перевіряти" (або ревалідувати) закешований ресурс у сервера. А не кешувати зовсім браузеру наказує no-store. Також і must-revalidate означає не обов'язкову ревалідацію, а те, що закешований ресурс використовується тільки якщо він молодший, ніж заданий max-age , і тільки в іншому випадку він ревалідується. Ось так все запущено із ключовими словами для кешування.

У цьому патерні ми можемо додати до відповіді ETag (ідентифікатор версії на ваш вибір) або заголовок Last-Modified. При наступному запиті вмісту з боку клієнта виводиться If-None-Match або If-Modified-Since відповідно, дозволяючи серверу сказати "Використовуй те, що у тебе є, твій кеш актуальний", тобто повернути HTTP 304.

Якщо надсилання ETag / Last-Modified неможливе, сервер завжди надсилає вміст повністю.

Цей патерн завжди вимагає звернень до мережі, тому він не такий гарний, як перший патерн, який може обходитися без мережних запитів.

Це не рідкість, коли у нас немає інфраструктури для першого патерну, але точно також можуть виникнути проблеми з мережними запитами в патерні 2. У результаті використовується проміжний варіант: короткий max-age і контент, що змінюється. Це поганий компроміс.

Використання max-age із змінним контентом це, як правило, неправильний вибір

І, на жаль, він поширений, як приклад можна навести Github pages.

Уявіть:

  • /article/
  • /styles.css
  • /script.js

Із серверним заголовком:

Cache-Control: must-revalidate, max-age=600

  • Вміст URL змінюється
  • Якщо в браузері є кешована версія свіжіша за 10 хвилин, вона використовується без консультації з сервером
  • Якщо такого кешу немає, використовується запит до мережі, по можливості з If-Modified-Since або If-None-Match

Сторінка : Гей, мені потрібні "/article/", "/script.js" та "/styles.css" 10:21

Кеш : У мене нічого нема, як у тебе, Сервер? 10:21

Сервер : Без проблем, ось вони. Але запам'ятай, Кеш: їх можна використовувати протягом найближчих десяти хвилин. 10:22

Кеш : Є! 10:22

Сторінка : Спс! 10:22

Сторінка : Гей, мені знову потрібні "/article/", "/script.js" та "/styles.css" 10:28

Кеш : Упс, я вибачаюсь, але я втратив "/styles.css", але все інше у мене є, тримай. Сервер, можеш підігнати мені "/styles.css"? 10:28

Сервер : Легко, він уже змінився з того часу, як ти минулого разу забирав його. Найближчі 10 хвилин можеш сміливо використовувати його. 10:29

Кеш : Без проблем. 10:29

Сторінка : Дякую! Але, здається, щось пішло не так! Все зламалося! Що взагалі відбувається? 10:29

Цей патерн має право на життя при тестуванні, але ламає все у реальному проекті та його дуже складно відстежувати. У прикладі вище, сервер оновив HTML, CSS та JS, але виведено сторінку зі старими HTML та JS з кешу, до яких додано оновлений CSS із сервера. Розбіжність версій все псує.

Часто при внесенні значних змін до HTML ми змінюємо і CSS, для правильного відображення нової структури, і JavaScript, щоб і він не відставав від контенту та стилів. Усі ці ресурси незалежні, але заголовки кешування що неспроможні висловити це. У результаті користувачів може бути остання версія одного/двох ресурсів і стара версія інших.

max-age задається щодо часу відповіді, тому якщо всі ресурси передаються як частина однієї адреси, їхній термін закінчиться одночасно, але й тут зберігається невеликий шанс розсинхронізації. Якщо у вас є сторінки, що не містять JavaScript або інші стилі, терміни придатності їх кешу будуть розсинхронізовані. І гірше того, браузер постійно витягує вміст із кешу, не знаючи, що HTML, CSS, & JS взаємозалежні, тому він з радістю може витягнути щось одне зі списку та забути про все інше. Враховуючи всі ці фактори разом, ви повинні зрозуміти, що ймовірність появи версій, що не збігаються, досить велика.

Для користувача результатом може бути зламана розкладка сторінки чи інші проблеми. Від невеликих глюків до непридатного контенту.

На щастя, користувачі мають запасний вихід.

Оновлення сторінки іноді рятує

Якщо сторінку завантажено шляхом оновлення, браузери завжди проводять серверну ревалідацію, ігноруючи max-age. Тому, якщо у користувача щось зламалося внаслідок max-age, просте оновлення сторінки може все виправити. Але, зрозуміло, після того, як ложки знайдуться, осад все одно залишиться і ставлення до вашого сайту буде іншим.

Сервіс-воркер може продовжити життя цих багів

Наприклад, у вас є такий сервіс-воркер:

Const version = "2"; self.addEventListener("install", event => ( event.waitUntil(caches.open(`static-$(version)`)) .then(cache => cache.addAll([ "/styles.css", "/script .js "]))); )); self.addEventListener("activate", event => ( // …delete old caches… )); self.addEventListener("fetch", event => ( event.respondWith(caches.match(event.request) .then(response => response || fetch(event.request))); ));

Цей сервіс-воркер:

  • кешує скрипт та стилі
  • використовує кеш при збігу, інакше звертається до мережі

Якщо ми змінюємо CSS/JS, ми також збільшуємо номер version, що ініціює оновлення. Однак, оскільки addAll звертається спочатку до кешу, ми можемо потрапити у стан гонки через max-age та невідповідні версії CSS & JS.

Після того, як вони закешовані, у нас будуть несумісні CSS & JS до наступного оновлення сервіс-воркера - і це якщо ми знову не потрапимо при оновленні стан гонки.

Ви можете пропустити кешування у сервіс-воркері:

Self.addEventListener("install", event => ( event.waitUntil(caches.open(`static-$(version)`) ).then(cache => cache.addAll([ new Request("/styles.css", (cache: "no-cache")), New Request ("/script.js", (cache: "no-cache"))))));));

На жаль, опції для кешування не підтримуються в Chrome/Opera і тільки-но додані в нічну збірку Firefox , але ви можете зробити це самостійно:

Self.addEventListener("install", event => ( event.waitUntil(caches.open(`static-$(version)`)) .then(cache => Promise.all([ "/styles.css", "/script .js" ].map(url => ( // cache-bust using a random query string return fetch(`$(url)?$(Math.random())`)).then(response => ( // fail on 404, 500 etc if (!response.ok) throw Error("Not ok");return cache.put(url, response);

У цьому прикладі я скидаю кеш за допомогою випадкового числа, але ви можете піти далі і додавати хеш контенту при складанні (це схоже на те, що робить sw-precache). Це свого роду реалізація першого патерну за допомогою JavaScript, але працює тільки з сервіс-воркером, а не браузерами та CDN.

Сервіс-воркери та HTTP-кеш чудово працюють разом, не змушуйте їх воювати!

Як бачите, ви можете обійти помилки з кешуванням у вашому сервіс-воркері, але правильніше вирішити корінь проблеми. Правильне налаштування кешування не тільки полегшує роботу сервіс-воркера, але й допомагає браузерам, які не підтримують сервіс-воркери (Safari, IE/Edge), а також дозволяє витягти максимум з вашої CDN.

Правильні заголовки кешування можуть значно спростити оновлення сервіс-воркера.

Const version = "23"; self.addEventListener("install", event => ( event.waitUntil(caches.open(`static-$(version)`)) .then(cache => cache.addAll([ "/", "/script-f93bca2c). js", "/styles-a837cb1e.css", "/cats-0e9a2ef4.jpg" ]))); ));

Тут я закешував кореневу сторінку з патерном №2 (серверна ревалідація) і решту ресурсів з патерном №1 (незмінний контент). Кожне оновлення сервіс-воркеру буде викликати запит до кореневої сторінки, а решта ресурсів завантажуватиметься тільки, якщо їх URL змінився. Це добре тим, що зберігає трафік і покращує продуктивність, незалежно від того, чи ви оновлюєтеся з попередньої або дуже старої версії.

Тут є значна перевага над нативною реалізацією, коли цілий бінарник завантажується навіть при невеликій зміні або викликає комплексне порівняння двійкових файлів. Так ми можемо оновити велику веб-додаток за порівняно невеликого завантаження.

Сервіс-воркери працюють краще як поліпшення, а не тимчасового милиця, тому працюйте з кешем замість того, щоб воювати з ним.

При акуратному використанні max-age і контент, що змінюється, можуть бути дуже хороші

max-age дуже часто буває неправильним вибором для контенту, що змінюється, але не завжди. Наприклад, оригінал статті max-age складає три хвилини. Стан гонки не є проблемою, так як на сторінці немає залежностей, що використовують однаковий патерн кешування (CSS, JS & зображення використовують патерн №1 - незмінний контент), все інше цей патерн не використовує.

Цей патерн означає, що я спокійно пишу популярну статтю, а мій CDN (Cloudflare) може зняти навантаження із сервера, якщо, звичайно, я готовий почекати три хвилини, доки оновлена ​​стаття стане доступною для користувачів.

Цей патерн слід використовувати без фанатизму. Якщо я додав новий розділ у статтю і поставив на нього посилання з іншої статті, я створив залежність, яку треба дозволяти. Користувач може клацнути на посилання і отримати копію статті без розділу. Якщо я хочу уникнути цього, я маю оновити статтю, видалити кешований варіант статті з Cloudflare, почекати три хвилини і тільки після цього додавати посилання в іншу статтю. Так, цей патерн потребує обережності.

При правильному використанні кешування дає значне покращення продуктивності та економію трафіку. Передавайте незмінний контент, якщо ви можете легко змінити URL-адресу, або використовуйте серверну ревалідацію. Змішуйте max-age і змінний контент, якщо ви досить сміливі і впевнені, що ваш контент не має залежностей, які можуть розсинхронізуватися.

© 2022 androidas.ru - Все про Android