В современном интернете сайтов очень много, и, практически никогда, их не ищут имея прямой адрес, а находят в поисковиках. Ввиду этого, публичные сайты должны выбрасываться в верхних строках результатов поиска. Помимо релевантного запросу контента страницы и SEO, на это влияет время загрузки страницы. Именно его мы и будем сегодня уменьшать.
Содержание
- PageSpeed Insights
- Исходная точка
- Первая беда – “Устраните ресурсы, блокирующие отображение”
- Изврат с картинками
- Работаем с таблицами стилей
- Оптимизируем скрипты
PageSpeed Insights
Это один из многих анализаторов времени загрузки страницы. Анализатор(а не измеритель) потому, что он
оценивает время загрузки в своих “попугаях”(если об основной оценке).
Несмотря на это, этот инструмент является основным для проверки оптимизации сайта; как мне кажется – потому, что разработан Google`ом(ну и удобство – кратко и по делу, в многих альтернативных ресурсов наоборот – много, подробно и хз что с этим делать).
Исходная точка
Исходная точка – сайт моего блога(на котором ты это читаешь). Поставлена мною мне же задача – максимально быстрая загрузка страниц. Все мы с школьной физики знаем, что время перемещения это путь деленный на скорость.
С сайтами это эмпирическое правило сохраняется; с чего можно предположить 2 варианта: дабы уменьшить время загрузки – уменьшай контент страницы, либо же увеличивай скорость ее загрузки.
И здесь мое размышление(к делу не относящееся):
Принято говорить: “оптимизация страницы приводит к ускорению загрузки сайта”. Моя мысль: может ли руль изменить характеристики двигателя?..
Итак, к чему это? А не к чему! Если соблюдать терминологию(из мысли) то: двигатель это девайс пользователя(т.е. твой или сервера поисковика…), сайт – это, нет , не машина… это водитель! страница это машина. Что я хочу сказать – оптимизация сайта – это обучение водилы крутить баранку, проходить виражи с минимальной потерей времени. Да, главным двигателем здесь является сервер, на котором размещен сайт и который рендерит страницы – однако, в большинстве случаев, его оптимизировать мы не сможем.
Лады, перейдем к сути. На данный момент(перед началом оптимизации) я имею такие показатели:
Еще я забыл упомянуть – я буду ориентироваться на показатели для мобильных устройств. Объясню это следующим образом: производя поиск(даже если у пользователя ультра-супер-пупер ПК, мощности которого, все равно, не задействуются в поиске), первыми будут подняты те страницы, которые не только более соответствуют запросу, но и для поднятия которых требуется меньше ресурсов. К примеру, эта страница по показателям ПК имеет 77 попугаев(уже! без оптимизации!).
Чем крут PageSpeed еще – это объяснением, как оптимизировать. Вот мои проблемы
В принципе, это полный спектр проблем, которые может иметь сайт… а нет, вру! На одном сайте было “Сократите время ответа сервера”, поскольку к серверу никак притронуться я не мог – я переключил только версию PHP на 7.0(она дала наибольшее ускорение).
Я пошарился по странице(а именно в инструментах разработчика в хроме) и нашел основные тормоза. В первых, я использую библиотеку ace.js для раскрашивания кода, во-вторых – как и на многих сайтах, есть jquery; также, есть скрипты темы, скрипты для соцсетей и много стилей.
Первая беда – “Устраните ресурсы, блокирующие отображение”
Чтобы понять суть этой проблемы – нужно понять как браузер рендерит страницу: Этап 1 – загрузка HTML-разметки. Затем происходит парсинг и выстраивание DOM(Document Object Model); на этой стадии, каждый внешний файл вызывает блокировку процесса до момента полного его прочтения и осознания. Файлы JS блокируют выполнение во всех браузерах, CSS же(по словам разработчика Yahoo! – Stoyan Stefanov) не блокируют в серии IE браузеров, не блочат в Firefox.
Однако, перейдем к проблеме – открыв подробности о ней, виден совет:
Некоторые ресурсы блокируют первую отрисовку страницы. Рекомендуем встроить критическую часть данных JS/CSS в код HTML и отложить загрузку остальных ресурсов. Подробнее…
Скажу более того, здесь же и ссылка на плагины для WordPress, которыми можно оптимизировать этот(да и прочие) параметры. НО! Используя их, мне не удалось побороть эту проблему – по-этому я прибег к кодингу.
Начнем-ка! в начале,прежде чем что-то ломать, глянем на вкладку Coverage(если отсутствует – кликни по трем точкам у начала панели) в Google Crome DevTools
с целью увидеть, что используется из активов. С ходу увидим в каких файлах использование кода равно 0 – в колонке “Unused Bytes” показатель 100%. в. Здесь ты можешь предположить, что я буду их снимать с регистрации, да! – именно так я и поступлю! К примеру, у меня нулевой файл имеет такую ссылку /wp-content/plugins/contact-form-7/includes/css/styles.css
; находим стпоку в исходном коде страницы
<link rel='stylesheet' id='contact-form-7-css' href='/wp-content/plugins/contact-form-7/includes/css/styles.css?ver=5.4' media='all' />
id=’contact-form-7-css’, что значит слаг – ‘contact-form-7’ и тип файла стили. Это знание позволит мне снять этот файл с регистрации на нужной мне странице
add_action('wp_head', function () { remove_action('wp_head','wp_print_styles',8); remove_action('wp_head','wp_print_head_scripts',9); if(621 != $post->ID){ wp_deregister_style('contact-form-7'); wp_deregister_script('contact-form-7'); } wp_deregister_style('rate-my-post'); wp_deregister_style('twentyfifteen-style'); wp_deregister_style('twentyfifteen-fonts'); },1);
аналогично поступаю с прочими файлами. Также первыми 2-мя строками, перенесу подключение активов в подвал сайта.
Ну что – проверим результат?..
Результаты от сих действий ощутимы(меня они даже поразили!). Но не буду на этом останавливаться, продолжу развлечение…
Изврат с картинками
На деле здесь все просто – никакого извращения нет. По поводу современных форматов изображения, а именно .webp -дело в том, что не все браузеры его поддерживают. В связи с этим вместо такого тега для изображения
<img src="URL" alt="альтернативный текст">
для страниц с webp-картинками требуется такая структура
<picture> <source srcset="images/name.webp" type="image/webp"> <img src="images/name.jpg" alt="описание" /> </picture>
при этом браузеру предлагается вначале загрузить webp, если он его не понимает – грузит “старый” формат. С практики скажу данная модификация дает крайне малый прирост, по этому я сделал альтернативный способ – ленивая загрузка изображений. Суть в том, чтоб браузер, загружая страницу, получал ее без картинок; по мере необходимости изображения подгружаются на javascript – этот метод дал мне большой прирост к скорости – я им и воспользовался. Единственная проблема – индексация картинок поисковыми роботами и, соответственно, можно забыть о трафике через изображения – но я решил, что переживу эту утерю… Итак, о самой загрузке – как же я ее сделал? Мой сайт на вордпресс, я поставил плагин Autoptimize… шучу, мне снего всего одна функция нужна, ее добавить одна(4) строчка
add_filter( 'wp_get_attachment_image_attributes', function ( $attr ) { $attr['loading'] = 'lazy'; return $attr; } );
<img src="URL" alt="альтернативный текст">
так выглядит тег картинки без лени
<img src="URL" loading="lazy" alt="альтернативный текст">
а так с ней. Чтобы добавить lazy-loading достаточно прописать атрибут loading=”lazy”. Однако, опять же, не все браузеры ее поддерживают и иногда нужно ее имитировать на js.
Результат
Согласись, не плохо – уже вплотную я приблизился к зеленой зоне(90). Кста, еще я установил плагин WebP Express для нарезки картинок в современном формате. Единственное замечание – для получения профита нужно в настройках выбрать “Replace image URLs”(вместо замены тегов).
Работаем с таблицами стилей
Здесь я буду использовать пока что мало распространенный способ – динамическое подключение. Сперва отключим стили вовсе
remove_action( 'wp_footer', 'wp_print_footer_scripts', 20 );
при этом , также, отпадут скрипты(не беда). Следующим шагом – выведем в подвал скрипт, который после полной загрузки страницы вставит ссылки на таблицы стилей
<script> window.onload = function () { var footer = document.querySelector('footer'); footer.insertAdjacentHTML('beforeend', `<?php wp_print_styles() ?>`); } </script
window.onload вызывает функцию после загрузки и отрисовки страницы. На медленных машинах(или с медленным интернет-соединением) при этои будет посойное наложение стилей.
Оптимизируем скрипты
Результат, полученный мною, неплох – но недостаточен. Следующий шаг оптимизация скриптов. Первое, что я хочу сделать – подключать их асинхронно, т.е. параллельно прочим процессам. Чтоб это сделать нужно просто дописать атрибут async к тегу script
<script async="async" src='URL'></script>
вот как это выглядит в разметке, а вот как можно это сделать в коде для вордпресс
add_filter( 'script_loader_tag', function($tag, $handle){ return str_replace( ' src', ' async="async" src', $tag ); }, 10, 2 );
От единого этого действия мои показатели улучшились(я считаю значительно)
но на этом со скриптами еще не все.
Далее, я пойду таким же путем, как и со стилями. Тут тоже такое работает, однако реализация отлична. Дело в том, что закрывающийся скрипт-тег в строке, закрывает скрипт(по крайней мере в многострочной строке). В связи с этим, я записал пути в массив и, создавая тег, вставлял ссылки на скрипты
// заполнение переменной to_do $wp_scripts->all_deps( $wp_scripts->queue ); foreach ( $wp_scripts->to_do as $handle )://echo $handle.'-'.$wp_scripts->registered[ $handle ]->src.'<br>'; if ( ! empty( $wp_scripts->registered[ $handle ]->src ) ) { $scripts[] = $wp_scripts->registered[ $handle ]->src; } // вывод зависимого кода if ( $wp_scripts->registered[ $handle ]->extra ) { echo "n<script>n"; echo "/* <![CDATA[ */n"; // Not needed in HTML 5. echo $wp_scripts->registered[ $handle ]->extra['data']; echo "/* ]]> */n"; echo "</script>n"; } endforeach;
конвертирую все это в js
var scripts = '<?php echo json_encode( $scripts )?>', footer = document.querySelector('footer'); JSON.parse(scripts).forEach(function (src) { script = document.createElement('script'), script.src = src; script.async = false; footer.append(script); })
Все скрипты, кроме ace.js, нормально работают. Немного просмотревуказанный скрипт понял, что проблема с его инициализацией. немного переделав его и подключив его напрямую(в смысле без динамического тега), и он тоже заработал. Результат страницы составил
Не идеально, но все же! Можно еще минификацию активов сделать, но они итак минифицированы. Ну, да и ладно…