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

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

От автора: как произвести асинхронную загрузку файлов CSS без использования JS. Использование атрибута media и веб-стандарта preload — об этом в статье.

Самый простой способ загрузить CSS файл в HTML – сделать это через тег link и rel=»stylesheet»:

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

Чтобы некритичные CSS файлы не блокировали рендер страницы, их нужно загружать асинхронно.

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

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

Один из способов (работает в современных браузерах) – с помощью JS создавать и вставлять ссылки на стили в DOM:

Последняя строка великолепна!

Еще один способ – установить атрибут media в теге link в медиа тип (или запрос), который не совпадает с браузером пользователя. Например, media=»print» или вообще что-то нераспознаваемое типа media=»nope!». Стили неприменимых медиа браузеры ставят в низший приоритет и загружают их, не блокируя рендер страницы. Хорошо, но чтобы отобразить их после загрузки, нам необходимо с помощью JS обработчика события onload менять значение media на значение, совпадающее с браузером пользователя, например, screen или all:

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

Как и в методе переключения медиа, мы можем асинхронно загружать CSS, если пометим link, как alternate стили (предлагают альтернативные представления сайта), и затем с помощью JS переключим атрибут rel обратно в stylesheet после загрузки файла:

Методы выше работают, но у них у всех есть недостаток – все они используют JS (не говоря уже, что нужно знать нюансы поведения браузеров), достигая желаемого эффекта не прямым способом…

Современный подход

К счастью, сейчас есть веб-стандарт, спроектированный специально для асинхронной загрузки ресурсов типа CSS — rel=»preload». Наконец-то мы можем асинхронно загружать CSS без JS! Шучу. Может, это вас удивит, но даже этот метод использует обработчик события onload. Но это наш лучший вариант.

Пример асинхронной загрузки и применения CSS через rel=»preload» (в браузере с поддержкой):

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

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

Поддержка браузерами rel=»preload» составляет… ну, в общем, хотя бы Chrome поддерживает. Другие основные браузеры тоже в скором времени будут поддерживать это значение. В Firefox 56 уже есть поддержка, но там очень много багов (preload работает только для файлов, которые явно считаются кэшируемыми), поэтому в Firefox 57 эту функцию отключили (поддержка вернется в Firefox 59).

К счастью, мы можем протестировать это значение и использовать полифилы для работы rel=»preload» во всех браузерах. Наш проект loadCSS предлагает скрипт cssrelpreload.js, который включает поддержку rel=»preload» для CSS файлов в браузерах, в которых нет родной поддержки (скрипт ничего не делает, если браузер знает значение preload).

Можете найти пошаговую инструкцию использования для cssrelpreload.js в readme проекта. Если вы подключите скрипт к страницы инлайново (или через server-push), это автоматически заставит работать элементы link[rel=»preload»] в браузерах без поддержки. Пример использования, в том числе и фолбек noscript на всякий случай:

Заметка: если вы уже работали с cssrelpreload.js ,то в последней версии 2.0.1 есть пара улучшений, и библиотека больше не зависит от скрипта loadCSS.js. Поэтому можете больше не подключать этот файл и сэкономить пару килобайт.

Как и любой open source проект, вы можете найти loadCSS на Github и на NPM. Если у вас возникли проблемы, есть вопросы или комментарии, пишите в issue tracker. Благодарю!

Автор: Scott

Источник: //www.filamentgroup.com/

Редакция: Команда webformyself.

Метки:

Похожие статьи:

Комментарии Вконтакте: