Кэширование интернет-магазина: настройка страничного, объектного и браузерного кэша

В оптимизации скорости интернет-магазина кэш даёт лучший результат на вложенный рубль — настроив только страничный кэш, вы снизите LCP с 4 секунд до менее чем 1 секунды. Три уровня кэша отвечают за своё: страничный — за HTML, объектный — за результаты запросов к базе...

三层缓存:每层管一段,不能混Three cache layers: each owns a segment, don’t mix 页面缓存管HTML · 对象缓存管数据库查询 · 浏览器缓存管静态资源Page=HTML · Object=DB queries · Browser=static assets ① 页面缓存 Page Cache —— 把整个HTML存起来,下次直接返回① Page Cache — store full HTML, return it next time 缓存时间:静态页面1小时至1天 · 表单页/wp-admin永不缓存TTL: static pages 1h-1d · forms/wp-admin never cached ② 对象缓存 Object Cache —— 把数据库查询结果存到Redis/Memcached② Object Cache — store DB query results in Redis/Memcached TTL:对象缓存12小时至7天 · 内容更新时主动失效TTL: 12h-7d · invalidate on content update ③ 浏览器缓存 Browser Cache —— 用Cache-Control头让访客本地存静态资源③ Browser Cache — use Cache-Control header to cache locally TTL:图片30天至1年 · CSS/JS 7天 · 文件名带hash自动失效TTL: images 30d-1y · CSS/JS 7d · hash-based invalidation 优先级:页面缓存 > 对象缓存 > 浏览器缓存(先配最值钱的)Priority: page > object > browser (do the highest-value first) 只配页面缓存就能让LCP从4秒降到1秒以内,对象缓存是加分项Page cache alone cuts LCP from 4s to under 1s; object cache is bonus 反直觉:缓存不是越多越好,表单页缓存了会泄露别人的提交Counter-intuitive: caching forms leaks other users’ submissions 询盘表单、wp-admin、购物车、登录后页面必须no-cacheInquiry forms, wp-admin, cart, logged-in pages must be no-cache 浏览器缓存不是越长越好:用文件hash解决”改了看不到”Browser TTL isn’t longer=better: use file hashes for updates
Три уровня кэша интернет-магазина: за что отвечают страничный, объектный и браузерный кэш и как настроить TTL

Кэширование интернет-магазина: настройка страничного, объектного и браузерного кэша

Сначала вывод: В оптимизации скорости интернет-магазина кэш даёт лучший результат на вложенный рубль — настроив только страничный кэш, вы снизите LCP с 4 секунд до менее чем 1 секунды. Три уровня кэша отвечают за своё: страничный — за HTML, объектный — за результаты запросов к базе, браузерный — за статику. Рекомендации по TTL: страничный кэш статики — от 1 часа до 1 дня, объектный — от 12 часов до 7 дней, браузерный кэш изображений — от 30 дней до 1 года. Контринтуитивный вывод: кэша не бывает слишком много — формы заявок, wp-admin и страницы после входа обязательно должны быть no-cache, иначе пользователи увидят данные, отправленные другими. Порядок настройки: сначала страничный кэш, затем объектный, в конце браузерный — не наоборот.

I. За что отвечает каждый из трёх уровней кэша

Кэш интернет-магазина делится на три уровня, каждый решает свою задачу — не путайте их. Страничный кэш сохраняет готовый HTML в статический файл: при следующем заходе на тот же URL файл отдаётся сразу, без запуска PHP и базы данных. Объектный кэш хранит результаты запросов к базе в памяти (например, Redis или Memcached): следующий такой же запрос берётся из памяти, без обращения к MySQL. Браузерный кэш через заголовки HTTP-ответа говорит браузеру посетителя: «этот файл хранится у тебя локально» — при следующем визите он читается прямо с диска.

