Photo by Patrick Konior
Отложенная загрузка CSS стилей

Отложенная загрузка некритичных CSS стилей в WordPress

17.08.23
7.07.24

Часто возникает необходимость ускорить загрузку сайта на базе CMS WordPress созданного какими-то сторонними разработчиками. Одной из необходимых задач будет отложенная загрузка некритичных CSS стилей, так как загрузка CSS блокирует отрисовку страницы браузером.

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

Как отложить загрузку CSS

Для обычной загрузки стилей используется тег типа:

<link rel="stylesheet" href="styles.css">

Для создания асинхронности загрузки есть несколько тегов. Лучше использовать:

rel="preload"

Обычный подход это прописать так:

<link rel="preload" href="styles.css" as="style">

На web.dev есть статья, где рекомендуют использовать js для замены rel после загрузки и обёртку <noscript> если браузер не поддерживает js. В этом случае код для отложенной загрузки CSS будет следующий:

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

Как сделать отложенную загрузку в WordPress без плагинов

За подключения стилей в WordPress отвечает функция wp_enqueue_style(). Код в functions.php выглядит так:

function add_my_styles() {
	wp_enqueue_style( 'main', get_stylesheet_directory_uri() . '/assets/css/main.min.css', array(), $ver = 0.10 );
}
add_action( 'wp_enqueue_scripts', 'add_my_styles', 25 );

Этот код добавит CSS в head ваших страниц. Для того чтобы сделать отложенную загрузку надо на хук style_loader_tag повесить обработчик:

function my_style_loader_tag_filter($html, $handle) {
	if ($handle === 'main') {
		$html_new = str_replace("rel='stylesheet'", "rel=\"preload\" as=\"style\" onload=\"this.onload=null;this.rel='stylesheet'\"", $html);
		$html_new = str_replace(" type='text/css' media='all'", "", $html_new);
		$html = $html_new . "<noscript>" . $html . "</noscript>";
	}
	return $html;
}
add_filter('style_loader_tag', 'my_style_loader_tag_filter', 10, 2);