如何消除渲染阻塞资源(app.css)?

Fra*_*uds 4 css performance performance-testing pagespeed-insights

在此输入图像描述

\n

我正在测试我创建的网络的性能。我尝试使用Google 的 Page Speed \xe2\x80\x8b\xe2\x80\x8band GT Metrix。每个应用程序都会产生不同的性能结果。

\n

我正在尝试查看热门问题 GT Matrix 中的结果,. 中的渲染资源存在问题app.css。我尝试使用下面的代码来解决这个问题,但初始渲染结果不太好看。

\n

谁能帮助我如何处理这个问题?

\n
<link rel="stylesheet" href="http://103.148.190.87/css/app.css" as="style" onload="this.onload=null;this.rel=\'stylesheet\'">\n<noscript>\n  <link rel="stylesheet" href="http://103.148.190.87/css/app.css">\n</noscript>\n
Run Code Online (Sandbox Code Playgroud)\n

Gra*_*hie 11

了解什么是“渲染阻塞资源”。

当浏览器请求您的页面时,它需要显示“首屏”的任何内容的 HTML 和 CSS,然后才能正确呈现。

“首屏”本质上是指无需滚动即可在屏幕上看到的任何内容。

关键 CSS 是渲染首屏内容所需的所有 CSS。

如果您的网站恰好是用 JS 渲染的,那么您还需要采用类似的技术,如下所示,用于水合/渲染初始页面内容所需的 JS。然而这个答案集中在CSS上(原理是一样的,只是方法不同)。

为什么这有关系?

如果您的样式位于外部样式表中,则浏览器必须执行以下操作:

  1. 下载该页面的 HTML。
  2. 看看渲染上面的折叠内容需要什么样式。
  3. 下载需要的样式
  4. 下载样式后,即可呈现内容。

如果某人的连接延迟较高(例如 4G,到服务器的往返时间可能为 300 毫秒或更长),那么对 CSS 的额外网络请求确实会减慢页面速度。

相反,我们想要做的是提供立即呈现折叠内容以上所需的所有样式,以便不需要进一步的网络请求。

修复步骤

原理很简单,但要正确执行可能相当困难,可能需要一点耐心。

识别关键 CSS

有很多方法可以做到这一点,但它们通常取决于您的构建过程、堆栈等。

原则上,您正在寻找一个工具,将首屏上方的 HTML 映射到与这些项目匹配的 CSS 类和样式。然后该工具应该为您导出这些样式。

不幸的是,我还没有看到一个 100% 有效的工具,所以我建议你使用一个工具来获取大部分样式,然后(内联关键 CSS 后 - 见下文)删除所有外部样式表,看看是否有是无法正确渲染的东西。在包含外部 CSS 的页面上检查它们并复制样式。

如果您在设计网站时没有考虑到这一点,这可能会很费力,但这是值得的。

内联关键 CSS

一旦您确定了关键的 CSS,您只需将其内联即可。

这仅意味着您缩小它,然后将其添加到您的网站<style>页面顶部的标签内。

这又回到了我在引言中所说的部分。内联所有样式后,浏览器就拥有渲染页面所需的一切,而无需其他网络请求。这对您的首次内容绘制、最大内容绘制(通常)等有很大帮助。

推迟非关键 CSS

现在您已经内联了关键的 CSS,您只剩下两个步骤了:

  1. 从样式表中删除关键的 CSS - 没有必要下载两次!
  2. 使用您在原始问题中显示的方法:
<link rel="preload" href="styles.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="styles.css"></noscript>
Run Code Online (Sandbox Code Playgroud)

它的工作原理如下:

  • link rel="preload" as="style"异步请求样式表。您可以在预加载关键资产指南中了解有关预加载的更多信息。
  • onload中的属性允许linkCSS 在完成加载时进行处理。
  • onload使用处理程序后将其“清空”有助于某些浏览器避免在切换rel属性时重新调用处理程序。
  • 对元素内部样式表的引用noscript可以作为不执行 JavaScript 的浏览器的后备措施。

取自https://web.dev/defer-non-ritic-css/

伪例子

为了澄清这一点,我们假设我们有一个网站,其中有一个简单的英雄部分出现在首屏上方。使这个英雄部分工作只需要三个 CSS 类,因此我们为其内联 CSS。

<style>
.hero{
   min-width: 100%;
   height: 100vh;
   background: #333;
}
.hero h1{
  position: relative;
  float: left;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  color: #fff;
}
section{
    width: 75%;
    margin: 0 auto;
    padding-top: 20px;
}
</style>
Run Code Online (Sandbox Code Playgroud)

然后我们使用您描述的方法加载其余的 CSS:

<link rel="preload" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
    <noscript><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css"></noscript>
Run Code Online (Sandbox Code Playgroud)

快速示例

<!-- normal styles that appear below the fold -->
<link rel="preload" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css"></noscript>

<!-- all styles required for above the fold -->
<style>
.hero{
   min-width: 100%;
   height: 100vh;
   background: #333;
}
.hero h1{
  position: relative;
  float: left;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  color: #fff;
}
section{
    width: 75%;
    margin: 0 auto;
    padding-top: 20px;
}
</style>

<!-- above the fold -->
<section class="hero">
   <h1>Above the fold - all required styles inlined</h1>
</section>

<!-- below the fold -->
<section class="below">
<h2>Below the fold, all classes in external style sheet</h2>
<p class="lead">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur sodales ligula in libero. </p>

<p>Sed dignissim lacinia nunc. Curabitur tortor. Pellentesque nibh. Aenean quam. In scelerisque sem at dolor. Maecenas mattis. Sed convallis tristique sem. Proin ut ligula vel nunc egestas porttitor. Morbi lectus risus, iaculis vel, suscipit quis, luctus non, massa. Fusce ac turpis quis ligula lacinia aliquet. Mauris ipsum. </p>

<p>Nulla metus metus, ullamcorper vel, tincidunt sed, euismod in, nibh. Quisque volutpat condimentum velit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nam nec ante. Sed lacinia, urna non tincidunt mattis, tortor neque adipiscing diam, a cursus ipsum ante quis turpis. Nulla facilisi. Ut fringilla. Suspendisse potenti. Nunc feugiat mi a tellus consequat imperdiet. Vestibulum sapien. Proin quam. </p>

<p class="h4">Etiam ultrices. Suspendisse in justo eu magna luctus suscipit. Sed lectus. Integer euismod lacus luctus magna. Quisque cursus, metus vitae pharetra auctor, sem massa mattis sem, at interdum magna augue eget diam. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi lacinia molestie dui. Praesent blandit dolor. Sed non quam. In vel mi sit amet augue congue elementum. Morbi in ipsum sit amet pede facilisis laoreet. Donec lacus nunc, viverra nec, blandit vel, egestas et, augue. Vestibulum tincidunt malesuada tellus. Ut ultrices ultrices enim. </p>

<p>Curabitur sit amet mauris. Morbi in dui quis est pulvinar ullamcorper. Nulla facilisi. Integer lacinia sollicitudin massa. Cras metus. Sed aliquet risus a tortor. Integer id quam. Morbi mi. Quisque nisl felis, venenatis tristique, dignissim in, ultrices sit amet, augue. Proin sodales libero eget ante. Nulla quam. Aenean laoreet. </p>


</section>
Run Code Online (Sandbox Code Playgroud)