Выгода от трёх уровней сильно различается. Страничный кэш даёт больше всего — он полностью пропускает выполнение PHP и запросы к базе, и LCP падает с более чем 4 секунд до менее чем 1 секунды. Объектный кэш даёт средний результат — он экономит только время запросов к базе; если страничный кэш уже сработал, объектный вообще не задействуется. Браузерный кэш работает для вернувшихся посетителей — при первом визите файлы всё равно скачиваются, со второго читаются локально, и скорость повторного захода заметно растёт.

Уровень кэша Что хранит Где хранит Выигрыш в производительности Типичные инструменты
Кэш страниц Полная HTML-страница Диск или память сервера Максимальный, LCP падает на 60–80% WP Rocket、LiteSpeed Cache
Объектный кэш Результаты запросов к базе, объекты PHP Redis или Memcached Средний, время запросов к БД падает на 50% Redis、Memcached
Браузерный кэш CSS/JS/изображения Локально в браузере посетителя Для вернувшихся посетителей, повторный визит быстрее Заголовок ответа Cache-Control
Кэш CDN Статика + часть HTML Глобальные пограничные узлы Задержка между регионами падает более чем на 50% Cloudflare、Akamai

Многие сразу начинают возиться с Redis и Memcached, хотя для B2B-сайта правильно настроенное кэширование страниц уже решает 80% проблем с производительностью. Объектное кэширование — это бонус, к нему стоит переходить, когда месячная посещаемость превышает 50 000 уникальных посетителей или запросы к базе данных замедляются. О том, как CDN связан с трёхуровневым кэшированием, читайте в Глобальное ускорение CDN и выбор узлов а о том, какие показатели производительности считаются нормой, — в Оптимизация Core Web Vitals.

II. Кэширование страниц: как хранить HTML без ошибок

Кэширование страниц — самый ценный уровень и самый простой для ошибок. Типичные симптомы неправильной настройки: после отправки заявки посетитель видит данные предыдущего посетителя; или после входа пользователь видит страницу в неавторизованном состоянии. Причина в том, что кэш страниц сохраняет HTML с динамическим содержимым как статический файл.

Правильный подход — разделить страницы на две категории по URL и статусу пользователя: публичные статические страницы (главная, страницы товаров, статьи блога) кэшируются; динамические страницы (страница после отправки формы заявки, админка wp-admin, страницы после входа, корзина) должны обходить кэш. Плагины кэширования WordPress (WP Rocket, LiteSpeed Cache) поддерживают правила «исключить URL» и «пропускать кэш по Cookie».

Тип страницы Кэшировать Время кэширования Правила исключения
Главная, список товаров Кэш от 1 до 4 часов Исключить авторизованных
Страница блога Кэш от 12 часов до 1 дня Обновлять вручную при изменении контента
Страница формы заявки Не кэшировать Не задано Всегда запрашивать с сервера
Страница успешной отправки формы Не кэшировать Не задано 带session cookie
Админка wp-admin Не кэшировать Не задано Исключить по cookie администратора
Страница результатов поиска Короткий кэш или без кэша 5 минут Не кэшировать разные поисковые запросы

