MaxSite.org
Создание сайтов и html-курсы для новичков

Как получить 100 баллов в Google PageSpeed Insights

Landing Page

Инструмент PageSpeed Insights позволяет не просто оценить скорость загрузки страницы, но и является в какой-то мере мерилом качества работы вебмастера. В отличие от html-валидатора, PageSpeed Insights оценивает сразу множество критериев, начиная от удобства мобильной версии и заканчивая настройками кэширования сервера.

Хочу отметить, что Гугл довольно неплохо развил этот инструмент и сейчас в общем-то на него можно смело ориентироваться (пока они опять что-нибудь не сломают :-) ).

Добиться заветных 100 баллов в PageSpeed Insights на самом деле не так просто. Лично я довольно долго ориентировался на «зеленые» оценки — это от 80 и выше. До последнего времени мой «потолок» был 93 для мобильной версии и 97 для десктопной. В своём последнем демо-лендинге я смог добиться 100/100 баллов.

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

Сразу хочу отметить, что 100 баллов очень сложно добиться на любой CMS. В них используется «пуленепробиваемый» код, который должен работать у любого пользователя. Например библиотеку jQuery можно подключить в конце BODY — это рекомендация гугла. Но, если пользователь решит разместить какой-то js-код (использующий jQuery) в теле записи, то он выдаст ошибку, поскольку jQuery ещё не загружена. Аналогично работают и множество плагинов, размещающие js-код прямо в основном теле страницы. Таким образом, jQuery потребуется разместить в HEAD, чтобы гарантировать её загрузку до выполнения любых других скриптов, что в свою очередь лишает нас нескольких баллов PageSpeed Insights.

Но, там где код страницы можно полностью контролировать, все рекомендации гугла можно выполнить. В основно это, конечно же, лендинги.

Итак. Перед тем, как приступить к анализу PageSpeed Insights прогоните страницу через html-валидатор до полного исправления всех ошибок.

Проверка страницы в html-валидаторе

Отсутствие html-ошибок будет гарантировать, что PageSpeed Insights построит страницу и выполнит анализ корректно.

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

Все ошибки/замечания можно разделить на несколько групп.

  • ошибки вёрстки
  • ошибки сервера
  • ошибки оптимизации ресурсов
  • ошибки сторонних сайтов

Ошибки вёрстки

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

С точки зрения верстальщика, оптимальным будет использование какого-то готового css-фреймворка, вроде UniCSS, который уже отработан для адаптивного дизайна и не содержит ошибок.

Ошибки сервера

В эту группу ошибок входят все те, для которых требуется настройка сервера. Обычно это правка .htaccess, где прописывается кэширования для браузера. Приводить код файла я не буду, поскольку он в типовом варианте присутствует в MaxSite CMS или LPF. То есть ничего придумывать не нужно.

Частая ошибка «Сократите время ответа сервера» зависит от множества факторов. Это может быть как медленный сервер сам по себе, медленное http-соединение или длительное построение страницы (PHP, MySQL). При медленном сервере решение возможно разве что путем обращения в техподдержку, а вот медленная генерация страницы в основном зависит от используемого «движка».

Обсуждать скорость работы CMS нет смысла, но вот что касается лендингов, то преобладают три подхода к их созданию:

  • «ванильный» html,
  • локальная сборка с получением статичного html-файла,
  • php-фреймворк.

Вёрстку «голым» html в общем-то сейчас мало кто использует, поскольку половина этой работы уйдёт на служебную часть кода.

Локальная сборка позволяет формировать html-файл из отдельных частей/файлов, а также последующая оптимизация кода, например его сжатие. К минусам здесь можно отнести медленную работу таких «движков» (обычно это Node.js), а также отсутствие PHP — например сложно будет сделать аякс-отправку почты.

PHP-фреймворк лишён всех этих недостатков. Я использую LPF (Landing Page Framework), специализирующийся именно на лендингах. Можно использовать другой: если генерация страницы проходит быстро, то PageSpeed Insights не будет выдавать ошибок о медлительности сервера.

Ошибки оптимизации ресурсов

