Оптимизация и ускорение загрузки страницы категории сайта yablukom.ua (WordPress) часть 2

Sorry, this entry is only available in Russian.

Продолжение статьи “Оптимизация и ускорение загрузки страницы категории сайта yablukom.ua (WordPress)”.

Продолжим, для тех, кто желает больше технических деталей…

Далее будем убирать ненужные загрузки скриптов\стилей с этой страницы, перемещать нужные в футер…
Вот так выглядит хедер сейчас…

Так выглядит header до оптимизации

А вот так он должен и будет выглядеть в идеале:

Так будет выглядеть header после оптимизации

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

В этой части я займусь переносом максимального количества нужных на данной странице JavaScript-библиотек и CSS стилей из хедера в футер, а также попробуем отложить загрузку внешних скриптов Google Tag Manager (GTM), Binotel, Jivosite на несколько секунд после полной загрузки – будет новый плагин.

Плагин «Настройки места и времени вывода GTM, Binotel, Jivosite и др.»

Для начала нужно избавится от внешних скриптов GTM, Binotel, Jivosite в хедере. Кроме того, что они загружаются в хедере, так они еще и грузятся с внешних серверов, что еще больше усугубляет ситуацию.

Скрипты GTM GA Binotel Jivosite в хедере

Для оперативного управления порядком загрузки всех этих внешних сервисов (скриптами), был написан встроенный в тему плагин «Настройки места и времени вывода GTM, Binotel, Jivosite и др.» (его не видно в списке плагинов поскольку в случае его отключения сайт будет работать с ошибками).

Написание данного плагина было обусловлено еще и тем, что заказчик пожелал посмотреть на промежуточный результат оптимизации на реальном сайте (т.е. что-бы была возможность включить либо отключить оптимизацию).
Настройки плагина находятся в подпункте «Настройки GTM» пункта «Настройки» главного меню административной панели WordPress.
Данный плагин позволяет оперативно перемещать подключение этих внешних скриптов в разные места сайта, в том числе и так как было до оптимизации, без правки шаблонов темы.
По специфике темы, предусмотрено 5 мест подключения:
– конец блока head;
– начало блока body;
footer, блок для не зарегистрированных пользователей;
footer, блок для всех пользователей;
footer, блок с задержкой.
Также для блока с задержкой, предусмотрено настройку этой самой задержки. Ее величину необходимо подобрать так, чтобы загрузка этих внешних скриптов не попадала в тест Pagespeed.

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

Настройка плагина для максимального ускорения

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

Настройка чтобы вернуться к старым показателям

Приводить весь код плагина здесь не буду, ввиду его громоздкости.
Все настройки хранятся в базе данных, в опциях темы в массиве an_gtm_options и доступны посредством стандартной функции WordPressget_option(‘an_gtm_options’).
В нужных местах файлов wp-content\themes\yablukom\header.php и wp-content\themes\yablukom\footer.php были установлены хуки, на которые повешены соответствующие функции, например для вывода в конец блока head:

function an_place_end_head_echo(){
  global $an_place_output;
  echo $an_place_output['an_place_end_head'];
}

Для вывода с задержкой:

function block_with_delay_echo(){
  global $an_place_output;
  global $an_gtm_options;
  echo '<script>';
  echo 'setTimeout(function() {';
  echo $an_place_output['block_with_delay'] . ';';
  echo '}, ' . $an_gtm_options['an_delay_block'] . ');';
  echo '</script>';
}

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

Перемещение остальных JavaScript

На скриншоте видно, что в хедере еще присутствуют лишние скрипты…

JavaScript еще присутствуют в хедере

Следующий код перебирает все зарегистрированные скрипты по их алиасам и если алиас совпадает с одним из массива:

$array_to_footer = array(
  'masktelinput',  // wp-content/themes/yablukom/js/inputmask.min.js
  'abwc-ajax-js',  // wp-content/plugins/ajaxified-cart-woocommerce/assets/js/abwc-ajax-cart.min.js
   'abwc-ajax-variation-js'); //wp-content/plugins/ajaxified-cart-woocommerce/assets/js/abwc-ajax-variation-cart.min.js

