Ускорение сайта на WordPress

Несколько нехарактерная тема для блога, но начал смотреть в сторону и WordPress-а в дополнение к Drupal-у. И в эту тему статья. Итак ...

Довольно часто можно услышать вопрос: «Можно ли сделать быстрый сайт на WordPress?» При этом WordPress позволяет получить достаточно серьёзные сайты, которые должны приносить большие деньги своим владельцам и скорость является неотъемлемым качеством в успехе SEO.

Да, это возможно, хотя сама система скрывает в себе множество подводных камней с точки зрения скорости работы сайта. В этой статье мы кратко остановимся на причинах торможения сайтов на WordPress и подробно рассмотрим способы ускорения. 
Все проблемы и их решения основаны на реальных событиях (сайтах, которые доводилось оптимизировать).

Истоки: почему всё так плохо

Не секрет, что система является бесплатной и популярной в эконом-сегменте разработки сайтов. Это означает использование готовых шаблонов (тем), которые дорабатываются под конкретный сайт. Таким образом, на сайте оказывается большое количество ненужного JavaScript (JS) и CSS-кода. Так как разработчик обычно слабо разбирается в принципах верстки шаблонов, он не в состоянии качественно их почистить, даже при желании.

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

Все вышесказанное относится в основном к клиентской производительности, а есть еще серверная сторона. Время генерации HTML-документа может становиться проблемой при использовании слабого хостинга и неоптимальных серверных настройках.

В заключение проблем добавляют попытки самостоятельно решить все проблемы без понимания принципов ускорения сайтов. Такие попытки можно описать словами «установить все плагины со словом «скорость» и включить все галочки». Хорошим примером будет использование CDN, у которых нет точек присутствия в России (такие CDN приводят лишь к торможению сайта).

Ускорение серверной части WordPress

Напомню, что серверная производительность сильно влияет на скорость индексации сайта. Роботы подстраиваются под возможности сайта: выбирают количество страниц за проход, частоту запросов к сайту. Чем быстрее сайт, тем быстрее он может индексироваться. Ну и конечно, время генерации HTML-документа критично для скорости отображения сайта у обычных пользователей (до получения HTML браузер не может ничего показать).

Какое время отдачи HTML-документа можно считать нормальным? Это понятие зависит от жесткости требований к скорости сайта. Если использовать модель RAIL (или LIAR :-), то на время отдачи самой страницы остаётся совсем немного (максимум 100 мс), потому что на загрузку самой страницы выделяется 1000 мс (1 сек). В реальном мире для небольших сайтов приемлемым можно считать 200-300 мс на получение страницы «под ключ» – время сервера плюс время получения по сети.

Как и с любыми сайтам, здесь многое зависит от хостинга. Полный контроль и гарантированную производительность можно получить только при использовании хостинга как минимум VPS (VDS) — виртуально-выделенного. В этом случае будут доступны все возможности ускорения сайта, включая установку актуальных версий ПО и его настройка.

Итак, что можно сделать для улучшения серверной части?

Кеширование страниц

Для этого нужно установить плагин для кеширования страниц их частей, я рекомендую W3 Total Cache.

В большинстве случаев стоит кешировать страницы (Page Cache) и объекты (Object Cache). Также можно включить Browser Cache для включения возможности кеширования средствами браузера. Метод кеширования можно выбирать по вкусу и возможностям вашего хостинга. Но даже самый совместимый способ Disk даст мощный эффект.

Используйте Nginx

Nginx в качестве веб-сервера позволит вам легко получить правильную конфигурацию для любого сайта, оптимальной я бы назвал комбинацию Nginx+PHP-FPM. Руководств по настройке этой связки для работы с WordPress написано множество, поэтому отразим важные моменты настройки по скорости. 

  • Убедитесь, что Nginx отдаёт статические файлы напрямую, с заголовком Expires. 
  • Включите Gzip-сжатие для всех текстовых форматов (степень сжатия 9). Также включите gzip_static (зачем — далее). 
  • Проверьте наличие keep-alive соединений к конфигурации.

Оптимизация настроек MySQL

