Html 如何异步加载 CSS

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32759272/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 18:16:11  来源:igfitidea点击:

How to load CSS Asynchronously

htmlcssasynchronous

提问by Paulina994

I'm trying to eliminate 2 CSS files that are render blocking on my site - they appear on Google Page Speed Insights. I have followed different methods, none of which were a success. But, recently, I found a post about Thinking Asyncand when I applied this code: <script async src="https://third-party.com/resource.js"></script>it did eliminate the problem.

我正在尝试消除在我的网站上呈现阻塞的 2 个 CSS 文件 - 它们出现在 Google Page Speed Insights 上。我采用了不同的方法,但都没有成功。但是,最近,我发现了一篇关于Thinking Async的帖子,当我应用此代码时:<script async src="https://third-party.com/resource.js"></script>它确实消除了问题。

However, after publishing, the page lost the styling. I'm not too sure as to what is going on because the code works but it's the styling after upload that doesn't work. Would appreciate your help with this. Thanks

但是,发布后,页面失去了样式。我不太确定发生了什么,因为代码有效,但上传后的样式不起作用。非常感谢您的帮助。谢谢

回答by Vladimir Salguero

The trick to triggering an asynchronous stylesheet download is to use a <link>element and set an invalid value for the media attribute (I'm using media="none", but any value will do). When a media query evaluates to false, the browser will still download the stylesheet, but it won't wait for the content to be available before rendering the page.

触发异步样式表下载的技巧是使用一个<link>元素并为 media 属性设置一个无效值(我使用的是 media="none",但任何值都可以)。当媒体查询评估为 false 时,浏览器仍将下载样式表,但不会等待内容可用后再呈现页面。

<link rel="stylesheet" href="css.css" media="none">

Once the stylesheet has finished downloading the media attribute must be set to a valid value so the style rules will be applied to the document. The onload event is used to switch the media property to all:

样式表下载完成后,必须将 media 属性设置为有效值,以便将样式规则应用于文档。onload 事件用于将 media 属性切换为 all:

<link rel="stylesheet" href="css.css" media="none" onload="if(media!='all')media='all'">

This method of loading CSS will deliver useable content to visitors much quicker than the standard approach. Critical CSS can still be served with the usual blocking approach (or you can inline it for ultimate performance) and non-critical styles can be progressively downloaded and applied later in the parsing / rendering process.

这种加载 CSS 的方法将比标准方法更快地向访问者提供可用的内容。关键 CSS 仍然可以使用通常的阻塞方法(或者您可以将其内联以获得最终性能),并且可以在解析/渲染过程中逐步下载和应用非关键样式。

This technique uses JavaScript, but you can cater for non-JavaScript browsers by wrapping the equivalent blocking <link>elements in a <noscript>element:

此技术使用 JavaScript,但您可以通过将等效的阻塞<link>元素包装在元素中来满足非 JavaScript 浏览器的需求<noscript>

<link rel="stylesheet" href="css.css" media="none" onload="if(media!='all')media='all'"><noscript><link rel="stylesheet" href="css.css"></noscript>

You can see the operation in www.itcha.edu.sv

您可以在www.itcha.edu.sv 中查看操作

enter image description here

在此处输入图片说明

Source in http://keithclark.co.uk/

来源http://keithclark.co.uk/

回答by jabacchetta

2020 Update

2020 更新



The simple answer (full browser support):

简单的答案(完整的浏览器支持):

<link rel="stylesheet" href="style.css" media="print" onload="this.media='all'">

The documented answer (with optional preloading and script-disabled fallback):

记录的答案(带有可选的预加载和禁用脚本的回退):

 <!-- 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>

Preloading and async combined:

预加载和异步结合:

If you need preloaded and async CSS, this solution simply combines two lines from the documented answer above, making it slightly cleaner. But this won't work in Firefoxuntil they support the preload keyword. And again, as detailed in the documented answer above, preloading may not actually be beneficial.

如果您需要预加载和异步 CSS,此解决方案只需结合上面记录的答案中的两行,使其更简洁。但是在 Firefox支持preload 关键字之前,这在 Firefox 中不起作用。同样,如上面记录的答案中详述的那样,预加载实际上可能没有好处。

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

Additional considerations:

其他注意事项:

Note that, in general, if you're going to load CSS asynchronously, it's generally recommended that you inline critical CSS, since CSS is a render-blocking resource for a reason.

请注意,一般而言,如果您打算异步加载 CSS,通常建议您内联关键 CSS,因为 CSS 是一种阻止渲染的资源,这是有原因的

Credit to filament groupfor their many async CSS solutions.

归功于 filament group的许多异步 CSS 解决方案。

回答by Flimm

Using media="print"and onload="this.media='all'":

使用media="print"onload="this.media='all'"

The filament group recently (July 2019) published an articlegiving their latest recommendation for how to load CSS asynchronously. Even though they are the developers of the popular Javascript library loadCSS, they actually recommend this solution that does not require a Javascript library:

filament group 最近(2019 年 7 月)发表了一篇文章,给出了他们关于如何异步加载 CSS 的最新建议。尽管他们是流行的 Javascript 库loadCSS的开发者,但他们实际上推荐了这个不需要 Javascript 库的解决方案:

<link rel="stylesheet" href="/path/to/my.css" media="print" onload="this.media='all'">

Using media="print"will indicate to the browser not to use this stylesheet on screens, but on print. Browsers actually do download these print stylesheets, but asynchronously, which is what we want. We also want the stylesheet to be used once it is downloaded, and for that we set onload="this.media='all'". If you want, you can add a <noscript>fallback for the rare users who don't have Javascript enabled.

Usingmedia="print"将指示浏览器不要在屏幕上使用此样式表,而是在打印时使用。浏览器确实会下载这些打印样式表,但是是异步的,这正是我们想要的。我们还希望样式表在下载后立即使用,为此我们设置了onload="this.media='all'". 如果需要,您可以<noscript>为未启用 Javascript 的少数用户添加后备。

The original articleis worth a read, as it goes into more detail than I am here. This article on csswizardry.comis also worth a read.

原来的文章值得一读,因为它进入更详细的比我在这里。csswizardry.com 上的这篇文章也值得一读。

回答by kamus

you can try to get it in a lot of ways :

您可以尝试通过多种方式获得它:

1.Using media="bogus"and a <link>at the foot

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.Inserting DOM in the old way

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.if you can try plugins you could try loadCSS

3.如果你可以尝试插件,你可以尝试 loadCSS

<script>
  // include loadCSS here...
  function loadCSS( href, before, media ){ ... }
  // load a file
  loadCSS( "path/to/mystylesheet.css" );
</script>

回答by Rounin

The function below will create and add to the document all the stylesheets that you wish to load asynchronously. (But, thanks to the Event Listener, it will only do so after all the window's other resources have loaded.)

下面的函数将创建您希望异步加载的所有样式表并将其添加到文档中。(但是,由于Event Listener,它只会在所有窗口的其他资源都加载后才会这样做。)

See the following:

请参阅以下内容:

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);

回答by virender nehra

Async CSS Loading Approaches

异步 CSS 加载方法

there are several ways to make a browser load CSS asynchronously, though none are quite as simple as you might expect.

有多种方法可以让浏览器异步加载 CSS,但没有一种方法像您预期的那样简单。

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

回答by Olivier Tassinari

If you need to programmatically and asynchronously load a CSS link:

如果您需要以编程方式异步加载 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);
}

回答by Bradley

If you have a strict content security policy that doesn't allow @vladimir-salguero's answer, you can use this (please make note of the script nonce):

如果您有严格的内容安全策略不允许@vladimir-salguero回答,您可以使用它(请记下脚本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>

Just add the following to your stylesheet reference: media="none" data-async="true". Here's an example:

只需以下添加到您的样式表参考:media="none" data-async="true"。下面是一个例子:

<link rel="stylesheet" href="../path/script.js" media="none" data-async="true" />

Example for jQuery:

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>

回答by kaushik gandhi

Please care to update the answer as all of the above fails to impress google pagespeed insights now.

请注意更新答案,因为上述所有内容现在都无法给 google pagespeed 见解留下深刻印象。

According to Googlethis is how you should implement async loading of Css

根据谷歌,这是你应该如何实现 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>