【问题标题】:"Eliminate render-blocking CSS in above-the-fold content"“消除首屏内容中的渲染阻塞 CSS”
【发布时间】:2013-09-12 10:03:23
【问题描述】:

我一直在使用 Google PageSpeed 洞察力来尝试提高我网站的性能,到目前为止,它已被证明非常成功。延迟脚本之类的东西效果很好,因为我已经有一个内部版本的 jQuery .ready() 来延迟脚本直到页面完全加载,我所要做的就是内联该特定函数并将完整脚本移动到末尾这页纸。效果很好。

但现在我发现自己盯着清单上剩下的一个黄点:“消除首屏内容中的渲染阻塞 CSS”。

我的 CSS 设置方式是拥有一个全局 _.css 文件,其中包含通常适用于页面结构的样式,或者在整个站点中不止一两个地方使用的样式。然后,大多数页面都有一个关联的 CSS 文件(例如,party.phpparty.css),其中包含特定于该特定页面的样式。所有 CSS 文件都被无限期缓存,因为我将 /t=FILEMTIME 附加到文件名(然后使用 .htaccess 删除它们)以保证文件在更改时得到更新。

无论如何,Google 建议内联首屏内容所需的关键样式。麻烦的是……好吧,看看这个截图:http://prntscr.com/1qt49e

如您所见...所有的内容都在首屏!人们讨厌滚动,尤其是在涉及加载许多页面的游戏中。所以我将网站设计为适合一个屏幕(假设分辨率足够好)。所以这意味着...... 所有 样式适用于首屏内容!那么……有什么解决办法吗?还是我在接近完美的分数上被那个黄色标记卡住了?

【问题讨论】:

  • 具有讽刺意味的是,屏幕截图的首屏内容需要很长时间才能加载 :) 事实上,对我来说,最终没有加载屏幕截图
  • @Anupam 可能被删除了。 prntscr 并不完全意味着永久性,我没想到这个问题会相当如此受欢迎。
  • 是的,一切都很好,只是一个简单的评论

标签: css pagespeed


【解决方案1】:

之前有人问过一个相关问题:What is “above-the-fold content” in Google Pagespeed?

首先,您必须注意,这都是关于“移动网页”的。
因此,当我正确解释了您的问题和屏幕截图时,这不适用于您的网站!

相反 - 执行 Google 在其指南中建议的一些事情对于“正常”网站来说会变得更糟。
并不是所有来自谷歌的东西都是“圣杯”,因为它来自谷歌。如果您查看他们的 HTML 标记,他们本身也不是一个好的榜样。

我能给你的最好建议是:

  • 在 CSS 中设置替换元素的宽度和高度,以便浏览器可以布局元素而不必等待替换的内容!

另外,您为什么使用不同的 CSS 文件,而不是只使用一个?
额外的请求比少量的数据量更糟糕。在第一次请求之后,CSS 文件无论如何都会被缓存。

应该始终注意的事情是:

  • 尽可能减少请求次数
  • 尽可能降低整体页面重量

不要让您的大脑困惑于如何获得 100% 的 Google PageSpeed Insights 工具......! ;-)

附加 1:这是 Google 向我们展示的页面,他们为 Optimize CSS Delivery 推荐的内容。

如前所述,我认为这既不现实也不对“正常”网站有意义!因为主要是当您有一个响应式网页设计时,最确定的是您使用媒体查询和其他布局样式。因此,如果您不打算先以阻塞方式加载 CSS,您将获得 FOUTFlash Of Unstyled Text)。我真的不相信这比渲染页面至少多几毫秒“更好”!

恕我直言,Google 正在开始一个新的“炒作”(当我在 Stackoverflow 上查看所有关于它的问题时)......!

