Как победить Google PageSpeed? Оптимизация сайта под мобильные устройства и ПК

Share

Еще относительно недавно каждый разработчик слышал от заказчика такую фразу: «Мы проверили сайт на валидность кода и оказывается у вас очень много ошибок в html и css. Нужно исправлять!». И здесь наступал этап долгих переговоров и убеждений, что этот валидатор, почти, ни на что не влияет, и что у вас не ошибки, а попытки сделать кроссбраузерный код, который сможет работать даже в Internet Explorer. Но обычно такие переговоры заканчивались мучениями и попытками обойти валидатор.

Время шло, вопрос о валидности кода канул в небытие, а на смену ему пришел новый, не менее хитрый валидатор от Google под названием PageSpeed. И теперь вопрос от клиентов звучит уже так: «Валидатор показывает ошибки, почему у нас не 100? Нужно исправлять!«. Но в этом случае удовлетворения требованиям хотя бы приносят ощутимый результат.

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

Исходный результат у нас следующий:

Оптимизация сайта. Получения высокой оценки от Google PageSpeed

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

Подробный отчет о диагностике:

Результаты диагностики от PageSpeed Результаты диагностики от PageSpeed

Ускорение работы сайта. Основные этапы

1. Время загрузки первого контента

Оптимизация сайта. Время загрузки первого контента

В отчете прекрасно видно, что первые 6 кадров при загрузке страницы пустые, то есть, браузеру что-то мешает отображать сайт. Эта ошибка возникает в том случае, когда у вас в разделе <head> присутствует большое кол-во скриптов или стилей, или же они расположены в начале страницы. Другими словами, браузер пытается сначала их загрузить, а лишь потом начать отображать. Действие не совсем корректное, поскольку браузер должен делать все синхронно. То есть одновременно начать отображать контент и параллельно подгружать статические элементы (картинки, стили, скрипты).

Наша задача в данном случае, это проанализировать все то, что находится в начале страницы и по максимуму унести вниз до закрывающего тега </body>. Стили также необходимо перенести в конец страницы, вверху оставить только те стили, которые формируют первый экран сайта.

В моем случае, вверху страницы находится: подключение библиотеки jQuery, скрипт по удалению Яндекс.Советника, основная библиотека функционала сайта main.js, подключение Google Tag Manager и десяток css-файлов. Из всего перечисленного в начале страницы действительно нужно только скрипт для удаления Яндекс.Советника и подключение GTM, со стилей нужен только маленький файл для первого экрана. Остальное, а это большая библиотека jQuery и main.js, да и еще десять css-файлов только замедляют работу сайта, их мы переносим вниз.

2. Уменьшение размера CSS-кода и JavaScript-кода

Сюда можно также отнести пункт «Удалите неиспользуемый код CSS«, но его мы вообще рассматривать не будем, поскольку часто прирост дает не большой, а требует продолжительного анализа и копания в коде ради удаления пары десятков строчек. В прочем, если вы знаете, что именно в CSS у вас лишнее — удаляйте, будет только в плюс.

Что под собой подразумевает уменьшение размера кода. В первую очередь, это уменьшение кол-ва файлов, то есть, если у вас 5-10 css-файлов, лучше их объедините. Браузеру проще загрузить один большой файл, нежели несколько мелких. После объединения необходимо почистить сами файлы, под чисткой подразумевается удаления всех комментариев, лишних пробелов и отступов, переносов строк. Этот процесс называется минификация. Чтобы сделать это автоматически можно установить либо дополнительный плагин, если таков существует, либо воспользоваться онлайн-сервисами минификации.

И так, наша задача, объединить, по возможности, все подключаемые css-файлы и все js-файлы в соответствующие большие файлы. Над полученными файлами произвести минификацию.

3. Уменьшение размера HTML-кода

Задача в чем-то похожа на предыдущий пункт, но речь уже не о статическом контенте, а генерации самой страницы сайта. С самого начала вам необходимо почистить файлы шаблонов, чтобы в них отсутствовал закомментированный код, так как он никакой информации не несет, но использует лишний трафик. Далее, после того, как ваш движок сгенерировал исходный код html-страницы и готов его отдать пользователю, вам необходимо минифицировать полученный код, то есть удалить из него лишние пробелы, табуляции, переносы строк.

