如何防止CSS阻塞我的网站渲染?

10

我正在尝试优化我的移动网页的加载速度,为此我正在使用以下网站:

该网站评估我的源码并告诉我可以改进的内容。在我的网站中,我下载了一种字体:

<link href="//fonts.googleapis.com/css?family=Open+Sans:400,700" rel="stylesheet">

显然,这会阻塞我的页面渲染。如果这是JavaScript,我可以在标签中使用async,问题就解决了,但我加载的不是JavaScript文件!

有没有办法防止此资源阻塞浏览器,并强制它等待下载完成?


1
你可以在<body>标签的末尾使用<style> @import "//fonts.googleapis.com/css?family=Open+Sans:400,700" </style>来加载字体...但是,这样会导致FOUC,就像使用JS一样。你想让他们再等一会儿,还是闪烁?个人而言,我会选择等待... - dandavis
@dandavis:当然,你是对的,尽管从技术上讲,在body(或者html中只有head)中,stylelink都不是有效的标签(尽管夜间规范有一个scoped属性可以允许它)。但我认为世界上没有一款浏览器会在意这个。用JavaScript做这件事可能是不必要的。通过将JS放在head中,我们可能希望能够稍微提前下载一点内容,但更有可能的是,浏览器的预取扫描程序会立即找到link元素... - T.J. Crowder
@dandavis:谢谢,我会测试那个选项。就我个人而言,我不介意FOUC,所以我相信那就是我需要的! - Flame_Phoenix
@dandavis:就我个人而言,我会将其发布为答案(引用新的scoped属性)。 - T.J. Crowder
搞定了。谁来发布答案?xD - Flame_Phoenix
显示剩余2条评论
2个回答

19

你可以使用JavaScript来实现:

<script>
(function() {
    var link = document.createElement('link');
    link.rel = "stylesheet";
    link.href = "//fonts.googleapis.com/css?family=Open+Sans:400,700";
    document.querySelector("head").appendChild(link);
})();
</script>

字体将在主渲染外加载。当字体完成加载时,会有视觉变化……如果用户禁用了JavaScript,则不会加载字体。


或者,正如dandavis指出的那样,您可以在body结束标签</body>之前使用style元素:

<style>
@import "//fonts.googleapis.com/css?family=Open+Sans:400,700"
</style>

现在它是有效的 HTML(截至 HTML 5.2 的 20170808 版草案),但即使在它变得有效之前,我从未遇到过放置 stylebody 中并且让浏览器关心它的情况。

与使用 JavaScript 相比,这样做的优点是:

  1. 理论上,浏览器的预取扫描程序可能会找到 style 元素并更早地开始下载 (尽管如果你将 JavaScript 放在 head 中,这不太可能),而且

  2. 即使用户禁用了 JavaScript,它也能起作用。

或者,您可以将您的 link 元素移到 body 的末尾,但目前这是无效的,并且 scoped 属性似乎不适用(还没有?)。 (为什么将其应用于 style 而不是 link[rel = stylesheet]?我不知道,也许只是因为还没有到达那里......)


1
@Flame_Phoenix:dandavis似乎不想发布答案,所以我已经更新了上面的内容。 - T.J. Crowder
有关 AMP 页面的任何想法? - kplshrm7
@kplshrm7:我甚至不知道什么是AMP页面。 :-) - T.J. Crowder
1
@T.J.Crowder 这是有效的HTML 截至HTML 5.2 - syntagma
@syntagma - 谢谢,看起来在2017071820170808草案之间发生了变化。终于!不过,以前的规则也没有被任何浏览器强制执行。 :-) - T.J. Crowder
显示剩余4条评论

0
<script src="https://ajax.googleapis.com/ajax/libs/webfont/1.5.18/webfont.js"></script>
<script>
 WebFont.load({
    google: {
      families: ['Open Sans:400,700,400italic,700italic']
    }
  });
</script>

4
从审核队列中:我可以请求您在回答中添加更多的上下文信息吗?仅有代码的答案很难理解。如果您能在帖子中添加更多信息,这将有助于提问者和未来的读者。 - RBT

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接