Часто причиной медленной работы сайта становится некорректная конфигурация MySQL. По умолчанию эта СУБД настроена на потребление минимального количества оперативной памяти, поэтому размеры кешей и буферов достаточно скромные. Существует несколько основных настроек, которые стоит трогать и набор настроек зависит от типа используемого движка таблиц (MyISAM, InnoDB или что-то еще) и количества доступной оперативной памяти. Не будем углубляться в эту тему, существует большое количество руководств по оптимизации MySQL (например, на Percona Performance Blog), которые можно использовать.

Кроме того, нужно посмотреть на версию MySQL, установленную на сервер. Как правило, в каждом новом поколении сервера внедряется множество оптимизаций и улучшений, поэтому предпочтительно использовать современные версии (особенно, если вы используете InnoDB).

Профилирование плагинов

Свой вклад в торможение сайта (с серверной стороны) могут вносить подключенные плагины. Чтобы их выявить, полезно установить плагин P3 (Plugin Performance Profiler). С его использованием вы получите достоверную информацию о времени исполнения каждого плагина на сайте. Единственный минус: данный плагин не поддерживается разработчиком и при его использовании могут возникнуть проблемы.

Ускорение клиентской части WordPress

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

Как я писал выше, сайты на WordPress строятся на базе тем (шаблонов), которые разрабатываются для быстрого запуска сайта «без навыков программирования». Как обычно, такая простота вызывает множество проблем. Основная проблема – непонимание разработчиком сайта принципов работы темы и назначения ее отдельных элементов.

Итак, посмотрим, какой план действий поможет нам ускорить сайт.

Определение критического пути

Сначала нужно найти все ресурсы, которые блокируют рендеринг страницы. Напоминаю, что в критическом пути могут фигурировать следующие элементы: HTML-документ (об этом мы говорили выше), CSS-файлы, JS-файлы (кроме асинхронных), подключаемые шрифты.

Сделать это легко: включить средства разработчика (например, Chrome Developers Tools) и выбрать закладку «Network» с установленным фильтром Doc, JS, CSS, Font. Также нужно активировать опцию «Сapture screenshots». Для большей наглядности можно затормозить сеть (Network Throttling).

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

Таким образом мы знаем, какие ресурсы требуются для отрисовки страницы до нужного нам уровня (как правило, это первый экран нужного вам дисплея).

Поиск лишних элементов

Это важнейший этап в оптимизации клиентской части, так как позволяет добиться высокого качества работ. Одновременно, это довольно затратный этап.

Суть заключается в следующем: нужно найти все элементы критического пути (и не только), которые загружаются, но не используются на странице.

Для CSS-файлов это можно сделать с помощью панели Audits в инструментах разработчика. Здесь можно найти файлы, которые не используются вообще (в разделе Remove unused CSS-rules). После этого можно убрать вызов этих файлов стилей (он может быть как header.php темы, так и в любом другом файле – нужно искать). Далее тестируем сайт – если какая-то конкретная страница использует убранный CSS, то можно оставить его только для этого типа страниц.

В результате мы уменьшаем количество кода CSS и экономим количество байт до начала рендеринга страницы. Напоминаю, что CSS файл, независимо от места размещения в HTML-документе, является блокирующим рендеринг элементом.

Для JS-файлов придётся разбираться полностью вручную. В первую очередь нужно посмотреть на дублирующие библиотеки. Это звучит странно, но в моей практике часто встречаются сайты несколькими jQuery одновременно. Второй по популярности случай: подключение плагинов jQuery, которые не используются на сайте. При этом сайт работает, но скорость загрузки оставляет желать лучшего. Далее выясняем назначение каждого из JS-файлов и начинаем отключать их по-одному. Подключение JS-файлов может быть как в header.php, script-loader.php, так и в других местах (например, плагинах).

Убирая лишние JS-файлы мы экономим дважды: сокращаем трафик в критическом пути, а также сокращаем процессорное время для исполнения этих файлов (особенно критично на мобильных устройствах).

Убираем единые точки отказа в JS и CSS

Типичная ошибка многих разработчиков в том, что они не учитывают эффект клиентской точки отказа (SPOF). Если мы подключаем JS-библиотеки или CSS-файлы с внешних источников (CDN, сайт разработчика, API сторонних сайтов), то попадаем в зависимость от внешнего сайта. При этом используются как правило бесплатные CDN, которые не имеют никаких гарантий работоспособности. В случае CSS-файла заблокируется рендеринг всей страницы, в случае JS (обычного, синхронного) – заблокируются элементы ниже по HTML-коду.