Пример кода для очистики html:

$result_html = preg_replace(
    ['/ {2,}/', '/<!--.*?-->|\t|(?:\r?\n[ \t]*)+/s'],
    [' ', ''],
    $result_html
);

Казалось бы, зачем удалять эти пробелы и переносы, роли никакой не играют, но на практике размеры страницы сокращаются на 25-50%. Что значительно ускоряет её загрузку.

4. Кеширования статических объектов

Задача достаточно простая, нам необходимо настроить web-сервер, который обрабатывает статику, чтобы он отправлял специальные заголовки браузеру с требованием кешировать картинки, иконки, скрипты, стили, шрифты и прочие подобные объекты.

Как правило, за отдачу статики отвечает nginx, поэтому в конфиг сайта необходимо добавить следующее:

location ~* ^.+\.(jpg|jpeg|gif|css|png|js|ico|bmp|eot|svg|ttf|otf|woff|woff2|webp)$ { 
    access_log off;
    expires 180d;
    break; 
}

В список вы можете также добавить и другие статически файлы, которые использует ваш сайт.

В случае, когда ваш сайт работает только на apache, в файл .htaccess добавляем следующее:

<ifModule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/html text/plain text/xml application/xml application/xhtml+xml text/css text/javascript application/javascript application/x-javascript
</ifModule>

<ifModule mod_headers.c>        
    <FilesMatch "\.(flv|swf|ico|gif|jpg|jpeg|png|js|css|txt|webp|ttf|woff|eot)$">
        Header set Cache-Control "max-age=2592000"
    </FilesMatch>
</IfModule>

<ifModule mod_expires.c>
    ExpiresActive On
    
    ExpiresDefault "access plus 5 seconds"
    
    ExpiresByType image/x-icon "access plus 2592000 seconds"
    ExpiresByType image/jpeg "access plus 2592000 seconds"
    ExpiresByType image/png "access plus 2592000 seconds"
    ExpiresByType image/gif "access plus 2592000 seconds"
    ExpiresByType application/x-shockwave-flash "access plus 2592000 seconds"
    ExpiresByType text/css "access plus 2592000 seconds"
    ExpiresByType text/javascript "access plus 2592000 seconds"
    ExpiresByType application/javascript "access plus 2592000 seconds"
    ExpiresByType application/x-javascript "access plus 2592000 seconds"
    ExpiresByType application/xhtml+xml "access plus 600 seconds"
</ifModule>

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

<script src="/assets/js/main.js?1568090309"></script>

5. Настройка показа всего текста во время загрузки web-шрифтов

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

Делается это добавлением в раздел @font-face{}:

font-display: swap;

6. Отложенная загрузка изображений

Так как для формирования страницы браузером нам в первую очередь необходима загрузка скриптов и стилей. А они находятся у нас в конце страницы, то следующая задача это создать условия для быстрейшей загрузки этих файлов. Здесь нам нужно притормозить загрузку остальных неприоритетных элементов, в данном случае ими выступают картинки сайта. Был изобретен метод в простонародье известен как «ленивая загрузка». Суть его в следующем, в атрибут src изображений помещают пустой пиксель, а требуемый путь прописывают в data-src (для разных расширений экрана можно использовать разные пути) и в последствии, заменяется data-src на src. То есть, загрузка картинок начинается после того, как загрузись css и js.

Пример кода:

<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-src="путь_к_файлу" alt="" />
function lazyloadRun() {
    var container = document.body;
    if(container) {
        var img_list = container.getElementsByTagName('img');
        for(var i = 0;i < img_list.length;i++) {
            var el = img_list[i];
            var data_src = el.getAttribute('data-src'); 
            if(data_src) {
                el.setAttribute('src',data_src);
                el.lazy = '';
            }
        }
    }
}

lazyloadRun();

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

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

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

Этот пункт необходимо разделить на 3 части:

