Проблема
С июля 2018 Google начали учитывать скорость страниц в выдаче. В ноябре 2019 года они добавили отчет о скорости страниц в личный кабинет Web Search Console. В июне 2021 они ужесточили критерии PageSpeed, подняв влияние Total Blocking Time (TBT) с 25% до 30% и Cumulative Layout Shift (CLS) с 5% до 15%.
Я когда-то, как и многие это делают и по сей день, искал штуку, которая бы закрыла все потребности в оптимизации своего WordPress сайта. Даже пару лет назад делал сравнительное исследование различных плагинов и их сочетаний, чтобы другим было проще ориентироваться, за что получил много положительных отзывов и благодарностей, спасибо вам за теплые слова.
Но почему-то, что в совокупности, что по отдельности не было идеального решения. У кого-то что-то лучше сделано, у кого-то хуже (сразу приходит на ум аналогия с процессом выбора автомобиля). Поскольку я разработчик, то ещё тогда закралась мысль о создании решения, закрывающего все потребности.
Решение
Оно увидело свет в этом году. Плагин написан полностью с нуля.
Проведенный тест на 72 различных сайтах (легких и тяжелых, с кучей рекламы, Elementor и т.д.) показал увеличение балла Google PageSpeed в среднем с 37% до 94% на мобильных устройствах и с 82% до 99% на десктопах. В тестах были использованы конфигурации с PHP 7.0.33, 7.1.33, 7.2.34, 7.3.28, 7.4.19, 7.4.3, 8.0.2, 8.0.5, 8.0.7 и веб-серверами Nginx 1.14.0 (Ubuntu x64), 1.20.1 (Ubuntu x64), Apache 2.4.6 (CentOS x64), 2.4.41 (Ubuntu x64), 2.4.35 (Windows x86), 2.4.46 (Windows x64).
Один нюанс, который можно отнести к недостаткам – решение платное. Но цена весьма скромна в сравнении с другими платными решениями. Да и функциональность получилась шире.
Далее о ключевых особенностях.
Никаких внешних сервисов и зависимостей
В софте всякие внешние дополнительные зависимости добавляют тормозов и искусственно «подсаживают» на сервис/продукт. Тут такого нет в отличие от некоторых других аналогичных решений. Также, нет лимитов на количество страниц, их просмотров, объёма и прочего.
Максимальная работоспособность без настроек
Хорошо и правильно, когда работает сразу. Многие плагины приходится долго мучительно настраивать, чтобы поучить стабильное поведение и какой-то результат. Настройки подобраны так, чтобы максимально охватить все конфигурации, минимально вмешиваться в структуру сайтов и сразу увидеть результат оптимизации. Но сами настройки гибкие и большие.
Необходимое использование сторонних библиотек
Чем меньше кода, тем лучше. Использованы внешние библиотеки только по явной необходимости.
Ленивая загрузка
Фронтенд. Он должен быть легким, надежным и достаточно быстрым. Выбор пал на LazySizes.Минификация JS
Бекэнд. Используется проверенная временем JsMin-Php.Минификация CSS
Бекэнд. Используется проверенная временем YUI CSS compressor PHP port.Разбор CSS
Бекэнд. Также используется для минификации. Выбрана актуальная и хорошо поддерживаемая с аккуратным кодом библиотека PHP CSS Parser. Используется взамен предыдущей. Но предыдущая быстрее, т.к. там нет полного парсинга структуры. В планах проведение сравнительного тестирования скорости обеих, чтобы понять можно ли оставить только эту, т.к. она более универсальная. В идеале её вообще сделать нативной, как следующую.Разбор HTML
Бекэнд. Используется встроенный в PHP DOMDocument как надежный и самый быстрый в силу своей нативной реализации.
Производительность в критических по времени местах
Важные и критические к быстродействию части кода были отдельно протестированы на скорость. Например:
json_decode() или unserialize()
Сравнивались, когда выбирался формат хранения данных для дескрипторов страниц. Последнее на 5% быстрее (предположительно из-за наличия длин полей).unserialize(gzdecode()) или unserialize()
Последнее быстрее на 20%, но размер данных у первого меньше на ~40%. Т.к. дескрипторы страниц занимают мало места по сравнению с основными данными (почему так – в следующем разделе), то решено было сжатие не использовать в угоду скорости. Пример сайта с 14000 страницами в кэше: суммарный размер дескрипторов ~170 МБ и суммарный размер данных ~1500 МБ, т.е. примерно 10%.substr($s, 0, 3) === 'abc' или strpos($s, 'abc') === 0
Используется при проверке исключений. Очень часто встречается PHP код, где для проверки начала строки используется substr. Понятно, что если строка длинная, то первый способ будет быстрее. Но на малых длинах строки $s (примерно до 100-130 символов) второй способ уже будет быстрее. Например, при длине строки в 30 символов, быстрее будет на 25%. Скорее всего, по этой причине в PHP 8 добавили str_starts_with.
Формат данных важен, т.к. на продакшене его изменить гораздо тяжелее, чем алгоритм. Замеры делались на PHP 7.4.20 и PHP 8.0.7, CPU Intel Core i7 3.4 ГГц, RAM 1600 МГц.
Оптимизация размера кэша
За место на хостинге мы платим почти всегда. Да и чем меньше данных, тем быстрее к ним доступ. А значит загрузка страниц будет быстрее.
Выделение одинаковых блоков
Т.к. страницы сайта похожи друг на друга – имеют общие части такие как хедер, футер, то хранение таких блоков в единственном экземпляре сильно экономит место. Это позволяет эффективно кэшировать зависящие от параметров страницы (например переключение валюты) или пользовательские сессии. Настраивается тут.
Сжатие
Также, по умолчанию кэш хранится в сжатом виде. Используется для:
- экономии места;
- для ускорения отдачи заранее сжатого контента.
Настраивается тут.
Также, небольшой размер кэша позволяет эффективнее использовать технологии кэширования в памяти, такие как Redis и Memcached. Это актуально для высоконагруженных сайтов. Их поддержка планируется в скором будущем. Напишите, пожалуйста, кому это важно – это позволит поднять в приоритете реализацию.
Распределение по нескольким CDN
Задавая несколько серверов, можно, например, разделить нагрузку на основной хостинг и (или) сэкономить на их тарифе. Настраивается тут.
Эффективное обновление данных
Кэш нужно обновлять, т.к. данные меняются. И делать это надо с минимальными затратами. Сильно влияет на First Contentful Paint (FCP), т.к. определяет время до получения первого байта от сервера.
Устойчивость к высоким нагрузкам
Когда запросов к сайту много, то обновление страницы может привести к сильной загрузке хостинга. Для предотвращения этого сделано так, что когда страница обновляется, то параллельные запросы к той же странице используют кэшированные данные. Но запрос, инициирующий это обновление, ждет окончания обновления. А избежать и этого помогает следующий пункт.Ленивое обновление страниц
Позволяет страницам всегда браться из кэша, даже когда идет обновление данных. Очень полезно, когда поисковые системы (особенно Google и Yandex) постоянно мониторят скорость страниц, т.к. всегда быстро возвращается оптимизированная страница. Настраивается тут.
Оптимизация изображений и видео
Как показывает опыт SEO, наличие видео очень хорошо сказывается на времени нахождения пользователей на страницах. Да и красивые картинки делают просмотр приятнее. Но это не должно негативно влиять на скорость загрузки контента.
Ленивая загрузка изображений
Она реализована через обозначенную выше библиотеку с добавлением встроенного прозрачного изображения того же размера, чтобы при загрузке не было «скачков» элементов, что положительно влияет на показатель Cumulative Layout Shift (CLS). Сам подход влияет в основном на Largest Contentful Paint (LCP) и на First Contentful Paint (FCP).Ленивая загрузка видео и фреймов
Очень важная штука, т.к. фреймы (особенно видео) сразу грузят большое количество скриптов, что сразу уводит рейтинг скорости сильно вниз баллов на 25-30, влияя на все показатели, кроме разве что Cumulative Layout Shift (CLS). Сделано так, что внедрение подменного быстрого блока вообще не ломает разметку исходной страницы в отличие от других плагинов.Уменьшение размера изображений
Т.к. изображения подгружаются лениво, то это сильно снижает влияние на результат. Поэтому реализация отложена в следующие версии плагина. Пока можно использовать сторонние, например, бесплатный EWWW Image Optimizer (у него правда под Windows плохо работает конвертация в WebP).Встраивание мелких изображений
По умолчанию изображения менее 2 КБ встраиваются в HTML и CSS. Это максимально ускоряет их загрузку. Настраивается тут.
На Хабре есть хорошая статья про изображения.
Оптимизация стилей (CSS)
Выделение критических частей
Это очень сильно влияет на показатель First Contentful Paint (FCP). Т.к. чем быстрее загрузятся первоначальные данные страницы, тем быстрее она нарисуется. Обычно, у сайтов много некритичных стилей, которые могут быть отложено загружены. По опыту прибавляет в среднем 10-15 баллов к показателю.
Группировка
Снижает количество запросов к серверу, тем самый уменьшает время загрузки страницы. По опыту прибавляет в среднем 5-10 баллов к рейтингу, влияя на показатель Total Blocking Time (TBT), важность которого подняли с 25% до 30% в 8 версии PageSpeed.Отложенная загрузка шрифтов
Делается стандартно через добавление font-display:swap атрибута. Плюс они не попадают в критические стили, что снижает размер страницы, особенно когда используются объемные Google Fonts. Настраивается тут.Минификация
Делается через специальную библиотеку, обозначенную выше.
Оптимизация скриптов (JS)
И наконец, скрипты – сама сложная часть страниц, которая хуже всего поддается оптимизации. Встречаются скрипты, которые зависят от своего местоположения (например, рекламные от Google AdWords). Поэтому оптимизация по умолчанию делает минимальные изменения. Большинство оптимизирующих плагинов как раз чаще всего «ломают» скрипты.
Группировка
По аналогии с CSS, снижает количество запросов к серверу, тем самый уменьшает время загрузки страницы. Но по опыту, т.к. скрипты в основном грузятся отложено, то ощутимого прироста рейтинга это не дает, а вероятность нарушить их работу повышает. GTMetrix показывает количество запросов, и включением этого режима можно попробовать увеличить на нём балл.Минификация
Делается через специальную библиотеку, обозначенную выше.Отложенная загрузка
Очень сильно влияет на показатели Total Blocking Time (TBT) и Time to Interactive (TTI). Потеря может достигать 30 баллов (прямо пропорционально объему скриптов). Самым эффективным способом оптимизации скриптов является задержка их загрузки. Но скрипты нужны для корректного отображения страницы. Поэтому они разделены на 3 группы:
Критичные
Сюда попадает всё что должно быть загружено до содержания главной страницы. Обычно тут пусто.
Некритичные
Всё что можно загрузить после содержимого главной страницы с задержкой. Здесь обычно все основные скрипты сайта.
Специальные
Всё, что можно загрузить ещё позже и не влияющее на основной рендеринг страницы. Сюда относятся, например, скрипты трекинга, рекламы, соц-сетей и т. д.
По умолчанию времена задержек загрузки некритичной и специальной групп выставлено для наибольшей совместимости и наилучшего показателя скорости. Для конкретных сайтов эти значения опытным путём можно уменьшать.
Что дальше
Решение протестировано с самыми популярными плагинами, не "ломает" рекламные скрипты, скрипты аналитики, видео-фреймы, и директивы Яндекса. По статистике, около 20% сайтов требуют дополнительной настройки, большая часть которых конечно-же скрипты.
Оптимизация изображений
Для ещё большего ускорения и доведения решения до полной комплектации. Как отмечалось выше, приоритет этой функции был понижен – надо было, чтобы продукт увидел свет.Предварительный прогрев страниц
В обычном режиме плагин ставится и сайт должен сразу стать быстрым. Сейчас страницы оптимизируются только при первом к ним обращении. Поэтому сейчас в начале присутствует инерционность, если сайт не имеет большого трафика.Кэширование пользователей
Оно и сейчас уже работает, но пока в состоянии «бета» - совместимость только с некоторыми плагинами. Нужно провести полное тестирование на различных популярных плагинах, для которых это критично, например, онлайн курсов, онлайн магазинов, поддержки аффилиата и прочих. Напишите, пожалуйста, какие плагины вам актуальны.Расширение статистики
Сейчас в статусе отображается самый минимум. Нужно добавить больше данных для мониторинга, например эффективность сжатия, включены ли все нужные подсистемы на хостинге и прочее. Вообще нужно показывать некое «здоровье» оптимизации.Использование кеширования в памяти
Поддержка, например, Redis и Memcached, упомянутая выше.
Заключение
Тема оптимизации ещё больше набирает обороты – возникает много решений в этой области. Тем более, что сам WordPress уже имеет 60 млн установок (что уже более 40% от общего количества сайтов) и продолжает расти. Да и Google будет и дальше изменять критерии, может, и Yandex тоже чем-нибудь подобным займется.
Также, в ближайших планах сделать отдельно анализ влияния различных оптимизаций на скорость страниц и итоговое влияние на PageSpeed score. Это позволит понимать при выборе кэширующего/оптимизирующего решения, на какие фичи обращать внимание и что актуально для конкретных сайтов. Например, для статичных сайтов с HTML, где страницы уже оптимизированы, можно просто задать кэширование браузера.
По любым вопросам я почти всегда на связи. Есть скидки для тех, кто с Хабра. Рассматриваются различные варианты сотрудничества.
(c) Seraphinite SolutionsTM 2015-2021. Все права защищены.