Помимо блокирования рендеринга страницы в случае недоступности источника есть вторая проблема: часто бесплатные CDN не имеют точек присутствия в России, поэтому их использование замедляет загрузку сайта.

Чтобы избавиться от этой проблемы нужно перенести все скрипты и стили на свой сервер, а те, которые не получится – подключать по возможности в асинхронном режиме.

Замена JS-файлов на более оптимальные варианты

Здесь хочется сказать о двух вещах. Во-первых, популярные JS-библиотеки и плагины постоянно развиваются, появляются новые версии. Часто в них исправляются ошибки, иногда улучшается скорость работы. Поэтому, нужно загрузить и подключить новые версии, при этом нужно следить за совместимостью (тестировать работоспособность всех элементов).

Во-вторых, некоторые библиотеки допускают частичную загрузку или сборку по компонентам. Яркий пример: jQuery-UI. Если вам нужен только календарь, то эта библиотека после сборки будет в несколько раз меньше, чем полный пакет. Также можно частично подключатьAPI Яндекс.Карт (но определить нужные модули будет сложно).

В-третьих, используйте асинхронный код подключения библиотек, если это возможно. Например, веб-счетчики уже давно представлены асинхронным кодом. Плагины социальных сетей также обычно имеют асинхронный вариант. Обратитесь к документации библиотек и выясните такую возможность. Асинхронная загрузка хороша тем, что не блокирует рендеринг страницы, независимо от положения вызова в HTML-коде.

Экономия достигается в двух направлениях: количество трафика и время компиляции кода (нагрузка на CPU).

Оптимизируем CSS и JS

На этом этапе у нас остались только нужные элементы критического пути, осталось их оптимизировать.

Для это нужно сделать 2 действия: минификация и сжатие. Минификацию можно проводить любыми доступными вам средствами или получить уже готовую минифицированную версию библиотеки (как правило, имеют суффикс .min или .pack в имени файла).

Сжатие это операция для владельцев VPS-хостинга или выделенных серверов. Дело в том, что можно провести компрессию файлов с использованием алгоритма Zopfli. Это разработка инженеров из Google, оптимизированный по степени сжатия вариант Gzip. За счет большой ресурсоёмкости позволяет «выжать» дополнительные 8-10% экономии размера файлов. С учетом размера современных JS-библиотек это очень актуально. Для использования этого преимущества нужно настроить в Nginx опцию gzip_static.

Оптимизация размещения CSS и JS

Для ускорения загрузки страницы нужно выполнять правило: CSS вверху страницы, JS внизу. Но здесь не всё так просто. Дело в том, что JS-код может быть разброшен по всему HTML-документу, кроме того важен порядок загрузки файлов, так как есть взаимозависимость.

Кроме того, эти файлы подключаются в различных местах и контролировать это вручную не получится.

Для решения этих проблем рекомендую подключить плагин Autoptimize. С его помощью можно автоматически оптимизировать порядок подключения CSS и JS-файлов.

Плагин имеет множество настроек, которые нужно поставить для достижения оптимальной скорости и не сломать функциональность сайта. Что нужно использовать: 

  • минификацию HTML (безопасно); 
  • объединение CSS (безопасно, если не важен порядок CSS); 
  • объединение JS-файлов (могут возникнуть проблемы с порядком); 
  • минификация JS и CSS (не должно вызывать проблем); 
  • перенос JS-файлов на место закрывающего тега </body> (также нужно следить за ошибками, а также включать объединение Inline JS).

В случае возникновения проблем нужно найти источник (конкретный файл или кусок кода в теле страницы) с использованием средств разработчика. Далее потребуется разобраться в причине проблемы, например: вызов jQuery до его загрузки, вызов функции плагина раньше его загрузки, инициализация переменных после модуля, который их использует.

Если удаётся разрешить все конфликты, то мы получаем действительно быструю загрузку сайта за счет отложенного кода JS, который грузится параллельно рендерингу страницы.