Пример: страница товара на сайте промышленного оборудования, URL — /products/cnc-machine-a/, содержимое меняется раз в несколько месяцев, её вполне можно кэшировать на 1 день. Но страница «Заявка отправлена» с URL /inquiry-thank-you/ должна показывать каждому посетителю подтверждение именно его отправки, поэтому её кэшировать нельзя. В WP Rocket добавьте /inquiry-thank-you/ и /wp-admin/* в список Never Cache URL(s).

Сброс кэша тоже важен для кэширования страниц. Изменили статью в блоге — как сразу обновить её на сайте? Два способа: вручную очистить весь кэш при публикации или обновить только эту страницу по URL. WP Rocket автоматически сбрасывает связанный кэш при обновлении записи, но для многих кастомных страниц это не срабатывает — нужно взять за привычку нажимать Purge после публикации. В crater на сайтах для выхода на зарубежные рынки сброс кэша привязан к процессу публикации, подробнее в Технологический стек crater и четыре собственных плагина.

III. Объектное кэширование: как переиспользовать результаты запросов к базе данных

Когда срабатывает кэш страниц, PHP и база данных не запускаются, и объектный кэш тоже не нужен. Но если кэш страниц промахнулся — например, вы только что опубликовали новую статью или открыли динамическую страницу, которую не стоит кэшировать, — PHP идёт в базу данных. В среднем страница WordPress делает от 12 до 20 запросов к базе, каждый запрос упирается в дисковый ввод-вывод, и накопленные медленные запросы легко растягивают загрузку страницы больше чем на секунду.

Объектный кэш хранит результаты этих запросов в Redis или Memcached, и при следующем таком же запросе они читаются прямо из памяти. Redis ставится на один сервер, WordPress подключается через плагин Redis Object Cache, код менять не нужно. При правильной настройке время запросов к базе падает больше чем на 50%, а отклик при промахе кэша страниц — с 1,5 секунды до менее чем 0,5 секунды.

Показатель Без объектного кэша С объектным кэшем Redis Прирост
Запросов к базе на страницу 12–20 на страницу 2–5 на страницу Сокращение на 70–80%
Время одного запроса 5–20 мс (дисковый ввод-вывод) 0,1–1 мс (память) В 10–50 раз быстрее
Отклик при промахе кэша страниц 1–1,5 секунды 0,3–0,5 секунды Снижение больше чем на 50%
Загрузка CPU MySQL Больше 80% в пик 30–40% в пик Снижение больше чем вдвое

Объектный кэш нужен не всем. Для B2B-сайта с месячной аудиторией до 10 000 уникальных посетителей нагрузка на базу небольшая, кэш страниц уже держит 95% запросов, и выгода от Redis незаметна. Когда его стоит ставить? Два сигнала: первый — в логе медленных запросов MySQL больше 100 запросов в день длиннее секунды; второй — после сохранения статьи в админке изменения на сайте появляются только через несколько минут (объектный кэш не сбрасывается правильно). О медленных запросах и оптимизации индексов читайте в статье Медленные запросы и оптимизация индексов в базе данных интернет-магазина.

Четыре. Кэш браузера: как настроить заголовки кэширования статических ресурсов

Кэш браузера — самый простой в настройке из трёх уровней. Он не затрагивает серверные программы: достаточно добавить несколько строк заголовков в веб-сервере (Nginx или Apache). Принцип такой: отдавая CSS, JS или картинку, сервер добавляет в HTTP-заголовок Cache-Control: max-age=2592000 и говорит браузеру «храни этот файл у себя 30 дней» — в течение 30 дней повторные обращения к серверу не идут.

Но здесь есть классическое противоречие: чем дольше кэш браузера, тем быстрее открывается сайт, но если вы изменили CSS или JS, у пользователя остаётся старая версия и страница выглядит неправильно. Решение не в том, чтобы сократить срок кэширования, а в том, чтобы добавить к имени файла версию или хэш — например, style.css?v=2 или style.abc123.css. Содержимое файла изменилось — изменился URL, и браузер скачивает файл заново.

Тип ресурса Рекомендации по Cache-Control max-age Стратегия обновления
Изображения (jpg/png/webp) public, max-age=31536000 1 год Хэш в имени файла: меняете картинку — меняете имя
Файлы шрифтов public, max-age=31536000 1 год Шрифты не меняются — трогать не нужно
Таблицы стилей CSS public, max-age=604800 7 дней Версия в имени файла: ?ver=2
JavaScript public, max-age=604800 7 дней Версия в имени файла: ?ver=2
HTML-страницы no-cache, must-revalidate Не кэшировать Проверка на источнике при каждом запросе
favicon.ico public, max-age=604800 7 дней Меняется редко

Контринтуитивный вывод: многие боятся, что при долгом кэшировании пользователи не увидят изменений, и ставят max-age в 1 час для всех ресурсов. В итоге каждый посетитель при каждом заходе заново скачивает весь CSS и JS, и первый экран загружается медленнее. Правильно — смело ставить долгий срок (изображения — 1 год, CSS/JS — 7 дней), а обновления решать через хэш файла или номер версии. Функция wp_enqueue_script в WordPress сама добавляет номер версии, и при обновлении темы или плагина он меняется автоматически — вручную следить не нужно.

Об оптимизации изображений и управлении медиафайлами читайте в разделе Управление медиафайлами и сжатие изображений. В многоязычных сайтах кэширование статических ресурсов требует учёта взаимодействия hreflang и кэша CDN, см.Hreflang для мультиязычных сайтов.

Пять. Стратегии инвалидации кэша и типичные конфликты

После настройки кэша главная проблема — «как заставить кэш устареть, когда это нужно». Если кэш не сбрасывается вовремя, пользователи видят старое содержимое; если сбрасывается слишком легко, выгода от производительности пропадает. В независимых интернет-магазинах есть четыре типичные ситуации инвалидации кэша: публикация новой статьи, обновление информации о товаре, изменение CSS/JS, отправка формы запроса. Для каждой ситуации своя стратегия инвалидации.

Ситуация Область инвалидации Способ инвалидации На что обратить внимание
Публикация новой статьи в блоге Главная + список статей + отдельная статья WP Rocket обновляет автоматически Страницы категорий и тегов тоже нужно обновлять
Обновление цены товара Страница товара + страница списка Вручную Purge нужного URL Не делайте Purge всего — это бьёт по производительности
Изменение CSS/JS Соответствующий статический файл Смена номера версии вступает в силу автоматически Не меняйте max-age, меняйте имя файла
Отправка формы запроса Страница формы не кэшируется никогда Правило исключения по URL Страница успешной отправки тоже не кэшируется
Полный редизайн сайта Весь кэш Purge All одной кнопкой Делайте в часы низкой нагрузки
Обновление плагина/темы Весь кэш Автоматический или ручной Purge Перед обновлением сделайте резервную копию

Типичных конфликтов два. Первый — установлены два плагина кэширования (например, одновременно WP Rocket и LiteSpeed Cache): оба правят .htaccess и буфер вывода, в результате страница белая или стили ломаются. Правило: на всём сайте только один плагин кэширования. Второй — конфликт кэша страниц со статусом входа: пользователь вошёл в админку, а на фронтенде всё ещё кэшированная страница для неавторизованных, и навигация отображается неправильно. Решение — плагин кэширования распознаёт cookie входа и автоматически пропускает кэш.

После запуска стратегии кэширования нужно постоянно следить за ней: раз в месяц проверять долю попаданий в кэш и LCP. Резкое падение доли попаданий обычно означает, что кто-то изменил структуру URL или добавил ссылки со случайными параметрами. Список для мониторинга и оповещений см. в Мониторинг сайта и оповещения, о повседневном обслуживании см. в Шесть задач на месяц в период обслуживания сайта. Учения по резервному копированию и восстановлению тоже нужно проводить после изменения настроек кэша, см.Бэкап и восстановление сайта.

FAQ: частые вопросы

Обязательно ли ставить плагин кэширования на независимый сайт WordPress?
Для сайтов с месячным трафиком от 10 000 UV плагин кэширования обязателен. Одна только настройка кэша страниц снижает LCP с более чем 4 секунд до менее чем 1 секунды — это оптимизация с лучшим соотношением затрат и результата. Рекомендую WP Rocket или LiteSpeed Cache, выберите один, не устанавливайте оба сразу. Для небольших сайтов с трафиком до 1000 UV в месяц на shared-хостинге PHP и так работает быстро, можно обойтись без плагина кэширования, но и с ним хуже не будет.
Можно ли кэшировать страницу с формой заявки?
Категорически нет. Страницу формы и страницу успешной отправки обязательно нужно настроить как no-cache. Если их кэшировать, следующий посетитель откроет форму и увидит данные, которые ввёл предыдущий, а отправленные данные перемешаются. В WP Rocket добавьте /inquiry*, /thank-you*, /wp-admin/* в список Never Cache URL(s). Также убедитесь, что плагин кэширования распознаёт cookie авторизации и автоматически пропускает кэширование.
Когда нужно подключать объектный кэш Redis?
Когда появились два сигнала: во-первых, в логе медленных запросов MySQL больше 100 запросов в день длительностью более 1 секунды; во-вторых, после сохранения статьи в админке изменения на сайте появляются только через несколько минут. Для B2B-сайтов с трафиком до 10 000 UV в месяц нагрузка на базу данных небольшая, кэш страниц уже держит 95% запросов, и выгода от Redis незаметна. Подключайте Redis с плагином Redis Object Cache, когда трафик превышает 50 000 UV в месяц или база данных становится узким местом.
На какой срок ставить кэширование в браузере?
Для изображений и шрифтов — 1 год (max-age=31536000), для CSS и JS — 7 дней (max-age=604800), HTML не кэшировать. Не сокращайте срок из страха, что пользователи не увидят изменений — тогда каждый посетитель будет заново скачивать файлы, и первый экран станет только медленнее. Решается это добавлением версии или хэша к имени файла, например style.css?v=2: содержимое изменилось — URL изменился, и браузер скачивает файл заново.
Что делать, если после изменения контента пользователи видят старую версию?
Есть два случая. Если это кэш CDN, зайдите в панель CDN и вручную очистите (Purge) нужный URL или всё сразу. Если это серверный кэш страниц, WP Rocket и LiteSpeed Cache автоматически обновляют связанный кэш при обновлении статьи, но для кастомных страниц и страниц категорий может потребоваться ручной Purge. Если это кэш браузера, значит, имя файла не изменилось — в следующий раз добавьте версию к статическим файлам. Не сокращайте max-age, чтобы решить эту проблему, — это как рубить сук, на котором сидишь.
Конфликтуют ли кэш страниц и кэш CDN?
Не конфликтуют, они работают как звенья одной цепочки. Кэш CDN отвечает за участок от пограничного узла до пользователя, серверный кэш страниц — за участок до исходного сервера. Правильная схема: HTML генерируется серверным кэшем страниц, CDN для HTML ставит no-cache с коротким TTL или не кэширует его вовсе, а кэширует только изображения, CSS и JS. Если CDN тоже начнёт кэшировать HTML и это наложится на серверный кэш страниц, резко вырастет вероятность того, что после отправки формы пользователь увидит старый контент.

В заключение

С кэшированием новички чаще всего бросаются в две крайности: либо вообще ничего не настраивают, и каждая страница каждый раз дёргает PHP и базу данных — первый экран грузится больше 4 секунд; либо настраивают слишком агрессивно, кэшируют даже страницы с формами, и пользователь видит чужие отправленные данные. Правильный подход — разделить по уровням: статические страницы кэшируем смело, динамические — категорически нет, а статику отдаём с длинным кэшем и версионированием.

Три шага на практике. Первый: ставим плагин кэширования страниц (WP Rocket или LiteSpeed Cache — на выбор) и исключаем страницы с формами и wp-admin. Второй: настраиваем в Nginx заголовок Cache-Control — картинки на год, CSS/JS на 7 дней, HTML не кэшируем. Третий: когда месячная посещаемость перевалит за 50 000, подключаем объектный кэш Redis. После этих трёх шагов LCP обычно укладывается в секунду, и никаких аварий с перемешанным содержимым кэша не будет.

Запомните главное: кэш — это рычаг производительности вашего сайта. Кэш страниц экономит 80% времени, объектный кэш разгружает базу данных, кэш браузера ускоряет повторные визиты. У каждого уровня своя задача — и следите, чтобы страницы с формами не попадали в кэш.

crater
crater Эксперт Crater

Официальный аккаунт организации · crater Crater

环形山 (Crater) — компания, которая помогает выходить на зарубежные рынки: разработка сайтов на WordPress, Google SEO и комплексный рост в GEO. Мы работаем с умными устройствами, промышленным оборудованием, SaaS и новой энергетикой.

Возможности продуктаБелая книга по методологииОтраслевые отчёты
965篇分享
78статей в базе знаний