добавляет к этому скрипту параметр ‘group’ = 1 – footer. Тем самым подключение скрипта на странице перемещается в футер.

// Перемещаем нужные JS-скрипты ($array_to_footer)  в футер
function an_move_js_to_footer() {
    $array_to_footer = array('masktelinput','abwc-ajax-js', 'abwc-ajax-variation-js');
    foreach( wp_scripts()->registered as $script ) {
        if (in_array($script->handle, $array_to_footer, true)) {
            wp_script_add_data( $script->handle, 'group', 1 ); // 0 - header, 1 - footer
        }
    }
}
add_action( 'wp_enqueue_scripts', 'an_move_js_to_footer', 99 );

После этой операции наблюдаем, что в хедере осталось только 2 самых необходимых :
wp-includes/js/jquery/jquery.js
wp-content/plugins/an-acceleration/js/lazysizes.min.js

Лишние JavaScript переместились в футер

Остальные переместились в футер.

Перемещение подключения ненужных CSS

На скриншоте видно подключение большого числа файлов стилей в хедере :

Лишние CSS в header

Список «лишних» стилей в хедере:
Алиас  . . . . . . . . . . . . . . . . . . . . . . . . . .  . . .  файл стилей

'an-wc-variations-popup-style' // wp-content/plugins/an-wc-variations-popup/css/style.css
'font-awesome-tema' // wp-content/themes/yablukom/css/font-awesome.css
'font-awesome' // wp-content/plugins/load-more-products-for-woocommerce/berocket/assets/css/font-awesome.min.css
'wc-mini-cart-an' // plugins/wc-mini-cart-an/css/wc-mini-cart-an.css
'wp-postratings' // wp-content/plugins/wp-postratings/css/postratings-css.css
'wp-block-library' // wp-includes/css/dist/block-library/style.min.css
'wc-block-style' // wp-content/plugins/woocommerce/packages/woocommerce-blocks/build/style.css
'wpdreams-ajaxsearchlite' // wp-content/plugins/ajax-search-lite/css/style-underline.css

Загоняем их алиасы в массив $array_to_footer
По аналогии с JS-скриптами написал подобную функцию:

function an_move_css_to_footer() {
    $array_to_footer = array('wc-mini-cart-an','mystyle');
    foreach( wp_styles()->registered as $style ) {
        if (in_array($style->handle, $array_to_footer, true)) {
            wp_style_add_data( $style->handle, 'group', 1 ); // 0 - header, 1 - footer
        }
    }
}
add_action( 'wp_enqueue_scripts', 'an_move_css_to_footer', 99 );

Провозился целый день… но так и не удалось с ее помощью реализовать задуманное…
Поискал, порылся в классах WordPress… и оказалось, что для CSS атрибут ‘group’ пока не поддерживается …

Немного поискал, подумал… и придумал план В .
Загоняем нужные алиасы в массив $array_to_footer, запоминаем в своем глобальном массиве $arr_styles и удаляем их из глобального массива стилей WordPress функцией wp_deregister_style().

//переносим стили из массива $array_to_footer в глоб.массив $arr_styles и deregister их из очереди
function an_move_css_to_global() {
    $array_to_footer = array('an-wc-variations-popup-style','font-awesome-tema','font-awesome','wc-mini-cart-an','wp-postratings','wp-block-library','wc-block-style','wpdreams-ajaxsearchlite');
    global $arr_styles;
	$arr_styles = array();     
    foreach( wp_styles()->registered as $style ) {
        if (in_array($style->handle, $array_to_footer, true)) {
        	$arr_styles[] = array(
        		'handle' => $style->handle,
        		'src'    => $style->src
        	);
        }
    }
    foreach( $arr_styles as $style ) {
    	wp_deregister_style( $style['handle'] );
    }
}
add_action( 'wp_enqueue_scripts', 'an_move_css_to_global', 99 );

Затем, подключаем эти файлы стилей из нашего, ранее созданного глобального массива $arr_styles по хуку ‘wp_footer’ с помощью функции wp_print_styles().

