Асинхронная загрузка CSS для устранения блокировки отображения
Быстрый ответ
Для оптимизации производительности веб-страниц, рекомендуется использовать асинхронную загрузку CSS. Сначала следует встроить ваши критически важные стили напрямую в HTML, а затем воспользоваться тегом link
с атрибутом rel="preload"
для остальных CSS-стилей. После окончания загрузки этих стилей, атрибут media
заменяется с "print"
на "all"
с помощью обработчика событий onload
. Для обеспечения отображения стилей без JavaScript используйте элемент noscript
. Приведем пример такого подхода:
<style>/* Критические стили, встроенные непосредственно в HTML */</style>
<link rel="preload" href="async.css" as="style" onload="this.rel='stylesheet'; this.onload=null;" media="print">
<noscript><link rel="stylesheet" href="async.css"></noscript>
Асинхронная подгрузка с использованием атрибутов onload и media
Используя атрибут onload
для тега link
, можно подгружать CSS-файлы асинхронно, не препятствуя при этом процессу отрисовки страницы. Атрибут media
, установленный вначале в значение "print", предотвращает моментальное применение стилей. Он заменяется на "all" после того, как файл CSS полностью загружен.
<!-- Асинхронная подгрузка CSS-стилей -->
<link rel="stylesheet" href="async.css" media="print" onload="this.media='all';this.onload=null;">
Таким образом, страница остается отзывчивой во время загрузки стилей.
Принцип прогрессивного улучшения пользовательского опыта
Согласно принципам прогрессивного улучшения, первоначально предоставьте пользователю основной контент, а затем асинхронно загрузите дополнительные стили. Вам поможет JavaScript, который позволяет добавить элементы link
после полной загрузки страницы. Это исключит моментальное появление недооформленного контента и улучшит особенности взаимодействия.
Пример кода, добавляющего CSS после события загрузки окна:
// Асинхронная подгрузка CSS-стилей после загрузки страницы
window.addEventListener('load', function() {
var link = document.createElement('link');
link.rel = 'stylesheet';
link.href = 'async.css';
document.head.appendChild(link);
});
Визуализация
Можно представить асинхронную загрузку CSS как автодорогу с выделенными полосами:
🛣️ Синхронная загрузка: Все "машины" (стили CSS) поступают через одни ворота, вызывая "пробку" 🚗🚕🚙
🚦==========🚧===🌐 Остановка отрисовки страницы из-за CSS!
🛣️ Дорога с выделенными полосами (Асинхронная загрузка): "Автомобили" (CSS-стили) движутся по отдельным полосам, не затрудняя движение по основной дороге 🚗🚕🚙
🚀======🌐 CSS не мешает начальной отрисовке страницы!
Постарайтесь создавать "выделенные полосы" на ваших сайтах, чтобы избегать заторов при загрузке.
Управление ресурсами и повышение производительности
Важно найти баланс между повышением производительности и оптимизацией ресурсов. Комбинирование rel="preload"
с асинхронными методами загрузки будет эффективным, если использовать его обдуманно. Для предварительной загрузки стилей, которые влияют на первичное отображение страницы, используйте стратегический подход.
Не забывайте о возможных сложностях при предзагрузке – большие файлы CSS могут ненароком замедлять загрузку остальных ресурсов. Настройте стратегию оптимизации так, чтобы она позволяла разделить и минимизировать CSS-файлы, оставляя необходимый минимум в каждом из них.
Доступность и надежность асинхронной загрузки
При асинхронной подгрузке CSS удостоверьтесь, что ваш сайт остается доступен для всех пользователей. Используйте элемент noscript
, чтобы те, кто отключил JavaScript, также могли видеть стилизованный контент.
<!-- Альтернатива CSS для пользователей с отключённым JavaScript -->
<noscript><link rel="stylesheet" href="async.css"></noscript>
Следите также за тем, чтобы ваш метод асинхронной загрузки не конфликтовал со Стратегиями безопасной отправки контента (CSP).
Асинхронная загрузка нескольких CSS файлов
Для асинхронной подгрузки нескольких CSS-файлов, используйте цикл в JavaScript в сочетании с вышеописанными методами. Это сделает стили неблокирующими и улучшит производительность страниц.
Пример подгрузки нескольких CSS-файлов асинхронно:
// Загружаем несколько CSS файлов асинхронно
var cssFiles = ['async1.css', 'async2.css', 'async3.css'];
cssFiles.forEach(function(cssFile) {
var link = document.createElement('link');
link.rel = 'stylesheet';
link.href = cssFile;
link.media = 'print';
link.onload = function() { this.media='all'; };
document.head.appendChild(link);
});
Полезные материалы
Глубже понять техники асинхронной загрузки CSS можно, изучив публикации Filament Group, посетив сайт csswizardry.com за советами по оптимизации веб-типографики или изучив подходы Кейта Кларка к неблокирующей загрузке CSS.
- rel=preload – HTML: HyperText Markup Language | MDN — как
rel=preload
может ускорить ваш сайт. - Deferred loading of non-critical CSS | web.dev — анализ отложенной загрузки некритически важных стилей для улучшения времени загрузки страниц.
- GitHub – filamentgroup/loadCSS: A function for loading CSS asynchronously — практическое руководство по асинхронной загрузке CSS.
- async vs defer attributes – Growing with the Web — понимание атрибутов
async
иdefer
для скриптов. - Understanding Critical CSS — Smashing Magazine — влияние критического CSS на производительность отрисовки.
- Using media queries – CSS: Cascading Style Sheets | MDN — использование медиа-запросов CSS для адаптивного дизайна.
- PageSpeed Insights — инструмент для оценки производительности веб-страницы после оптимизации.