我正在尝试消除在我的网站上呈现阻止的2个CSS文件 - 它们出现在Google Page Speed Insights上。我遵循了不同的方法,但都没有成功。但是,最近,我发现了一篇关于Thinking Async的帖子,当我应用此代码时:<script async src="https://third-party.com/resource.js"></script>
它确实消除了这个问题。
然而,在发布后,该页面失去了样式。我不太确定会发生什么,因为代码可以工作但是上传后的样式不起作用。非常感谢您的帮助。感谢
答案 0 :(得分:94)
触发异步样式表下载的技巧是使用<link>
元素并为media属性设置无效值(我使用media =“none”,但任何值都可以)。当媒体查询评估为false时,浏览器仍会下载样式表,但在呈现页面之前不会等待内容可用。
<link rel="stylesheet" href="css.css" media="none">
样式表下载完成后,必须将media属性设置为有效值,以便将样式规则应用于文档。 onload事件用于将media属性切换为all:
<link rel="stylesheet" href="css.css" media="none" onload="if(media!='all')media='all'">
这种加载CSS的方法将比标准方法更快地向访问者提供可用内容。关键CSS仍然可以使用通常的阻塞方法(或者你可以内联它以获得最佳性能),非关键样式可以逐步下载并在解析/渲染过程中稍后应用。
此技术使用JavaScript,但您可以通过在<link>
元素中包含等效的阻止<noscript>
元素来满足非JavaScript浏览器:
<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
中查看操作 中的来源答案 1 :(得分:47)
现在,您可以将preload
keyword用于link
元素。
同步版本:
<link href="style.css" rel="stylesheet">
异步版本:
<link href="style.css" rel="preload" as="style">
此功能最近才成为现代浏览器中的widely supported。如果您需要旧版浏览器的后备广告,请使用loadCSS。
Firefox中默认禁用此功能。在Firefox实施解决方案之前,loadCSS(如上所述)可能是您最好的选择。以下评论取自this discussion:
我们决定采用不同的方法来实现rel = preload。我做 不知道什么时候会实施。
答案 2 :(得分:7)
你可以尝试以很多方式获得它:
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>
答案 3 :(得分:5)
下面的函数将创建并向文档添加您希望异步加载的所有样式表。 (但是,感谢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);
答案 4 :(得分:3)
media="print"
和onload="this.media='all'"
:The filament group recently (July 2019) published an article给出了有关如何异步加载CSS的最新建议。即使他们是流行的Javascript库loadCSS的开发者,他们实际上还是建议使用不需要Javascript库的解决方案:
<link rel="stylesheet" href="/path/to/my.css" media="print" onload="this.media='all'">
使用media="print"
将向浏览器指示不要在屏幕上使用此样式表,而应在打印时使用。浏览器实际上确实下载了这些打印样式表,但是异步地下载了,这正是我们想要的。我们还希望样式表一经下载即可使用,为此,我们设置了onload="this.media='all'"
。如果需要,可以为未启用Javascript的罕见用户添加<noscript>
后备广告。
original article值得一读,因为它比我在这里更详细。 This article on csswizardry.com也值得一读。
答案 5 :(得分:2)
<link rel="preload" href="mystyles.css" as="style" onload="this.rel='stylesheet'">
答案 6 :(得分:1)
如果您需要以编程方式和异步方式加载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);
}
答案 7 :(得分:0)
如果您有严格的内容安全政策但不允许@vladimir-salguero answer,则可以使用此政策(请注意脚本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>
答案 8 :(得分:0)
请谨慎更新答案,因为上述所有内容现在都无法打动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>
答案 9 :(得分:0)
我尝试使用:
<link rel="preload stylesheet" href="mystyles.css" as="style">
它可以正常工作,但是它也会引起布局的累积偏移,因为当我们使用rel =“ preload”时,它只是下载css,而不是立即应用。
例如,当DOM加载一个包含ul,li标签的列表时,默认情况下,li标签之前有一个项目符号,然后应用CSS,我将这些项目符号删除为自定义样式以列出。 因此,这里发生了累积布局偏移。
有什么解决办法吗?
答案 10 :(得分:0)
使用rel="preload"
使其独立下载,然后使用onload="this.rel='stylesheet'"
将其应用于样式表(将as="style"
应用于样式表是必要的,否则onload
将不会工作)
<link rel="preload" as="style" type="text/css" href="mystyles.css" onload="this.rel='stylesheet'">