【问题标题】:Deferred non-critical caused high CLS延迟非关键导致高 CLS
【发布时间】:2020-11-05 18:37:31
【问题描述】:

我已经推迟了非关键 CSS/JS 并预加载了网站的基本 CSS。 PageSpeed Insights 上的每个实验室数据都变得更好。除了“最大内容绘制”和“累积布局转移”。 尤其是 CLS 从 0.002 增加到 1.148!

网站上的图片设置为background-image,我认为不会有“图片没有尺寸”的问题。我也试过用font-display修复字体,但是CLS还是一样。

还有其他我可以用来优化 CLS 的技术吗?

【问题讨论】:

  • 这个问题似乎是题外话,因为它是关于在 Stack Overflow 上题外话的 SEO。请阅读“Which SEO questions should be closed as non-programming/non-admin?”以更好地了解何时可以在此处提出 SEO 问题(大多数情况不接受)。可以在Webmasters.SE 上询问一般 SEO 问题。
  • 这个问题中没有关于 SEO 的任何内容,他们只是错误地添加了标签。这完全是关于页面速度和布局转变,对于 SO 来说是完全可以接受的问题。我已经删除了错误的 SEO 标签。请不要仅根据标签在未阅读的情况下将问题标记为关闭。

标签: performance google-pagespeed lighthouse pagespeed-insights


【解决方案1】:

您需要内联您的关键 CSS。

基本上,当页面加载时,它必须等待所有 CSS 呈现“首屏”(无需滚动即可立即查看的所有内容)内容。

当您延迟所有 CSS 时,您稍后会这样做,以便加载 HTML,然后在加载 CSS 时应用样式,从而导致页面上的内容发生变化。

它所说的关键部分是“延迟non-critical CSS”需要延迟,“critical CSS”需要尽早加载。

什么是关键 CSS?

Critical CSS 是“首屏”内容所需的所有 CSS。

您要做的是在您的文档<head> 中添加一个<style> 元素并将所有关键的CSS 放入其中。

这样一来,当您的所有 HTML 加载完毕后,浏览器也拥有渲染页面所需的所有 CSS,因此它几乎可以立即渲染。

这对于慢速移动连接至关重要,因为 3G/4G 上的大部分加载时间是延迟(到服务器的往返时间)。将呈现初始页面所需的 CSS 作为 HTML 的一部分意味着只有 1 个请求(您的主页)。

看到这个article which is quite good at explaining the concept

请注意,对于大多数主题来说,这不是一件容易的事(找到关键的 CSS 很困难,而且大多数工具都找不到所有相关的样式),但如果您试图获得超高的初始负载,那么值得付出努力次。

这将修复您的 CLS,因为所有内容都会同时呈现(因此不会发生布局变化)。

异常

您确实提到您使用 background-image 作为 CSS 的一部分。

您要么需要为具有背景图像的容器提供初始尺寸,要么首先使用Padding top CSS hack 或类似名称来设置框的尺寸。

否则当图像加载到其中时会导致布局偏移。这些尺寸应在您的关键 CSS 中设置。

最后的事情

请注意,这将修复 Page Speed Insights。

但这并不意味着现实世界中的所有 CLS 都是固定的。如果您在修复“实验室数据”(模拟)后遇到“现场数据”(真实世界数据)显示大 CLS 的问题,您可能会在页面下方延迟加载等。

这超出了这个问题的范围,但请记住,CLS 在现实世界中测量直到页面卸载,正如在 Google Chrome 上工作的 explanation on CLS from Addy Osmani 中提到的那样。

【讨论】:

  • 你提到我必须在<head><style> 标签中添加关键的CSS,但是我们的网站是用CMS 构建的,而且它是一个巨大的网站。真的不可能做到这一点。如果我使用rel="preload" 预加载<head> 中的关键CSS 会怎样?他们会采取同样的行动吗?
  • 不,问题是一样的,但可能会减少。 1 个请求 = 页面渲染,第二个您需要外部页面资源,您有一个关键请求。这将有所帮助,还将您的 CSS 拆分为“关键”和“非关键”以减少初始页面有效负载可能会有所帮助,因为您可以将更少的线路作为“优先级”(不推迟)推送,然后推迟其他所有内容。这绝不是一件容易实现的事情。
【解决方案2】:

CLS 优化

我的回答解决了您问题的第二部分,关于可用于优化 CLS 的技术。

从广义上讲,我的解决方案在 CSS 中隐藏了有问题的元素,并使它们在 javascript 中再次可见。布局移位是一个问题 - 并有助于 CLS 分数 - 只有当它对用户可见时;当它不可见时,它不会影响 CLS 分数。具体实现如下。

首先,创建一个“antiCls”类并将其添加到您的自定义 CSS(在 HEAD 元素中),如下所示:

.antiCls { 
    visibility: hidden;
}

接下来,将以下代码添加到自定义 JS 文件的 end(在 BODY 元素的底部)。一、JQUERY版本:

$(document).ready(function(){

...
existing jquery code
...

    $(window).on("load", function() 
                                                
        $('.antiCls').css("visibility", "visible"); 

    });
});

这里是原版 javascript 版本,没有 jquery:

var cls = document.getElementsByClassName('antiCls'),
    i = cls.length;
    
for (i = 0; i < cls.length; i++) {
    cls[i].style.visibility = "visible";
    } 

接下来,您需要确定要应用新“antiCls”类的元素。在该页面的 Google“PageSpeed Insights”下,查看“诊断”部分,并展开子标题“避免大的布局变化”。在那里,您会发现列出的违规(非零)DOM 元素:这些可能是图像,但其他元素(包括整个 div)也可能在此处列出。

对于图像,将新的 antiCls 类应用到父 div, 应用到图像本身。对于在一个父 div 下组合在一起的元素,将新的 antiCls 类应用于父 div。需要进行一些实验,但使用此技术通常可以轻松实现零分 CLS。

CLS 分数是否应该达到零是另一个问题。为了有效,antiCls 类需要被应用到“首屏”——也就是说,在没有滚动的情况下出现在视口中的元素。重要的是,至少 一些 元素保留在未应用 antiCls 类的页面顶部:这些元素通常包括一个徽标,可能还有一些导航。这样一来,向用户呈现一些关键内容(“首次内容绘制”)的速度不会受到负面影响。

在我自己的测试中,我发现这种 CLS 优化技术对页面显示的速度没有明显的影响;这意味着可以以几乎为零的性能成本实现低或零 CLS 分数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-05
    • 2015-10-26
    • 1970-01-01
    • 1970-01-01
    • 2015-10-25
    • 1970-01-01
    • 2018-07-14
    • 1970-01-01
    相关资源
    最近更新 更多