【讨论】:

  • 很好的答案。问题是如果你的页面速度较慢,谷歌似乎会惩罚你。因此,他们强迫你坚持他们的想法,无论是伟大的还是完全愚蠢的。 :(
  • @Netsurfer 并非来自谷歌的一切都是“圣杯”哈哈。我挠头想达到 100,但在阅读此评论后停在 92。
  • 你应该更强调一点,事实上,Google doesn't adhere to their own suggestions
  • 附加请求将不再是 HTTP/2 和 SPDY 的问题,from Wikipedia,“HTTP/2 初稿(它是 SPDY 的副本)中的附加性能改进来自多路复用请求和响应的数量,以避免 HTTP 1 中的行头阻塞问题(即使使用 HTTP 流水线)、标头压缩和请求的优先级。”
  • 一直在尝试将我的页面从 72 移动和 80 桌面升级,但遇到了同样的问题。我拒绝将我的 css 放在更低的位置,并且可能会通过显示 FOUT 来降低用户体验!
【解决方案2】:

我如何在 Google Page Speed(移动版)上获得 99/100

TLDR:在 <style></style> 标签之间压缩并嵌入整个 CSS 脚本。


大约一个星期以来,我一直在追求难以捉摸的 100/100 分数。和你一样,剩下的最后一项是消除“首屏内容的渲染阻塞 css”。

肯定有一个简单的解决方案?没有。我尝试了Filament group's loadCSS 解决方案。 .js 太多了,我不喜欢。

async 的 css 属性(如 js)怎么样?它们不存在。

我已经准备好放弃了。然后我恍然大悟。如果 linking 脚本阻止了渲染,那么如果我改为将整个 CSS 嵌入头部会怎样。这样就没有什么可以阻止的了。

在我的样式标签中嵌入 1263 行 CSS 似乎是绝对错误的。但我试了一下。我首先使用压缩它(并添加前缀):

postcss -u autoprefixer --autoprefixer.browsers 'last 2 versions' -u cssnano --cssnano.autoprefixer false *.css -d min/See the NPM postcss package.

现在它只是一长行的无空格 css。我在主页上的<style>your;great-wall-of-china-long;css;here</style> 标签中添加了css。然后我重新分析了页面速度洞察力。

我在移动设备上从 90/100 到 99/100!!!

这违背了我(可能还有你)的一切。但它解决了问题。我现在只是在我的主页上使用它,并通过 PHP 包含以编程方式包含压缩的 css。

YMMV(您的里程可能会有所不同)取决于您的 CSS 长度。谷歌可能会因为您的首屏内容过多而对您不利。 但不要假设;测试!

注意事项

  1. 我现在只在我的主页上执行此操作,以便人们在我最重要的页面上获得 FAST 渲染。

  2. 您的 css 不会被缓存。不过我并不担心。当他们点击我网站上的另一个页面时,.css 被缓存(见注 1)。

【讨论】:

  • 感谢您的奉献和研究,但我个人不会梦想这样做:D
  • 那么,除了试图获得一个无济于事的分数之外,还有什么意义呢?
  • 当然,您的分数更高了,但现在您网站上的每个页面都会有更多的权重。不过,很好的发现。
  • @EdwardM 谢谢!请参阅我在帖子中的注释 2。一旦他们点击第二页,css 就会被缓存,重量问题就会消失。
  • @LarryBud 分数高点?给我更多的钱。我的网站在 Google 中的排名越高,就越有可能有人点击它并成为客户。因为Google uses page speed to determine ranking,我决定提高我的分数。
【解决方案3】:

一些可能有帮助的提示:

  • 我昨天在 CSS 优化中看到了这篇文章: CSS profiling for ... optimization
    很多关于 CSS 的有用信息以及哪些 CSS 会导致性能下降。

  • 我在 jQueryUK 上看到了以下关于 Googe Chrome (Canary) 开发工具中“隐藏的秘密”的演示: DevTools Can do that。 查看Time to First Paint、重绘和昂贵的 CSS 部分。

  • 1234563例如。合并具有相同属性的块。我用了几次,它可以节省相当多的CSS。

题外话: 我第二个@Enzino 为您正在加载的所有小图标创建一个精灵。文件大小非常小,它并不真正保证每个图标的服务器往返。还要记住浏览器可以执行的并发 http 请求总数。因此,对大量小图标的请求也是“阻止渲染”的。尽管与您的页面相比是一个空白页面,但我喜欢 duckduckgo 的加载方式。

【讨论】:

  • 好像duckduckgo也不在乎他们的页面分数,检查here
【解决方案4】:

请查看以下页面https://varvy.com/pagespeed/render-blocking-css.html。 这帮助我摆脱了“Render Blocking CSS”。我使用以下代码来删除“Render Blocking CSS”。现在在谷歌页面速度洞察中,我没有遇到与渲染阻塞 css 相关的问题。

<!-- loadCSS -->
<script src="https://cdn.rawgit.com/filamentgroup/loadCSS/6b637fe0/src/cssrelpreload.js"></script>
<script src="https://cdn.rawgit.com/filamentgroup/loadCSS/6b637fe0/src/loadCSS.js"></script>
<script src="https://cdn.rawgit.com/filamentgroup/loadCSS/6b637fe0/src/onloadCSS.js"></script>
<script>
      /*!
      loadCSS: load a CSS file asynchronously.
      */
      function loadCSS(href){
        var ss = window.document.createElement('link'),
            ref = window.document.getElementsByTagName('head')[0];

        ss.rel = 'stylesheet';
        ss.href = href;

        // temporarily, set media to something non-matching to ensure it'll
        // fetch without blocking render
        ss.media = 'only x';

        ref.parentNode.insertBefore(ss, ref);

        setTimeout( function(){
          // set media back to `all` so that the stylesheet applies once it loads
          ss.media = 'all';
        },0);
      }
      loadCSS('styles.css');
    </script>
    <noscript>
      <!-- Let's not assume anything -->
      <link rel="stylesheet" href="styles.css">
    </noscript>

【讨论】:

  • 当我使用上述功能时,它会降低 pageSpeed 分数。我写的函数是:jsfiddle.net/kvfzbxxo你能帮帮我吗?
  • 我已经在下面的 url 上实现了同样的功能,请在此处查看速度“whitecashback.in”您可以查看源 url 并在页脚找到函数“loadCSS”。这将帮助您了解我是如何实现代码的。在页面之后加载 css 时,页面速度应该会提高。
  • 我使用了这个代码:jsfiddle.net/sbpa1hun。现在网站中没有加载 CSS。
  • 我提到在添加此代码后:jsfiddle.net/sbpa1hun 正在您的网站中使用,我的网站失去了所有样式。它提高了页面速度,但 CSS 不再起作用了!你能帮我一些方法吗?我的页面速度大约为 40。但是添加你的代码我得到了 70 左右。但无法让 CSS 工作。
  • 如果您尝试在 jsfiddle 中执行此操作,那么这将不起作用,请在您的网站中尝试此代码,jsfiddle 将阻止加载外部网站的 css。因为您正在使用 javascript 加载外部源的 css。因此,请尝试在您的网站中执行此操作。还尝试包含 jquery 文件,它们在您的脚本中丢失。包含 js 文件后,这可能会起作用。另请注意,https 站点可能在 jsfiddle 中运行。您收到此错误:“阻止加载混合活动内容”。你需要先解决这个问题。
【解决方案5】:

我也一直在为这个新的页面速度指标而苦恼。

虽然我没有找到让我的分数恢复到 %100 的实用方法,但我发现有一些事情很有帮助。

将所有 css 合并到一个文件中很有帮助。我所有的网站都备份到 %95 - %98。

我能想到的唯一另一件事是在第一页上内联所有必要的 css(这似乎是大部分 - 至少对于我的页面而言)以获得甜蜜的高分。虽然它可能有助于您的速度得分,但这可能会使您的页面加载速度变慢。

【讨论】:

【解决方案6】:

2019 年的最佳解决方案是 HTTP/2 服务器推送

您不需要任何 hacky javascript 解决方案或内联样式。但是,您确实需要支持 HTTP 2.0 的服务器(任何现代服务器版本都可以),它本身要求您的服务器运行 SSL。但是,有了 Let's Encrypt,无论如何都没有理由不使用 SSL。

我的网站https://r.je/ 在移动设备和桌面设备上的得分均为 100/100。

这些错误的原因是浏览器获取 HTML,然后必须等待 CSS 下载后才能呈现页面。使用 HTTP2,您可以同时发送 HTML 和 CSS。

您可以通过设置 Link 标头来使用 HTTP/2 推送。

Apache 示例 (.htaccess):

Header add Link "</style.css>; as=style; rel=preload, </font.css>; as=style; rel=preload"

对于 NGINX,您可以将标头添加到服务器配置中的位置标记:

location = / {
    add_header Link "</style.css>; as=style; rel=preload, </font.css>; as=style; rel=preload";
}

设置此标头后,浏览器会同时接收 HTML 和 CSS,从而阻止 CSS 阻止呈现。

您将需要对其进行调整,以便仅在第一个请求时发送 CSS,但 Link 标头是“消除渲染阻塞 Javascript 和 CSS”的最完整和最简单的解决方案

详细讨论请看我的帖子:Eliminate Render Blocking CSS using HTTP/2 Push

【讨论】:

  • 我可能理解错了,但是服务器推送不会导致每次加载页面时都发送 CSS,而不是在缓存之前发送一次吗?
  • 是的,有一些技术,例如 cookie,可以帮助避免这种情况。在此处查看选择性推送部分:nginx.com/blog/nginx-1-13-9-http2-server-push
【解决方案7】:

考虑使用一个包从您的 css 文件中自动生成内联样式。一个好的是Grunt CriticalCritical css for Laravel

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多