根据 Google 优化 CSS 交付
Optimising CSS delivery according to Google
所以我 运行 通过 Google 的 PageSpeed Insights 我的站点,它告诉我可以通过延迟加载非关键资源来改进 CSS 交付。特别是它提到了字体 awesome:
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
我想我可以通过简单地将它放在结束 body 标记之前的脚本之前来延迟它的加载,如下所示:
...
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="js/min/scripts.min.js"></script>
</body>
</html>
但是!在查看 Google 的 documentation on delivery speed 时,我发现了两种不同的解决方案。
以我的母语(荷兰语;您可以在右下角更改文档的语言)文档说明我应该将非必要的 css 放在下面 结束 html 标签。这对我来说似乎非常奇怪。 尝试通过 JS 访问文件时,这不会使事情复杂化吗? 为什么不将它放在结束 body 标记之前?
...
</body>
</html>
<link rel="stylesheet" href="small.css">
然而,在英文文档中,事情变得更加复杂,需要 JavaScript:
...
<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>
</body>
</html>
为什么需要 JS? 是不是有点过头了?
我的方法有什么问题?为什么不能在结束正文标记之前加载非关键 CSS?
我建议您查看此存储库:https://github.com/filamentgroup/loadCSS
LoadCSS 是 Filament Group 的人员编写的一个非常精明的脚本,用于以某种方式延迟加载样式表,大多数浏览器都能很好地配合使用。
如果 Javascript 被禁用或出于任何原因脚本将无法运行,则也包含回退。
我认为您关注的是他们(令人困惑的)文档的错误部分。我认为他们真正想要分享的是,您应该将您的关键 CSS 内嵌到您的 html 中。看style标签里的蓝色class
<html>
<head>
<style>
<!-- This is what they are trying to show -->
.blue{color:blue;}
</style>
</head>
<body>
<div class="blue">
Hello, world!
</div>
<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>
</body>
</html>
我阅读了相同的法语文档,它似乎和您的荷兰语版本一样过时,他们再次将蓝色 class 内联
<html>
<head>
<style>
.blue{color:blue;}
</style>
</head>
<body>
<div class="blue">
Hello, world!
</div>
</body>
</html>
<link rel="stylesheet" href="small.css">
他们想说的是,关键 CSS 可以直接放入 html 而无需加载整个 CSS 文件。在他们的示例中,蓝色 class 很关键,因为它是唯一使用的。
关于html标签的外部,它确实是无效的HTML,但浏览器似乎还是允许的。对于 JS 代码部分,我猜他们正试图在 header 中添加样式表,但只有在 JS 将被执行时,这意味着在页面加载结束时。此时,您可能需要考虑代码的可读性而不是性能。
外部样式表将阻止页面呈现,直到它完全加载。 Google 建议将文档最初可见(关键,首屏)部分所需的样式放在头部的 <style>
标签内(您唯一可以放置的地方可以定义非内联样式) 来避免这种渲染阻塞。非关键样式(当您登陆页面时不会直接看到的样式)作为外部样式表添加到头部 after HTML 已被读取。这样它会首先呈现,然后才会加载所有其他样式。这一切都是为了尽快向访问者展示内容,而不是让 her/him 等待不必要的时间。
它认为在大多数情况下 超过了 Google 推荐的内容,他们只是在几毫秒内变得异常 - 他们的方法才有意义如果 CSS 很大。但我认为很难,如果不是几乎不可能的话,用当前可用的工具进行维护。例如,如果它是一个回访者,他在较早的时候向下滚动了页面并会自动再次登陆那里(Opera 是一个对此非常顽固的浏览器)?仅此一项,您就需要更多的 JS,并且可能需要处理样式。那不是一个好方法。即使是初始显示,您也必须直接在头部填充一些媒体查询,以便在不诉诸全屏部分的情况下尝试正确处理。这一切都适得其反,而且过于复杂。
将 <style>
或 <link>
标记放在头部部分之外可能有效,但这是不正确的。我确信 Google 不再站在那个立场上,而且英文版是唯一有效的文档。
编辑 - 请参阅评论了解其中的细微差别。
即使有人按照 google 的方式进行操作并在 PageSpeed Insights 上获得 'good' 分数也没有太大意义。您仍然可以隐藏整个页面,并且仅在 所有内容 已加载(这并不罕见)时才显示它,而不会影响分数。
我个人决定忽略它,直到他们实现了一个你可以异步加载 CSS 的功能(就像你已经可以使用 JavaScript 和 async
一样)就像是在文档中宣布。它仍然需要一个特殊的用例,但至少你可以为它构建一个框架。我自己不喜欢插件。
Google 文档中缺少一件重要的事情 - 在禁用 JavaScript 时提供回退。幸运的是 HTML5,<noscript>
标签可用于此:
<head>
/* other stuff */
<noscript><link rel="stylesheet" href="small.css"></noscript>
</head>
旁注 - Google 自己的分析脚本将阻止完美的 PageSpeed 得分,因为他们在其上设置了(逻辑上)快速缓存过期。图那个。
回答您的具体问题:
Javascript 不需要完成你想要的。有几种以非阻塞方式加载 CSS 的方法。有些依赖 JS,有些则不。 Filamant 集团 LoadCSS is a JS option. Critical Path's CSS Generator is one non-JS method. The process of generating the critical CSS can also be automated using Gulp or Grunt.
虽然您的方法可行,但不推荐。 Google 建议使用 Javascript 加载非关键 CSS 文件,以便在页面加载完成后将 CSS 加载到 head
。
备选方案
有两种方法可以改进您当前的实施。
听起来您当前正在加载 2 个 CSS 文件 - 您网站的 CSS 和 font-awesome.min.css
。这需要 2 个 HTTP 请求并且会导致一个小的延迟。将 2 个文件中的 CSS 合并为一个 CSS 文件。
正如其他人指出的那样 Google 建议将关键的 CSS 内联到页面的 head
中,并加载剩余的 CSS以非阻塞的方式。我发现另一个有用的选项是将 CSS 的 全部 内容加载到 style
标记内的站点 head
中。如果您的 CSS 文件相对较小且已最小化,我建议 仅。
<head>
<style>
// ALL YOUR CSS
</style>
</head>
嗯,有 3 个主要部分,您可以在其中放置
第一个是 body,第二个是 head,第三个在 html 中无处不在,尝试使用它
所以我 运行 通过 Google 的 PageSpeed Insights 我的站点,它告诉我可以通过延迟加载非关键资源来改进 CSS 交付。特别是它提到了字体 awesome:
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
我想我可以通过简单地将它放在结束 body 标记之前的脚本之前来延迟它的加载,如下所示:
...
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="js/min/scripts.min.js"></script>
</body>
</html>
但是!在查看 Google 的 documentation on delivery speed 时,我发现了两种不同的解决方案。
以我的母语(荷兰语;您可以在右下角更改文档的语言)文档说明我应该将非必要的 css 放在下面 结束 html 标签。这对我来说似乎非常奇怪。 尝试通过 JS 访问文件时,这不会使事情复杂化吗? 为什么不将它放在结束 body 标记之前?
...
</body>
</html>
<link rel="stylesheet" href="small.css">
然而,在英文文档中,事情变得更加复杂,需要 JavaScript:
...
<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>
</body>
</html>
为什么需要 JS? 是不是有点过头了?
我的方法有什么问题?为什么不能在结束正文标记之前加载非关键 CSS?
我建议您查看此存储库:https://github.com/filamentgroup/loadCSS
LoadCSS 是 Filament Group 的人员编写的一个非常精明的脚本,用于以某种方式延迟加载样式表,大多数浏览器都能很好地配合使用。 如果 Javascript 被禁用或出于任何原因脚本将无法运行,则也包含回退。
我认为您关注的是他们(令人困惑的)文档的错误部分。我认为他们真正想要分享的是,您应该将您的关键 CSS 内嵌到您的 html 中。看style标签里的蓝色class
<html>
<head>
<style>
<!-- This is what they are trying to show -->
.blue{color:blue;}
</style>
</head>
<body>
<div class="blue">
Hello, world!
</div>
<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>
</body>
</html>
我阅读了相同的法语文档,它似乎和您的荷兰语版本一样过时,他们再次将蓝色 class 内联
<html>
<head>
<style>
.blue{color:blue;}
</style>
</head>
<body>
<div class="blue">
Hello, world!
</div>
</body>
</html>
<link rel="stylesheet" href="small.css">
他们想说的是,关键 CSS 可以直接放入 html 而无需加载整个 CSS 文件。在他们的示例中,蓝色 class 很关键,因为它是唯一使用的。
关于html标签的外部,它确实是无效的HTML,但浏览器似乎还是允许的。对于 JS 代码部分,我猜他们正试图在 header 中添加样式表,但只有在 JS 将被执行时,这意味着在页面加载结束时。此时,您可能需要考虑代码的可读性而不是性能。
外部样式表将阻止页面呈现,直到它完全加载。 Google 建议将文档最初可见(关键,首屏)部分所需的样式放在头部的 <style>
标签内(您唯一可以放置的地方可以定义非内联样式) 来避免这种渲染阻塞。非关键样式(当您登陆页面时不会直接看到的样式)作为外部样式表添加到头部 after HTML 已被读取。这样它会首先呈现,然后才会加载所有其他样式。这一切都是为了尽快向访问者展示内容,而不是让 her/him 等待不必要的时间。
它认为在大多数情况下 超过了 Google 推荐的内容,他们只是在几毫秒内变得异常 - 他们的方法才有意义如果 CSS 很大。但我认为很难,如果不是几乎不可能的话,用当前可用的工具进行维护。例如,如果它是一个回访者,他在较早的时候向下滚动了页面并会自动再次登陆那里(Opera 是一个对此非常顽固的浏览器)?仅此一项,您就需要更多的 JS,并且可能需要处理样式。那不是一个好方法。即使是初始显示,您也必须直接在头部填充一些媒体查询,以便在不诉诸全屏部分的情况下尝试正确处理。这一切都适得其反,而且过于复杂。
将 <style>
或 <link>
标记放在头部部分之外可能有效,但这是不正确的。我确信 Google 不再站在那个立场上,而且英文版是唯一有效的文档。
编辑 - 请参阅评论了解其中的细微差别。
即使有人按照 google 的方式进行操作并在 PageSpeed Insights 上获得 'good' 分数也没有太大意义。您仍然可以隐藏整个页面,并且仅在 所有内容 已加载(这并不罕见)时才显示它,而不会影响分数。
我个人决定忽略它,直到他们实现了一个你可以异步加载 CSS 的功能(就像你已经可以使用 JavaScript 和 async
一样)就像是在文档中宣布。它仍然需要一个特殊的用例,但至少你可以为它构建一个框架。我自己不喜欢插件。
Google 文档中缺少一件重要的事情 - 在禁用 JavaScript 时提供回退。幸运的是 HTML5,<noscript>
标签可用于此:
<head>
/* other stuff */
<noscript><link rel="stylesheet" href="small.css"></noscript>
</head>
旁注 - Google 自己的分析脚本将阻止完美的 PageSpeed 得分,因为他们在其上设置了(逻辑上)快速缓存过期。图那个。
回答您的具体问题:
Javascript 不需要完成你想要的。有几种以非阻塞方式加载 CSS 的方法。有些依赖 JS,有些则不。 Filamant 集团 LoadCSS is a JS option. Critical Path's CSS Generator is one non-JS method. The process of generating the critical CSS can also be automated using Gulp or Grunt.
虽然您的方法可行,但不推荐。 Google 建议使用 Javascript 加载非关键 CSS 文件,以便在页面加载完成后将 CSS 加载到
head
。
备选方案
有两种方法可以改进您当前的实施。
听起来您当前正在加载 2 个 CSS 文件 - 您网站的 CSS 和
font-awesome.min.css
。这需要 2 个 HTTP 请求并且会导致一个小的延迟。将 2 个文件中的 CSS 合并为一个 CSS 文件。正如其他人指出的那样 Google 建议将关键的 CSS 内联到页面的
head
中,并加载剩余的 CSS以非阻塞的方式。我发现另一个有用的选项是将 CSS 的 全部 内容加载到style
标记内的站点head
中。如果您的 CSS 文件相对较小且已最小化,我建议 仅。
<head>
<style>
// ALL YOUR CSS
</style>
</head>
嗯,有 3 个主要部分,您可以在其中放置
第一个是 body,第二个是 head,第三个在 html 中无处不在,尝试使用它