7.1. использование правильных размеров

Перед загрузкой изображений задайте им правильный размер, то есть, если у вас изображение на сайте должно отображаться в формате 500×300 пикселей, то и само изображение должно быть по ширине 500 пк., а по высоте 300 пк. Бывает часто, что «опытные» контент-менеджеры загружают картинки прямо с флешки зеркального фотоаппарата. А после заходишь на сайт, а там 10 статей и в каждой картинки с размером в 10 МБ.

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

7.2. сжатие изображений

Вторым действием будет сжатие изображения. В процессе сжатия картинка, особенно в формате jpeg, может потерять в качестве, но потери не значительны и на практике буквально не заметны. Сжатые изображения весят, в среднем, в два раза меньше, тем самым экономят трафик и повышают скорость работы.

Для сжатия изображений можно использовать онлайн-сервисы, либо использовать «Сохранить для web» в Photoshop. Либо установить специальный софт (jpegoptim и optipng) для сервера и использовать сжатие для все загруженных файлов. Подробнее об установке и использовании софта под Linux рассмотрим в следующих записях. Вы же можете найти информацию в интернете.

Наша задача, проверить изображения на сервере и по возможности произвести сжатие.

7.3. Использование современных форматов изображений

В последние годы набирает популярности представленный Google формат *.webp. Но заменять сразу все изображения на webp не стоит, так как браузер Safari не поддерживает данный формат, как и старые тоже. А значит львиная доля пользователей будет испытывать проблемы при посещении вашего сайта.

Использование формата webp дает не плохой прирост в скорости и если вы все-же хотите его использовать следует знать, что браузеры, которые поддерживают формат webp отображают это в системных заголовках. То есть при генерации страницы вы можете сделать проверку:

if(strpos( $_SERVER['HTTP_ACCEPT'], 'image/webp') !== false) {
    // используем webp
}

И если браузер поддерживает webp, то отдавать картинки в этом формате, в противном случае использовать стандартный jpeg или png. Но данный способ требует больше дискового пространства и заморочки при добавлении записей.

8. Ajax — наш лучший друг

Одной из рекомендаций Google PageSpeed является «Сократите размер структуры DOM«. О чем идет речь, если у вас на сайте есть слайдеры, любой скрытый контент или просто бесполезная (в качестве SEO) информация, её можно подгрузить асинхронно.

Как это выглядит на примере, на рассматриваемом нами сайте есть раздел «Новинки», он представлен в виде слайдера и вот что интересно, при прокрутке товары подгружаются не асинхронно, а просто показываются, то есть они уже сформированы и добавлены в html-код страницы, но пока пользователей не нажмет прокрутку они будут оставаться невидимыми. С одной стороны проблемы нету, но таких товаров более 80-ти штук, а на экране отображается только 4-е. Получается, что в коде страницы присутствует очень много лишней информации, которую можно удалить. Также, внизу страницы есть раздел «Последние публикации», в нем размещены статьи 3-х годичной давности, они уже проиндексированы и размещения их на главной не требуется, сделано по требованию дизайна, а значит такой блок можно также подгрузить с помощью ajax.

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

Результат

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

Оптимизация сайта. Получения высокой оценки от Google PageSpeed

Для данного сайта это является, практически, максимальным результатом. Возникает логический вопрос, как же другие сайты умудряются получить 100 баллов. Чтобы ответить на него проведем следующий анализ. У нас остается две рекомендации:

Оптимизация сайта. Отчет по работе JavaScript

Здесь мы можем увидеть, что загрузка скриптов занимает большую часть времени. Проанализировав список самих скриптов, видим, что это скрипты используемые в целях аналитики и электронной коммерции. Все они подключены через Google Tag Manager. Пробуем скрыть код подключения и видим такие результаты:

Результат. Оптимизация сайта. Получения высокой оценки от Google PageSpeed

Поскольку код GTM мы удалить не можем, делаем вывод, что предыдущие результаты являются максимальными для данного сайта.

На этом все, если у вас остались какие-либо вопросы или дополнения пишите в комментариях.

Может быть полезно