使用requestAnimationFrame异步加载CSS样式表

Async loading CSS stylesheet using requestAnimationFrame

本文关键字:样式 CSS 加载 requestAnimationFrame 异步 使用      更新时间:2023-09-26

谷歌推荐(https://developers.google.com/speed/docs/insights/OptimizeCSSDelivery)使用以下JS代码优化页面速度(异步CSS加载)

<script>
  var cb = function() {
    var l = document.createElement('link'); l.rel = 'stylesheet';
    l.href = 'small.css';
    var h = document.getElementsByTagName('head')[0]; h.parentNode.insertBefore(l, h);
  };
  var raf = requestAnimationFrame || mozRequestAnimationFrame ||
      webkitRequestAnimationFrame || msRequestAnimationFrame;
  if (raf) raf(cb);
  else window.addEventListener('load', cb);
</script>

当我使用上面的代码时,Page Speed Insights(https://developers.google.com/speed/pagespeed/insights/)识别它并给页面更高的分数。但问题是,这段代码在旧的IE中不起作用。

例如,IE 8抛出一个错误"Object requestAnimationFrame is not defined"。问题是显而易见的,IE 8不支持RAF,所以由于未定义对象,它抛出了一个错误。

我需要网站在这些旧的IE中也能正常工作,所以我决定更新我的代码如下:

<script>
function loadCss() {
    var l = document.createElement('link');
    l.href = 'http://static.xyz.com/css/style.min.css?v=23';
    l.rel = 'stylesheet';
    l.type = 'text/css';
    l.media = 'screen';
    document.getElementsByTagName('head')[0].appendChild(l);
}
if (typeof requestAnimationFrame === 'function') {
    requestAnimationFrame(loadCss);
}
else if (typeof mozRequestAnimationFrame === 'function') {
    mozRequestAnimationFrame(loadCss);
}
else if (typeof webkitRequestAnimationFrame === 'function') {
    webkitRequestAnimationFrame(loadCss);
}
else if (typeof msRequestAnimationFrame === 'function') {
    msRequestAnimationFrame(loadCss);
}
else if (typeof window.addEventListener === 'function') {
    window.addEventListener('load', loadCss);
}
else {
    window.onload = loadCss;
}

这段代码不太漂亮,但它在IE7+、Firefox、Chrome等中运行正常。但当我通过Page Speed Insights测试它时,它没有识别出CSS是异步加载的,也没有给我更高的分数(它显示的错误与CSS是通过同步加载的一样)。

我的问题是:我的代码中是否有我不知道的错误,或者谷歌根本不知道这种插入异步CSS的方式。对我来说,代码正常工作是绝对重要的,但我希望在页面速度测试中获得更高的分数,因为这将有利于SEO目的。

我不是Javascript或布局绘画等方面的专家,但我找不到关于发生了什么或问题可能在哪里的解释。

提前感谢您的任何解释或提示。

这段代码似乎帮了我一把(它加载异步CSS,Google PageSpeed接受它,它在旧浏览器上工作):

<script>
var cb = function(){
  var styles = ["http://mycdn.co.uk/stylesheet1.css", "http://mycdn.co.uk/stylesheet2.css"];
  for( var i = styles.length - 1; i >= 0; i-- )
  {
    l = document.createElement( 'link' );
    l.rel = 'stylesheet';
    l.href = styles[i];
    h = document.getElementsByTagName( 'head' )[0];
    h.insertBefore( l, h.childNodes[h.childNodes.length-1] );
  };
};
var raf = ( "undefined" != typeof requestAnimationFrame ) ? requestAnimationFrame : false ||
    ( "undefined" != typeof mozRequestAnimationFrame ) ? mozRequestAnimationFrame : false ||
    ( "undefined" != typeof webkitRequestAnimationFrame ) ? webkitRequestAnimationFrame : false ||
    ( "undefined" != typeof msRequestAnimationFrame ) ? msRequestAnimationFrame : false;
if( raf )
{
  raf( cb );
}
else
{
  if( "undefined" != typeof window.addEventListener )
    window.addEventListener( 'load', cb );
  else if( "undefined" != typeof window.attachEvent )
    window.attachEvent( 'onload', cb );
}
</script>

感谢Ultrabenosaurus的代码!

您的代码异步加载css,是的。所以谷歌很可能就是不认识你的方式。您可以尝试将window.onload替换为attachEvent以获得ie支持,这可能有助于

我遇到了同样的问题,在我的情况下,几个移动"用户体验"问题导致Page Speed Insights在我异步加载的CSS启动之前分析了网站。

这样做很痛苦,但最终提取了解决用户体验问题的基本样式,然后在头中放置该内联的缩小版本,同时让大部分CSS通过js异步加载。

希望有更好的解决方案。