Оптимизация подключаемых шрифтов Довольно обширная тема и хорошо описанная в различных статьях (например, здесь). Если кратко, то есть два аспекта: минимизация набора символов и вариантов шрифта и использования оптимальных форматов.

Варианты шрифта оптимизируется путём загрузки только тех начертаний, которые используются на сайте. То же самое относится к наборам символов.

Наиболее продвинутый формат хранения шрифтов называется WOFF2. Этот вариант можно использовать в первую очередь. Для остальных браузеров уже можно подключать WOFF, EOT и TTF. При этом нужно помнить, что все форматы, кроме WOFF2 можно сжать обычным Gzip при отдаче, что даёт экономию трафика.

Оптимизация изображений

Есть хорошая новость: картинки не блокируют отрисовку страницы целиком и могут спокойно загружаться во время просмотра. Тем не менее, оптимизировать изображения нужно сразу по нескольким причинам: на их загрузку тратится трафик и используется полоса пропускания (что замедляет загрузку CSS и JS), а также изображения могут нести важную информацию, без которой страница теряет ценность.

Все изображения можно разделить два типа: картинки оформления (шаблона) и контент (иллюстрации на странице). Разница в том, что картинки оформления меняются редко: их можно оптимизировать и забыть на время. Контент же добавляется постоянно и разовой оптимизацией здесь не обойтись: требуется процесс оптимизации контента.

Программа максимум: организовать оптимизацию всех изображений на сайте, минимум – картинок оформления.

Посмотрим, что нужно сделать для оптимизации изображений.

Во-первых, размер картинок должен соответствовать размеру в документе (за исключением картинок для hidpi-дисплеев). Типичная ошибка: показ крупной картинки в виде миниатюры – например, для анонса статьи или в фотогалерее. Единого решения здесь нет: если картинки нарезаются программно, то нужно добавить корректный размер миниатюры, если вручную: сделать еще одну версию при выкладке контента.

Во-вторых, нужно выбирать правильный формат изображений. Если кратко: фото должны быть в JPEG, картинки с прозрачностью и небольшие элементы оформления в PNG. Основная ошибка в выборе: использование PNG24 для больших изображений (например, слайдов, рекламных баннеров).

В-третьих, получившиеся картинки нужно оптимизировать: сжать оптимальным образом, убрать всё лишнее из файла. Для выполнения этих действий есть множество программных инструментов, набор зависит от формата.

Итак, для JPEG-файлов рекомендации следующие: 

  • Компрессия с использованием кодера Mozilla JPEG, уровень качества около 80%. 
  • Оптимизация с использованием JPEGoptim – из файла убираются все лишние метаданные.

Для PNG-формата следующий процесс: 

  • Сжимаем дополнительно с ZopfliPNG – получаем до 8-10% экономии. 
  • Удаляем все лишние данные с OptiPNG.

Для продвинутой оптимизации можно сгенерировать WebP. Этот формат позволяет сжимать в различных режимах (с потерями и без), поддерживает прозрачность и отличается повышенной эффективностью (экономия может достигать 80%). Он поддерживается только в Chromium-браузерах (Chrome, Opera, Яндекс.Браузер). Для обеспечения совместимости нужно сохранять и обычные версии картинок. За счет настройки Nginx можно прозрачно раздавать оптимальный вариант изображений.

Оптимизация Single Page Application

Сейчас всё большую популярность набирают сайты с активным использованием AJAX, где переход между страницами осуществляется путем динамической перерисовки части блоков. При начальной загрузке такого сайта работают все правила оптимизации обычных сайтов. А вот скорость работы JS после загрузки оптимизировать какими-то стандартными средствами не получится. Подход здесь должен быть индивидуальным, но методика следующая: профилируем JS-код, находим самые «горячие» куски кода, медленные функции и оптимизируем их.

Итоги

Итак, мы рассмотрели практически все аспекты ускорения сайта на WordPress. Как видите, есть множество аспектов скорости работы сайта, о которых нужно позаботиться. Даже в этой, довольно объёмной статье, не удаётся рассмотреть все возможные ситуации. Например, мы практически не говорили о выборе и настройке хостинга под нагрузки.

Надеюсь, что статья поможет владельцам и разработчикам сделать их сайты быстрее.

Автора автора