Руководство ThemeHills для владельцев магазинов на CS-Cart.
Тема отвечает лишь за половину того, что видит посетитель. Вторая половина зависит от того, как настроены магазин и сервер, и эту половину обычно оставляют по умолчанию. Всё, что описано ниже, мы применили на своём демо-сервере, где на скромном железе живёт много установок CS-Cart, и измерили результат до и после.
Часть 1 вы делаете сами в админке. Часть 2 требует доступа к серверу, это задача для хостинга или системного администратора. Часть 3 о том, как проверить, что всё это дало эффект.
Часть 1. В админке магазина
1.1 Переведите картинки в WebP
Настройки → Миниатюры → Формат миниатюр: WEBP.
WebP весит заметно меньше JPEG и PNG при том же качестве, и одна эта настройка применяет выигрыш сразу ко всем миниатюрам магазина.
Первая загрузка страницы после переключения будет медленной: все превью пересоздаются на лету. Дальше всё снова быстро.
Перед переключением проверьте цвет фона миниатюр. В тех же настройках есть поле цвета фона. Если оно заполнено, каждая прозрачная картинка при создании превью получит эту заливку, и баннеры с прозрачным фоном превратятся в сплошные прямоугольники. Для прозрачности поле должно быть пустым.
Это легко пропустить, потому что поломка проявляется только после включения конвертации: до неё такие картинки отдаются оригиналами и через генератор превью вообще не проходят. Мы наступили на это на собственной демке.
1.2 Помните, что баннеры не миниатюры
Настройка конвертации касается только миниатюр. Баннеры, логотип и любые другие изображения, которые выводятся в исходном размере, мимо генератора превью не проходят, и настройка их не затрагивает.
Либо загружайте такие картинки уже сконвертированными, либо попросите администратора настроить подмену на стороне сервера (часть 2). На нашей демке баннеры дали больший выигрыш, чем настройка миниатюр, просто потому, что это самые крупные картинки на странице. Стоит сделать и то, и другое.
Никогда не переименовывайте файлы картинок в базе ради смены формата. Соблазн понятный: сконвертировал файлы, прописал новые пути. Но тогда формат становится частью ваших данных, и любое изменение настроек начинает с ним конфликтовать. При включённой конвертации магазин возьмёт уже сконвертированный файл как исходник и сожмёт его повторно, с лишней потерей качества и именами вида
image.png.webp.webp.Держите в базе оригинальные пути, а формат решайте в момент отдачи: либо настройкой магазина, либо на веб-сервере. Тогда ничего не ломается и всё откатывается.
1.3 Загружайте исходники разумного размера
Фотография шириной 4000 пикселей под плитку товара в 300 пикселей это впустую потраченный трафик на каждой карточке, а карточек на странице категории много. Уменьшайте перед загрузкой.
1.4 Дайте первому баннеру приоритет загрузки
Если главная открывается баннерной каруселью, первый слайд почти всегда самый крупный элемент на экране, и инструменты проверки скорости меряют именно то, как быстро он появляется.
Наши темы умеют сказать браузеру, чтобы он загрузил этот слайд раньше остального. В настройках баннерного блока включите «Загружать первый слайд с высоким приоритетом».
Включайте там, где карусель это первое, что видит посетитель, обычно на главной, и не включайте на остальных страницах: пометить приоритетными несколько картинок это то же самое, что не пометить ни одной.
1.5 Retina-картинки: честный компромисс
В CS-Cart есть штатный аддон HiDPI, который отдаёт экранам с высокой плотностью картинки двойного разрешения. Магазин выглядит резче на современных телефонах и ноутбуках, и это стоит трафика.
Для обычного экрана не меняется ничего. Для посетителя с retina каждая плитка товара подменяется вдвое большей по ширине и высоте, то есть вчетверо по площади пикселей, и вес картинок страницы растёт соответственно. На странице, где много фотографий, разница существенная.
Универсально правильного ответа тут нет, но есть факт, который стоит знать: мобильные тесты скорости эмулируют экран с высокой плотностью, то есть качают именно удвоенные картинки. Если после включения аддона мобильный балл просел, причина в этом.
Наш совет: включайте, если товар визуальный и фотография это то, чем вы продаёте; не включайте, если продаёте ценой и скоростью. Прежде чем решать, померьте оба варианта.
1.6 Держите один главный заголовок на страницу
На странице должен быть ровно один заголовок первого уровня. В CS-Cart это решает обёртка блока, которую вы выбираете в Дизайн → Макеты в настройках блока: одна обёртка выводит заголовок блока как главный заголовок страницы, остальные как обычные подзаголовки.
Обёртка с главным заголовком принадлежит одному центральному блоку страницы. Если назначить её и второму блоку, на странице окажется два конкурирующих главных заголовка, а это одинаково не нравится и поисковикам, и проверкам доступности. Если заголовок какого-то блока на главной выглядит слишком крупно, меняйте его обёртку, а не правьте тему.
1.7 Не вставляйте отрисованный HTML в HTML-блоки
Скопировать готовую разметку списка категорий или сетки товаров со страницы и вставить её в HTML-блок кажется быстрым решением, а на деле замораживает магазин. В такой копии зашиты абсолютные адреса, пути к картинкам и их размеры; она не последует за каталогом, когда вы переименуете категорию или замените фотографию, а после переезда на другой домен её ссылки будут вести в никуда. Используйте блок, который сам строит нужный список.
1.8 После перехода на HTTPS проверьте контент, а не код
Если хоть один элемент на HTTPS-странице загружается по HTTP, браузер помечает страницу как не полностью защищённую, а проверки снимают за это баллы.
Важное: эти адреса почти никогда не лежат в коде темы. Они в контенте, который завели вы или предыдущий разработчик: содержимое баннеров и меню, HTML-блоки, ссылки в подвале, настройки аддонов.
Быстрее всего найти их самим браузером. Откройте страницу, нажмите F12 и посмотрите вкладку Console: браузер перечислит каждый небезопасный ресурс с полным адресом, и по нему сразу понятно, какой блок править.
Одна оговорка: меняйте http:// на https:// только у проверенных адресов. Свой домен безопасен, сторонние сайты не всегда: часть из них до сих пор не поддерживает HTTPS, и замена вслепую превращает рабочие ссылки в битые.
1.9 Ставьте только те языки, которые вам действительно нужны
Каждый язык умножает число переводимых записей в базе и работу по поддержанию контента в согласованном виде. Добавить язык дело минуты; держать каждый баннер, пункт меню и категорию согласованными во всех языках уже нет.
1.10 Отключите аддоны, которыми не пользуетесь
Каждый включённый аддон добавляет запросы, хуки шаблонов, стили и скрипты на каждую страницу. Это самая дешёвая оптимизация из существующих и чаще всего пропускаемая.
Часть 2. На сервере
Эта часть требует доступа к хостингу. Передайте её администратору или в поддержку хостинга.
2.1 Держите кэш в оперативной памяти, а не в файлах
По умолчанию CS-Cart складывает кэш в файлы. Со временем этот каталог разрастается до огромных размеров, и первая загрузка после простоя начинает занимать очень долго. Быстрее всего это происходит в магазинах с фильтрами: каждая комбинация параметров в адресе порождает свою запись.
Переведите кэш на Redis. Он живёт в памяти и вытесняет старое сам, поэтому расти бесконечно не может. В config.local.php:
$config['cache_backend'] = 'redis';
$config['store_prefix'] = 'ваш_магазин';
Если на одном сервере несколько установок CS-Cart,
store_prefixобязателен и должен быть у каждой свой. Без него они делят одни и те же ключи кэша и начинают отдавать ошибки. Мы убедились в этом на своём опыте: разом слегло большинство наших установок.
Сессии и блокировки можно оставить в базе.
Ограничьте Redis по памяти и включите вытеснение, иначе он способен съесть всю оперативку:
maxmemory 512mb
maxmemory-policy allkeys-lru
Наш результат: долгий холодный старт исчез полностью.
2.2 Включите сжатие ответов
Проверьте, включён ли gzip. Его отсутствие это самая частая и самая обидная находка: страница уезжает к посетителю в несжатом виде.
Для nginx:
gzip on;
gzip_comp_level 5;
gzip_vary on;
gzip_proxied any;
gzip_types text/plain text/css application/json application/javascript
text/xml application/xml image/svg+xml;
Картинки и шрифты в список не добавляйте, они уже сжаты.
Наш результат: главная стала кардинально легче. На мобильном интернете это разница между «открылось» и «всё ещё крутится».
2.3 Включите HTTP/2
Если магазин работает по HTTPS, включите HTTP/2, чтобы браузер грузил десятки файлов темы параллельно по одному соединению. Для nginx это http2 on; в блоке сайта.
Проверка: curl -sI --http2 https://ваш-магазин/ | head -1 должно ответить HTTP/2 200.
2.4 Отдавайте WebP для картинок, которые идут мимо генератора превью
Настройка из части 1 покрывает миниатюры. Баннеры и другие полноразмерные изображения можно закрыть на веб-сервере: положить рядом с каждым оригиналом копию .webp и отдавать её, когда браузер сообщает, что принимает WebP, а остальным отдавать оригинал.
Оригиналы остаются нетронутыми, в базе ничего не меняется, а вся схема откатывается удалением копий. На одной из наших демок, где в настройках магазина вообще ничего не меняли, только это срезало вес картинок главной более чем вдвое.
Не забудьте Vary: Accept в ответе, чтобы кэши не отдали файл WebP браузеру, который его не покажет.
2.5 Задайте статике срок жизни в кэше
Статике нужен заголовок Cache-Control, иначе браузер при каждом заходе перепроверяет каждый файл. Разумные сроки: картинки и шрифты 30 дней; CSS и JS с хешем в имени год и больше; HTML не кэшировать.
2.6 Настройте PHP
OPcache держит скомпилированный PHP в памяти вместо перечитывания с диска. Разумные стартовые значения для магазина:
opcache.memory_consumption=256
opcache.max_accelerated_files=50000
opcache.interned_strings_buffer=16
max_accelerated_files важнее, чем кажется: у CS-Cart с аддонами легко набираются многие тысячи файлов, и при нехватке слотов кэш начинает вытеснять сам себя по кругу.
После настройки проверьте, что кэш не переполнен, а процент попаданий близок к 100.
Перезапуск PHP очищает этот кэш, и первые минуты сайт будет заметно медленнее. Делайте это в тихий час и сразу прогрейте магазин, открыв главную и пару категорий.
Число рабочих процессов. Больше не значит лучше. Считайте их от числа ядер процессора, а не от оптимизма: примерно четыре процесса на ядро это здравая отправная точка. На двухъядерной машине это около 8, а 30 будут работать медленнее, а не быстрее, потому что под нагрузкой сборка шаблонов и стилей начинает конкурировать за процессор и медленнее становится всем сразу. Плюс поставьте ограничение времени выполнения около 45 секунд, чтобы зависший запрос не держал процесс вечно.
Фоновые задачи. Если они запускаются посетителями, то один невезучий покупатель ждёт чужую тяжёлую задачу. Переведите их на системный планировщик и отключите запуск из веб-запроса. Заодно исчезнут всплески нагрузки в часы наплыва.
2.7 Проверьте две настройки базы данных
CS-Cart редко упирается в базу, но две настройки стоит посмотреть:
- Буферный пул InnoDB должен вмещать базу целиком, если позволяет память: тогда чтение идёт из памяти, а не с диска.
- Размер временных таблиц. При значении по умолчанию сортировки и группировки начинают сбрасываться на диск. У нас на сервере до правки на диск уходила изрядная доля временных таблиц.
Как понять, что база не виновата: посмотрите процент попаданий в буферный пул. Если он около 99.9, узкое место не здесь, и настраивать надо PHP и кэш.
2.8 Микрокэш страниц для магазинов с большим потоком
Если анонимных посетителей много, сильно помогает кэширование готового HTML на 30-60 секунд на стороне веб-сервера: при наплыве PHP считает страницу один раз, а все остальные получают готовую.
Условия, без которых это опасно, все сразу:
- Кэшировать только запросы без cookie. Появилась любая кука (сессия, корзина, валюта, язык), отдавайте живую страницу.
- Никогда не кэшировать корзину, оформление заказа, личный кабинет, вход и админку.
- Только запросы GET и только успешные ответы.
- Если магазин многоязычный, учитывайте язык в ключе кэша. CS-Cart умеет отдавать разные языки по одному и тому же адресу, ориентируясь на языковой заголовок браузера. Без этого посетитель может получить из кэша чужой язык. Мы поймали ровно это в тестах.
Часть 3. Как проверить результат
Меряйте до и после, иначе не поймёте, что именно помогло.
- Вес страницы и число запросов самые честные цифры.
- PageSpeed Insights, обязательно в мобильном режиме. Он моделирует медленный интернет и слабый телефон, и именно там видны реальные проблемы. Десктопная оценка почти всегда льстит.
- Время ответа сервера на главную и на страницу товара.
Три ловушки при проверке
- Кэш страниц. Если включён микрокэш, обычная проверка может показать вам устаревшую копию. Отправьте с запросом любую куку: такие запросы кэш обходят.
- Кэш шаблонов. После правки шаблонов изменения подхватываются не всегда. Сбросьте кэш магазина. На сервере с несколькими установками делайте это по одной за раз и прогревайте каждую перед переходом к следующей: одновременный сброс вызывает всплеск нагрузки, и посетители видят ошибки.
- Retina. Обычные проверки из командной строки показывают вес для стандартного экрана. Если аддон retina включён, реальные посетители на современных устройствах скачивают заметно больше. Меряйте с поправкой на плотный экран или доверяйте мобильному баллу, он это уже учитывает.
Чего мы НЕ рекомендуем
- Гнаться за SEO-оценкой на тестовом магазине. Если магазин закрыт от поисковиков, оценка будет низкой независимо от качества темы.
- Ставить все «ускорители» подряд. Два слоя кэширования, которые не знают друг о друге, чаще мешают, чем помогают.
- Покупать сервер помощнее, не разобравшись в проблеме. Не раз мы сталкивались с тем, что медленно было из-за настройки, а не из-за железа: в одном случае из-за разросшегося кэша, в другом из-за отсутствия сжатия. Более мощная машина обошлась бы дороже и не помогла бы ни там, ни там.