Я пытаюсь удалить 2 файла CSS, которые блокируют рендеринг на моем сайте - они отображаются в Google Page Speed Insights. Я использовал разные методы, ни один из которых не увенчался успехом. Но недавно я нашел сообщение о Thinking Async, и когда я применил этот код: <script async src="https://third-party.com/resource.js"></script>
он устранил проблему.
Однако после публикации страница потеряла стиль. Я не совсем уверен в том, что происходит, потому что код работает, но стиль после загрузки не работает. Был бы признателен за вашу помощь в этом. Благодарность
html
css
asynchronous
Паулина994
источник
источник
Ответы:
Уловка для запуска асинхронной загрузки таблицы стилей заключается в использовании
<link>
элемента и установке недопустимого значения для атрибута media (я использую media = "none", но подойдет любое значение). Когда медиа-запрос оценивается как ложный, браузер все равно загрузит таблицу стилей, но не будет ждать, пока контент станет доступным, прежде чем отобразить страницу.<link rel="stylesheet" href="css.css" media="none">
После завершения загрузки таблицы стилей атрибут мультимедиа должен иметь допустимое значение, чтобы правила стиля были применены к документу. Событие onload используется для переключения свойства media на all:
<link rel="stylesheet" href="css.css" media="none" onload="if(media!='all')media='all'">
Этот метод загрузки CSS предоставит посетителям полезный контент намного быстрее, чем стандартный подход. Критический CSS можно по-прежнему обслуживать с помощью обычного подхода блокировки (или вы можете встроить его для максимальной производительности), а некритические стили можно постепенно загружать и применять позже в процессе синтаксического анализа / рендеринга.
В этом методе используется JavaScript, но вы можете обслуживать браузеры, не поддерживающие JavaScript, путем обертывания эквивалентных блокирующих
<link>
элементов в<noscript>
элемент:<link rel="stylesheet" href="css.css" media="none" onload="if(media!='all')media='all'"><noscript><link rel="stylesheet" href="css.css"></noscript>
Вы можете увидеть операцию на www.itcha.edu.sv
Источник в http://keithclark.co.uk/
источник
preload
Firefox и старых браузеров - см. Ссылку в первом комментарии к этому ответу].Обновление 2020
Простой ответ (полная поддержка браузера):
<link rel="stylesheet" href="style.css" media="print" onload="this.media='all'">
Документированный ответ (с необязательной предварительной загрузкой и резервным вариантом с отключенным скриптом):
<!-- Optional, if we want the stylesheet to get preloaded. Note that this line causes stylesheet to get downloaded, but not applied to the page. Use strategically — while preloading will push this resource up the priority list, it may cause more important resources to be pushed down the priority list. This may not be the desired effect for non-critical CSS, depending on other resources your app needs. --> <link rel="preload" href="style.css" as="style"> <!-- Media type (print) doesn't match the current environment, so browser decides it's not that important and loads the stylesheet asynchronously (without delaying page rendering). On load, we change media type so that the stylesheet gets applied to screens. --> <link rel="stylesheet" href="style.css" media="print" onload="this.media='all'"> <!-- Fallback that only gets inserted when JavaScript is disabled, in which case we can't load CSS asynchronously. --> <noscript><link rel="stylesheet" href="style.css"></noscript>
Сочетание предварительной загрузки и асинхронности:
Если вам нужен предварительно загруженный и асинхронный CSS, это решение просто объединяет две строки из задокументированного ответа выше, делая его немного чище. Но это не будет работать в Firefox, пока они не поддержат ключевое слово preload . И снова, как подробно описано в задокументированном ответе выше, предварительная загрузка на самом деле может не принести пользу.
<link href="style.css" rel="preload" as="style" onload="this.rel='stylesheet'"> <noscript><link rel="stylesheet" href="style.css"></noscript>
Дополнительные соображения:
Обратите внимание, что в целом, если вы собираетесь загружать CSS асинхронно, обычно рекомендуется встраивать критический CSS , поскольку CSS не зря является ресурсом, блокирующим рендеринг .
Благодарим filament group за их многочисленные асинхронные CSS-решения.
источник
onload="this.rel='stylesheet'; this.onload = null"
. Очевидно, необходимо установить,this.onload
чтобыnull
избежать этого дважды в некоторых браузерах.Использование
media="print"
иonload
Группа filament недавно (июль 2019 г.) опубликовала статью с последними рекомендациями по асинхронной загрузке CSS. Несмотря на то, что они являются разработчиками популярной библиотеки JavaScript loadCSS , они на самом деле рекомендуют это решение, для которого не требуется библиотека Javascript:
<link rel="stylesheet" href="/path/to/my.css" media="print" onload="this.media='all'; this.onload = null" >
Использование
media="print"
укажет браузеру использовать эту таблицу стилей не на экранах, а на печати. Браузеры действительно загружают эти таблицы стилей печати, но асинхронно, что нам и нужно. Мы также хотим, чтобы таблица стилей использовалась после загрузки, и для этого мы установилиonload="this.media='all'; this.onload = null"
. (Некоторые браузеры будут вызыватьonload
дважды, чтобы обойти это, нам нужно установитьthis.onload = null
.) Если хотите, вы можете добавить<noscript>
резервный вариант для тех редких пользователей, у которых не включен Javascript.Оригинал статьи стоит читать, как она идет более подробно , чем я здесь. Эту статью на csswizardry.com тоже стоит прочитать.
источник
вы можете попытаться получить это разными способами:
1. С помощью
media="bogus"
и<link>
у ног<head> <!-- unimportant nonsense --> <link rel="stylesheet" href="style.css" media="bogus"> </head> <body> <!-- other unimportant nonsense, such as content --> <link rel="stylesheet" href="style.css"> </body>
2. Вставка DOM старым способом
<script type="text/javascript"> (function(){ var bsa = document.createElement('script'); bsa.type = 'text/javascript'; bsa.async = true; bsa.src = 'https://s3.buysellads.com/ac/bsa.js'; (document.getElementsByTagName('head')[0]||document.getElementsByTagName('body')[0]).appendChild(bsa); })(); </script>
3. если вы можете попробовать плагины, вы можете попробовать loadCSS
<script> // include loadCSS here... function loadCSS( href, before, media ){ ... } // load a file loadCSS( "path/to/mystylesheet.css" ); </script>
источник
<script>
на<style rel=stylesheet>
? (Просто любопытно. Я буду использоватьloadCSS
(например, ваш пример 3) вместо этого, если мне понадобится загрузить CSS позже.)Функция ниже создаст и добавит в документ все таблицы стилей, которые вы хотите загрузить асинхронно. (Но, благодаря
Event Listener
, это произойдет только после загрузки всех других ресурсов окна.)См. Следующее:
function loadAsyncStyleSheets() { var asyncStyleSheets = [ '/stylesheets/async-stylesheet-1.css', '/stylesheets/async-stylesheet-2.css' ]; for (var i = 0; i < asyncStyleSheets.length; i++) { var link = document.createElement('link'); link.setAttribute('rel', 'stylesheet'); link.setAttribute('href', asyncStyleSheets[i]); document.head.appendChild(link); } } window.addEventListener('load', loadAsyncStyleSheets, false);
источник
var newStyle = document.createElement("link"); newStyle.rel = "stylesheet"; newStyle.href = "stylesheet.css"; document.getElementsByTagName("head")[0].appendChild(newStyle);
внутри<script>
тега в теле страницы отлично справляется со своей работой - даже в старых браузерах вроде MSIE8.window.load
событию. Итак, загрузка начинается, когда все загружено. Не повезло. Вам нужна неблокирующая загрузка как можно скорее, чтобы начать.Подходы к асинхронной загрузке CSS
Есть несколько способов заставить браузер загружать CSS асинхронно, но ни один из них не настолько прост, как вы могли ожидать.
<link rel="preload" href="mystyles.css" as="style" onload="this.rel='stylesheet'">
источник
Если вам нужно программно и асинхронно загрузить ссылку CSS:
// https://www.filamentgroup.com/lab/load-css-simpler/ function loadCSS(href, position) { const link = document.createElement('link'); link.media = 'print'; link.rel = 'stylesheet'; link.href = href; link.onload = () => { link.media = 'all'; }; position.parentNode.insertBefore(link, position); }
источник
Если у вас есть строгая политика защиты контента , которая не позволяет @ владимир-Салгуэро «s ответ , вы можете использовать это (пожалуйста , обратите внимание на сценарий
nonce
):<script nonce="(your nonce)" async> $(document).ready(function() { $('link[media="none"]').each(function(a, t) { var n = $(this).attr("data-async"), i = $(this); void 0 !== n && !1 !== n && ("true" == n || n) && i.attr("media", "all") }) }); </script>
Просто добавьте следующие строки в качестве ссылки таблицы стилей:
media="none" data-async="true"
. Вот пример:<link rel="stylesheet" href="../path/script.js" media="none" data-async="true" />
Пример для jQuery:
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css" type="text/css" media="none" data-async="true" crossorigin="anonymous" /><noscript><link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css" type="text/css" /></noscript>
источник
async
атрибут игнорируется, поскольку тег скрипта не долженsrc
загружаться асинхронно ... или он действительно полезен здесь? Также не могли бы вы подробнее рассказать, какое значение использовать в качествеnonce
?Пожалуйста, обновите ответ, так как все вышеперечисленное не дает впечатления от аналитики Google Pagespeed.
Согласно Google, вот как вы должны реализовать асинхронную загрузку Css
< noscript id="deferred-styles" > < link rel="stylesheet" type="text/css" href="small.css"/ > < /noscript > <script> var loadDeferredStyles = function() { var addStylesNode = document.getElementById("deferred-styles"); var replacement = document.createElement("div"); replacement.innerHTML = addStylesNode.textContent; document.body.appendChild(replacement) addStylesNode.parentElement.removeChild(addStylesNode); }; var raf = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame; if (raf) raf(function() { window.setTimeout(loadDeferredStyles, 0); }); else window.addEventListener('load', loadDeferredStyles); </script>
источник
Я пытаюсь использовать:
<link rel="preload stylesheet" href="mystyles.css" as="style">
Он отлично работает, но также увеличивает совокупный сдвиг макета, потому что, когда мы используем rel = "preload", он просто загружает css, а не применяется немедленно.
Пример, когда DOM загружает список, содержащий теги ul, li, по умолчанию перед тегами li есть маркеры, затем применен CSS, чтобы я удалил эти маркеры в пользовательские стили для листинга. Так что здесь происходит кумулятивный сдвиг макета.
Есть ли решение для этого?
источник
Используйте,
rel="preload"
чтобы заставить его загружаться независимо, затем используйте,onload="this.rel='stylesheet'"
чтобы применить его к таблице стилей (as="style"
необходимо применить его к таблице стилей, иначе этоonload
не сработает)<link rel="preload" as="style" type="text/css" href="mystyles.css" onload="this.rel='stylesheet'">
источник