Современная асинхронная загрузка CSS

Самый простой способ загрузить CSS в HTML-документ заключается в использовании тега link и атрибута rel=»stylesheet»:

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

Но есть и обратная сторона медали: это происходит синхронно. Другими словами, браузер останавливает рендеринг остальных частей страницы в процессе запроса, загрузки и парсинга файла. Это необходимо, чтобы браузер не начал отображать содержимое веб-страницы до того, как загрузится CSS. Но не все стили настолько критичны, чтобы задерживать доступ к контенту. Для этого необходимо загружать некритичные CSS файлы асинхронно, без блокировки рендеринга страницы.

Способы асинхронной загрузки CSS

Существует несколько способов заставить браузер загружать CSS асинхронно.

Первый способ (работает в современных браузерах) заключается в использовании JavaScript для создания и вставки ссылки на файл CSS в DOM:

// Создаем ссылку на таблицу стилей
var myCSS = document.createElement( "link" );
myCSS.rel = "stylesheet";
myCSS.href = "mystyles.css";
// вставляем ее в конце блока head
document.head.insertBefore( myCSS, document.head.childNodes[ document.head.childNodes.length - 1 ].nextSibling );

Второй способ заключается в том, чтобы задать  атрибуту media в теге link значение, которое не соответствует устройству пользователя. Например, media=»print».

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

Но чтобы задействовать асинхронно загруженные стили, нужно использовать JavaScript-обработчик события onload. Это позволит изменить значение media на соответствующее браузеру и устройству пользователя. Например, screen или all:

<link rel="stylesheet" href="mystyles.css" media="nope!" onload="this.media='all'">

Примечание: мы используем комбинацию перечисленных выше приемов в библиотеке loadCSS.js, предназначенной для обработки асинхронной загрузки CSS. А также обходные пути для устаревших версий браузеров, которые не поддерживают события onload в элементах link.

Также можно загружать CSS асинхронно, используя значение rel=»alternate stylesheet». Оно используется для того, чтобы предложить пользователю альтернативное представление сайта:

<link rel="alternate stylesheet" href="mystyles.css" onload="this.rel='stylesheet'">

Методы, описанные выше, работают. Но у них есть один общий недостаток: они используют JavaScript.

Современный метод

Существует решение, созданное специально для асинхронной загрузки CSS файлов: rel=»preload». Но даже этот вариант использует обработчик события onload.

Ниже приведен использования rel=»preload»:

<link rel="preload" href="mystyles.css" as="style" onload="this.rel='stylesheet'">

Значение атрибута rel=»preload» заставляет браузеры (которые его поддерживают) загружать, но не применять указанный файл. Поэтому необходим обработчик события onload, чтобы установить атрибут rel в значение stylesheet после загрузки.

Вариант с rel=»preload» имеет одно важное преимущество: браузеры начнут загружать CSS раньше, чем при использовании подхода с несоответствующим значением атрибута media.

Использование rel=preload c loadCSS

Поддержка rel=»preload» браузерами, ну… спасибо, что хотя бы Google Chrome его поддерживает. Другие популярные браузеры находятся на пути к этому.

Но мы можем обеспечить поддержку rel = ‘preload’ с помощью полифиллов.  Проект loadCSS предлагает скрипт cssrelpreload.js, который заставляет rel=»preload» работать в браузерах, которые не поддерживают его по умолчанию.

Пошаговое руководство по использованию cssrelpreload.js можно найти в readme проекта. Ниже приведен пример применения скрипта:

<link rel="preload" href="mystyles.css" as="style" onload="this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="path/to/mystylesheet.css"></noscript>
<script>
/*! loadCSS rel=preload polyfill. [c]2017 Filament Group, Inc. MIT License */ (function(){ ... }());
</script>

loadCSS можно найти на Github и NPM.

Пожалуйста, оставьте свои отзывы по текущей теме материала. За комментарии, подписки, дизлайки, отклики, лайки низкий вам поклон!

Пожалуйста, опубликуйте ваши мнения по текущей теме материала. Мы крайне благодарны вам за ваши комментарии, лайки, подписки, отклики, дизлайки!

Ангелина Писанюкавтор-переводчик статьи «Modern Asynchronous CSS Loading»