Гугл считает, что все загружаемые ресурсы должны быть сжаты для экономии трафика. Причём выигрыш может быть минимальный, буквально десяток байт. Речь идёт о сжатии изображений, js и css кода. В новой версии PageSpeed Insights сам предлагает скачать все оптимизированные файлы:

Оптимизированые файлы

Это будет файл optimized_contents.zip— архив со всеми сжатыми файлами. Будет достаточно лишь загрузить их на сервер.

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

Основная сложность здесь в неудобстве работы со сжатым кодом. Если для генерации CSS мы используем Sass, который минифицирует код, то вот с JS есть некоторые сложности. В самом простом случае придется держать две копии файлов — одну исходные коды, вторую — сжатые для отправки на сервер.

Технически можно настроить автоматическое сжатие кода с помощью grunt (и аналогичных). Для LPF я использую специальную функцию, о которой речь пойдет ниже.

Ошибки сторонних сайтов

Это самые противные ошибки, поскольку мы никак не можем на них повлиять. Обычно это сторонний js-код, css-стили или изображения. Вот например «типовая» проблема с кодами Аналитикса и Фидбернера:

Ошибки сторонних сайтов

По иронии, оба этих сайта принадлежат гуглу и это рекомендованный код вставки. ;-(

Можно ли что-то с этим сделать? В некоторых случаях js-файлы можно скачать и подключать уже со своего сервера. Но, если сторонний файл обновится, то придется это как-то проверить и обновить файл. В более продвинутом случае можно настроить cron на автоматическую скачку сторонних файлов.

В любом случае такие ошибки проблема, с которыми, скорее всего, придётся смириться.

Оптимизация количества соединений

Чем больше количество дополнительных http-соединений, тем ниже будет рейтинг в PageSpeed Insights. На некоторые соединения мы не можем повлиять, например загрузка изображений или гугл-шрифтов, но можем уменьшить количество своих подключаемых js и css-файлов.

Здесь следует действовать осторожно. Когда-то считалось, то лучше все файлы объединить в один, но по факту получалось ещё хуже: из-за большого размера PageSpeed Insights сильно понижал оценку. Да и для посетителей загрузка страницы оказывалась медленней.

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

Оптимизация HTML

Здесь всё до безобразия просто — html-код следует сжать. В LPF это стандартная VAR-настройка compress_text: true.

Lazy-загрузка

Так называемая отложенная загрузка — это подключение всех js и css-файлов в конце BODY. Для css такая возможность появилась совсем недавно в HTML 5.2 примерно полгода назад. Поскольку стили подключаются в конце html-кода, то при медленном соединении страница будет отображаться без дизайна — фактически голым html. И вот здесь важно вспомнить о html-семантике и использовать надлежащие html-тэги: заголовки, тэги физического форматирования, списки, таблицы и т.д.

В некоторых случаях в секции HEAD размещают короткий css-код, который прячет основную страницу и выводит аля-заглушку с каким-нибудь крутящимся индикатором. Вопрос использования такого подхода сугубо индивидуальный, хотя для лендинга малопригодный, поскольку прилично раздражает посетителя, которому неясно: происходит ли реальная загрузка страницы или она уже «подвисла».

С точки зрения Гугла, html-код первичен, а значит все css-стили следует подгружать в конце.

Мы можем указать браузеру будущую загрузку в виде preload-контента. У него довольно простой код, который размещается в секции HEAD:

<link rel="preload" href="style.css" as="style">
<link rel="preload" href="main.js" as="script">
<link rel="preload" href="webfont.woff" as="font" type="font/woff" crossorigin="anonymous">
<link rel="preload" href="webfont.woff2" as="font" type="font/woff2" crossorigin="anonymous">

То есть браузер сам будет решать как организовать предзагрузку этих файлов.

Другой момент связан с загрузкой файлов с других сайтов. Здесь браузеру следует заранее указать домены, с которых предполагается что-то загружать. Делается это для того, чтобы получить IP сайта заранее (определение DNS может занять некоторое время). Решается задача следующим образом.

Нужно определить сайты с котрых будет идти загрузка. После прописываем их в виде кода:

<link rel="dns-prefetch" href="//fonts.gstatic.com/">
<link rel="dns-prefetch" href="//google-analytics.com/">
<link rel="dns-prefetch" href="//fonts.googleapis.com/">

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

Оптимизация CSS

CSS код следует формировать с помощью Sass. Я использую UniCSS — css-фреймворк, который позволяет настраиваться под любые задачи. Для лендинга желательно выставить такие настройки (см. _variables.scss), чтобы отключить генерацию лишнего css-кода. Например нет сысла генерировать все цвета, отступы, размеры и т.п. Обычно я беру _variables-minimal.scssи постепенно в процессе вёрстки добавляю нужный код. Такой подход позволяет сократить полные 120Кб до 50Кб.

CSS-файлы загружаются как lazy. Основной файл, который по умолчанию style.scssя переименовываю как -lazy.scss. LPF понимает, что его нужно подключить в конце BODY. В этом файле нужно размещать только самый основной css-код и нужно исключить подгрузку всех шрифтов, особенно сторонних. Браузер быстро скачивает этот файл и страница сразу приобретает нормальный вид.

Дополнительные локальные шрифты, например fontawesome, подключаются отдельным файлом. Сделано это из-за его довольно большого размера, но главное, что иконки не самый критичный элемент дизайна.

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

Последним загружается css-файл, содержащий остальной «второстепенный» код, например эффекты наведения, слайдеры и т.п. Такой файл должен быть один сборный.

В LPF каталог css/lazy/как раз используется для lazy-загрузки, поэтому достаточно просто разместить их в аналогичном каталоге (sass/lazy) для Sass-компилятора. Нигде ничего указывать не нужно — всё будет работать автоматом.

Оптимизация JS-файлов

В целом для js-файлов подход аналогичен CSS — используется тот же lazy-каталог. Первым делом следует подключить jQuery (1-jquery-min.js). Это достаточно большой файл, поэтому его лучше загрузить отдельно, причём самым первым.

Следующим файлом будет что-то вроде my.js, который представляет собой сборку всех используемых js-файлов (свой и код jQuery-плагинов). Для того, чтобы LPF выполнял работу по сборке и минификации кода, я написал простенькую функцию. При желании вы сможете её модифицировать под свою задачу.

Исходный js-код размещается в каталоге assets/js-add-lazy/. Результат помещается в assets/js/lazy/. Для js-файлов используйте префиксы (1,2...) для указания порядка размещения в итоговом файле. Свой js-код лучше размещать где-то в конце, поэтому файл может именоваться например assets/js-add-lazy/z-my.js.

Функцию сборки нужно разместить в lpf-content/config/functions.php— файл подключается в начале работы LPF.

my_js_to_one_file(); // собрать и сжать
function my_js_to_one_file($in_dir = 'js-add-lazy', $out_file = 'js/lazy/my.js')
{
    if ($js = mso_get_path_files(ASSETS_DIR . $in_dir, ASSETS_URL . $in_dir, false, array('js')))
    {
        $out = '';
        foreach($js as $f)
        {
            $text = mso_fr($f, ASSETS_DIR . $in_dir . '/', true);
            if ($text) 
            {
                $text = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $text);
                $text = str_replace(array("\r\n", "\r", "\n", "\t", '  ', '    ', '    '), '', $text);
                $out .= $text . "\n";
            }
        }
        
        if ($out)
        {
            $fp = fopen(ASSETS_DIR . '/' . $out_file, "w");
            fwrite($fp, $out);
            fclose($fp);
        }
    }
}

После сборки, когда работа с js завершена, вызов функции можно закомментировать.

Также обратите внимание, что сжатие кода довольно примитивное, поэтому не используйте вот такие «//» комментарии в js-коде — после сжатия он окажется нерабочим. Используйте «/* */».

В итоге весь js-код для страницы окажется в двух файлах: непосредственно jQuery и весь остальной код. Естественно в самом теле страницы никакого js-кода быть не должно.

Оставьте комментарий!

Комментарий будет опубликован после проверки. Вы соглашаетесь с правилами сайта.

(обязательно)