//переносим стили из массива глоб.массив $arr_styles и выводим их в футере
function an_css_global_to_footer() {
	global $arr_styles;
    foreach( $arr_styles as $style ) {
    	wp_register_style( $style['handle'], $style['src'] );
    	wp_print_styles( $style['handle'] );
    }	
}
add_action( 'wp_footer', 'an_css_global_to_footer' );

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

Лишние CSS ушли в footer

Все доработки собраны в один плагин An_Acceleration for WordPress.
Плагин An_Acceleration for WordPress
Если деактивировать этот плагин и перенастроить по-старому встроенный в тему плагин «Настройки места и времени вывода GTM, Binotel, Jivosite и др.», то все доработки будут отключены и показатели Pagespeed Insights вернуться к прежним значениям.

В результате данной работы получили следующие результаты:
Вот так выглядел хедер страницы категории до:

Так выглядит header до оптимизации

А вот так он выглядит после выполнения этого этапа:

Так будет выглядеть header после оптимизации

Для проверки результатов оптимизации, а также проверки правильности функционирования  как страницы категории так и сайта в целом, я установил все эти обновления на тестовый сайт https://test-yablukom.eurolighting-technology.com.ua

Тестировалась страница https://test-yablukom.eurolighting-technology.com.ua/semena-podsolnechnika/

Ну и вот результаты Pagespeed Insights:

До оптимизации Pagespeed

До оптимизации Pagespeed блок 1

После оптимизации Pagespeed

После оптимизации Pagespeed блок 1

До оптимизации рекомендации Pagespeed

До оптимизации Pagespeed блок 2

После оптимизации рекомендации Pagespeed

После оптимизации Pagespeed блок 2

До оптимизации успешные аудиты Pagespeed

До оптимизации Pagespeed блок 3

После оптимизации успешные аудиты Pagespeed

После оптимизации Pagespeed блок 3

Для удобства сделал таблицу сравнения основных показателей:

Показатель для мобильных

До оптимизации

После оптимизации

Улучшение %

Pagespeed (среднее из 5 тестов)

9

35

388

Запросов

112

69

162

Размер страницы

3 415 КБ

699 КБ

488

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

5,8 сек.

2,5 сек.

232

Индекс скорости загрузки

14,7 сек.

12,5 сек.

118

Отрисовка крупного контента

7,7 сек.

3,8 сек.

202

Время загрузки для взаимодействия

26,9 сек.

11,6 сек.

231

Общее время блокировки

4 050 мс

2 690 мс

150

Успешные аудиты

9

15

166

Хочу очередной раз заметить, что главная цифра Pagespeed Insights ( 9 -до оптимизации и 35 после) – это просто отвлеченная  цифра, которая плавает от измерения к измерению из-за сильной нагрузки на сайт (ее нужно стараться поймать максимальную)… А основным показателем успешной оптимизации является увеличение количества успешных аудитов. В данном случае мы решили проблемы 6-ти аудитов, переместив их из блока рекомендаций в блок “Успешные аудиты”.

Размер страницы сократился с 3415 КБ до 699 КБ (почти в 5 раз!!!), количество запросов к серверу с 112 до 69 (почти в 2 раза!!!), а это очень много для неоконченной оптимизации…

Остались конечно еще не решенные рекомендации Pagespeed Insights … Но заказчик решил, что пока хватит(бюджет)… и возможно потом мы ними и займемся…

Ну, а теперь вишенка на торте
Я решил проверить остальные страницы: главную и страницу товара…
И был приятно удивлен тестами… Впрочем судите сами:

Главная до оптимизации

Главная yablukom до оптимизации

Главная после оптимизации

Главная yablukom после оптимизации

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

Страница товара получилась конечно поскромнее, но тоже есть улучшение в 2+ раза… хоть ней совсем и не занимались… Но мы ней точно займемся в ближайшее время…

 

Страница товара до оптимизации

Страница товара до оптимизации

Страница товара после оптимизации

Страница товара после оптимизации

 

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

А вот и отзыв заказчика из Телеграмм:

Скриншот отзыва заказчика из Телеграмм