Оптимизация скорости загрузки скриптов и стилей через стратегии async & defer в WordPress

async & defer – это очень полезные механики, которые позволяют существенно ускорить загрузку страниц, скриптов и стилей. Рассмотрим новые интерфейсы для внедрения этих стратегий в WordPress & WooCommerce.

Простые решения перед тем как идти в детали

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

Для новичков есть простые правила:

  • выбираем грамотные и проверенные темы – где большая часть проблем уже решена
  • ставим плагины типа WP Rocket (все в одном) или комбинации типа WP Super Cache + Autoptimize
  • можно иногда правильно настроить CloudFlare или аналоги – которые позволяет сильно ускорять отдачу сайта и TTFB (нужно почти всегда для международных сайтов и для SEO ориентированны)

Проверяем через Google PageSpeed или через установку плагина SiteKit для WordPress – который позволяет видеть результаты по ходу работы с сайтом.

Если все сделано правильно – скорость сайта становится максимально высокой.

Если нет – читаем далее и готовимся к приключениям или заказываем консультацию.

Как делали раньше

Для предыдущего/существующего использования функций wp_register_script() и wp_enqueue_script(), использующих булев параметр $in_footer, обратная совместимость сохраняется с помощью логики, которая явно задает группу скриптов для применимого значения вывода в подвале или заголовке на основе булевого значения, переданного в новый/перегруженный параметр $args.

Описание метода wp_script_add_data есть тут https://developer.wordpress.org/reference/functions/wp_script_add_data/

Это было примерно так:

add_action( 'wp_enqueue_scripts', function(){
    wp_enqueue_script( 'wpdemo-respond', get_template_directory_uri().'/js/respond.min.js' );
    wp_script_add_data( 'wpdemo-respond', 'conditional', 'lt IE 9' );
 
    wp_enqueue_script( 'wpdemo-html5shiv',get_template_directory_uri().'/js/html5shiv.js');
    wp_script_add_data( 'wpdemo-html5shiv', 'defer', true );
});

//add support for async and defer params
add_filter( 'script_loader_tag', function($tag, $handle){
    if ( wp_scripts()->get_data( $handle, 'defer' ) ) {
        $tag = str_replace( '></', ' defer></', $tag );
    }
    if ( wp_scripts()->get_data( $handle, 'async' ) ) {
        $tag = str_replace( '></', ' async></', $tag );
    }
    return $tag;
}, 10, 2 );

Можно посмотреть как внедряют async & defer в теме для WordPress TwentyTwenty https://github.com/WordPress/twentytwenty/pull/30/files

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

Начиная с версии WP 6.3 доступные дополнительные опции указания стратегии загрузки скриптов

  • Асинхронные скрипты – Скрипты, помеченные для асинхронного выполнения с помощью атрибута async, выполняются сразу после их загрузки браузером. Асинхронные скрипты не имеют гарантированного порядка выполнения, так как скрипт B (хотя добавлен в DOM после скрипта A) может выполниться первым, поскольку он может завершить загрузку раньше скрипта A. Такие скрипты могут выполняться как до полной конструкции DOM, так и после события DOMContentLoaded.
  • Отложенные скрипты – Скрипты, помеченные для отложенного выполнения с помощью атрибута defer, выполняются только после полной загрузки дерева DOM (но до событий DOMContentLoaded и window load). Отложенные скрипты выполняются в том же порядке, в котором они были добавлены в DOM, в отличие от асинхронных скриптов.

пример

wp_register_script( 
    'foo', 
    '/path/to/foo.js', 
    array(), 
    '1.0.0', 
    array(
        'strategy' => 'defer'
    ) 
);

Асинхронная загрузка стилей

Тут мы разберемся как отложить некритичный CSS с целью оптимизации критического пути рендеринга (Critical Rendering Path, CRP) и улучшения первой контентной отрисовки (First Contentful Paint, FCP).

Во первых это опасная практика и каких то простых решений тут нет. Можно наломать дров без подготовки.

Во вторых – перед тем как сюда погружаться – надо изучить что такое Critical CSS и как его готовить https://web.dev/articles/extract-critical-css

Ряд плагинов для WP это умеют – типа Autoptimize & Rocket.

Как это работает с учетом рекомендаций Google

Детально тут https://web.dev/articles/defer-non-critical-css

Критический CSS должен загружаться как тег style

Например:

<style type="text/css">
.accordion-btn {background-color: #ADD8E6;color: #444;cursor: pointer;padding: 18px;width: 100%;border: none;text-align: left;outline: none;font-size: 15px;transition: 0.4s;}.container {padding: 0 18px;display: none;background-color: white;overflow: hidden;}h1 {word-spacing: 5px;color: blue;font-weight: bold;text-align: center;}
</style>

Не критические стили грузятся как файлы по другой схеме

  • link rel="preload" as="style" запрашивает таблицу стилей асинхронно. Дополнительную информацию о предварительной загрузке можно найти в руководстве Preload critical assets guide.
  • Атрибут onload в теоге link позволяет обрабатывать CSS после завершения загрузки.

Пример

<link rel="preload" href="styles.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="styles.css"></noscript>

Как уже сказано выше – многие плагины оптимизации для WP это умеют делать автоматически.

Пример аналогичного решения для шрифтов

function enqueue_font_preload() {
	wp_enqueue_style('example-font-handle', 'https://domain.com/wp-content/font-file.woff2', array(), null);
}
add_action('wp_enqueue_scripts', 'enqueue_font_preload');
function style_loader_tag_filter_preload($html, $handle) {
	if($handle === 'example-font-handle') {
		$new_html = str_replace("text/css", "font/woff2", $html);
		return str_replace("rel='stylesheet'", "rel='preload' as='font' crossorigin='anonymous'", $new_html);
	}
	return $html;
}
add_filter('style_loader_tag', 'style_loader_tag_filter_preload', 10, 2);

Источники

Фото аватара
Anatolii I

Веб разработчик, специализация на лучших мировых практиках: WordPress, WooCommerce, NextJS, Strapi, JAMStack ...

Основные типы проектов: CMS, eCommerce, SEO, LMS, ECM, BPM

Подробнее...

Статей: 108

Ответить

Ваш адрес email не будет опубликован. Обязательные поля помечены *