【问题标题】:Google Page Speed Insight Shows In-Consistent ResultsGoogle Page Speed Insight 显示不一致的结果
【发布时间】:2020-08-13 14:47:00
【问题描述】:

我有一个 wordpress 网站正在运行,我正在使用 W3Total 缓存插件来加快网站加载速度。当我在 Google Page Speed Insight 中扫描网站时,我注意到我得到了不一致的扫描结果。我有一个浮动在网页上的 Facebook Messenger 聊天和一个谷歌地图。由于这两个给了我减少第三方代码的影响警告我已经进行了更改,以便只有在 DOM 完全加载后才会加载这两个。实际上我为此使用了 jQuery SetTimeOut。通过这样做,我实际上设法从结果中删除了警告。但时不时地我注意到同样的警告再次出现,即使我已经做出了调整。如果我经常扫描该网站两到三遍,警告可能会响起,但过一会我会再次尝试。

这些是频繁扫描的结果。你们知道这里会出现什么问题吗?我花了很多时间搜索,但无法理解它。

【问题讨论】:

    标签: wordpress google-pagespeed pagespeed-insights w3-total-cache


    【解决方案1】:

    使用经典的 HTTP/1.0 超文本传输​​协议,Javascript、CSS、HTML、图像等资源被加载到请求/响应对中,这意味着浏览器发送请求以请求资源(无论是 CSS、Javascript等),并在请求另一个资源之前等待响应返回。即使它们被加载到请求/响应对中,由于网络延迟、服务器响应时间、服务器当前正在经历的负载等方面的随机性,请求和响应对并不总是严格遵循相同的顺序。

    使用 HTTP/2 和 HTTP/3(HTTP 协议的较新版本),可以一次发送所有请求,而不是等待响应返回再发送另一个请求。我检查了您的网站,发现您的网站正在使用 HTTP/2 和 HTTP/3。使用 HTTP/2 和 HTTP/3 协议,由于可以一次发送所有请求,因此它也会导致一定程度的“不一致”,等等。即使使用 HTTP 1,也总是存在一定程度的随机性,因为有很多因素会影响它,例如服务器响应时间会有所不同,网络延迟会有所不同,等等。

    为了说明这一点,如果您使用的是 Chrome 浏览器,请通过单击浏览器右上角的三个点打开“开发者工具”选项卡,然后单击“更多工具”,然后单击“开发者工具” ”。或者,如果您使用 Windows,则可以执行“Ctrl+Shift+I”或在 Mac 上执行“Command + Option + I”。然后转到其“网络”选项卡,然后刷新页面。每次刷新页面,资源加载的顺序都会有点不同:

    在上图中,以 Google Tag Manager UA-174548329-1 Javascript 为例(我知道它可能不是 Google 地图),它作为 4th 资源加载。

    当我再次刷新页面时,您的 Google 跟踪代码管理器 UA-174548329-1 Javascript 将作为 11th 资源加载:

    当页面正在加载或您在 Google 的 PageSpeed Insight 上运行它时,由于请求和响应的随机性,主线程有时会很忙,有时不会。您的主线程也在构建 DOM,并且做了很多工作。有时它会被阻止渲染的资源(例如 Javascript)阻止。

    默认情况下,Javascript 总是会阻止关键渲染路径。如果不查看您的 Javascript SetTimeOut,很难说您使用什么实现来延迟您的 Javascript,但可以肯定的是,它可能无助于清除关键渲染路径。您应该使用 deferasync,而不是使用 SetTimeOut。

    您可以在此处详细了解Critical Rendering Path。主线程是您的浏览器运行的主要进程,用于处理和呈现页面上的 CSS、Javascript、HTML 的大部分工作。关键的渲染路径是“浏览器将 HTML、CSS 和 JavaScript 转换为屏幕上的像素的一系列步骤”。 - 引用自Critical Rendering Path。关键渲染路径是您的 Javascript、HTML、CSS、图像和其他资源被下载和渲染的顺序。优化关键渲染路径需要大量知识,这不是一件容易的事。但是,您可以尝试在脚本标签中使用两个属性,即“async”和“defer”来控制何时执行 Javascript。

    看看这张图片:

    致谢:与网络一起成长

    https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/loading-third-party-javascript/?utm_source=lighthouse&utm_medium=unknown

    如您所见,您可以尝试将async 属性放入您的脚本或将defer 属性放入您的脚本标签中,看看是否有帮助。

    在脚本标签中带有'async'属性,这意味着您的Javascript将在下载后立即异步执行。如图所示,<script async> 下方的蓝色条显示在解析 HTML 的同时下载了脚本,因为可以看到绿色条和蓝色条并行执行。脚本下载完成后,立即执行脚本。此时,HTML 解析会暂停,直到脚本执行完毕。而如果没有 'async' 属性,您的 HTML 解析将在下载和执行脚本时暂停(或阻止)。

    在脚本标签中使用'defer' 属性,这意味着您将推迟执行 Javascript,直到 DOM 完成解析。虽然浏览器一收到javascript资源就会下载,但是下载不会阻塞HTML解析。

    总之,您可以在您的第三方脚本中使用“异步”属性在一定程度上“解除阻塞”您的主线程,以便在渲染 DOM 时在后台下载和执行主线程。这将加快主线程的速度。但是需要注意的是,执行仍将是渲染阻塞的。需要注意的一个非常重要的事情是,通过使用“异步”属性,准备好查看页面的一些可能的不稳定行为,因为现在可能会发生更多“不一致”,因为现在可以在渲染路径中随时执行 Javascript,因此如果在脚本之前或之后需要发生一些事情,你可能会破坏流程和它的逻辑。

    或者您可以在您的第三方脚本中使用“defer”属性来告诉您的脚本只有在 DOM 完全加载后才能执行。这只能稍微加快这个过程,只是一点点,因为现在可以在 HTML 解析发生时并行下载脚本,而不是使用默认脚本标记而不指定 defer 或 async,但执行仍将继续占用主线程的开销。

    根据 Google 的支持文档,How do you load third-party script efficiently? 上有一个部分,这里有几种方法:

    "

    • 使用 async 或 defer 属性加载脚本以避免阻塞文档解析。

    • 如果第三方服务器速度较慢,请考虑自行托管脚本。

    • 如果脚本不能为您的网站增加明确的价值,请考虑删除它。

    • 考虑使用 <link rel=preconnect><link rel=dns-prefetch> 之类的资源提示来对托管第三方脚本的域执行 DNS 查找。

    "

    其他方法:

    了解如何将各种 Javascript 文件压缩、缩小或合并到一个文件中(如果您使用的是文件形式的 Javascript)。使用GZIP compression 压缩您的Javascript、CSS。另请查看如何使用 CDN(内容分发网络/内容分发网络)等加载第三方脚本。

    2020 年 8 月 12 日更新:

    在回复您的评论时,由于您提到您的第三方脚本来自您无法将“异步”或“延迟”属性编码到脚本标签中的插件,您可以考虑在其他脚本之前添加它:

    <script>
    // If your script tag has an id, use either one below:
    document.getElementById("your_script_tag_id").async = true;
    document.getElementById("your_script_tag_id").defer = true;
    
    // If your script tag has a class name, use either one below:
    document.getElementsByClassName("your_script_tag_class_name")[0].async = true;
    document.getElementsByClassName("your_script_tag_class_name")[0].defer = true;
    
    // If for once and for all scripts, use either one below:
    document.getElementsByTagName("script")[0].async = true;
    document.getElementsByTagName("script")[0].defer = true;
    </script>
    

    您也可以查看:Async JavaScript,这允许您延迟或异步您的 Javascript,包括第三方的。

    【讨论】:

    • 关键渲染路径,虽然非常重要,但与“减少第三方代码的影响”关系不大,即使你推迟它仍然会阻塞主线程。这是提高性能的好建议,OP 你绝对应该这样做(使用defer,除非你知道自己在做什么,async 会破坏你的网站)这个答案不会解决问题。
    • 感谢您如此详细的解释。但这里的问题是,大多数脚本都来自我无法完全控制的 wordpress 插件。
    • 希望我能投票两次,只是为了解释如何在 WordPress 中为 OP 添加 deferasync
    • 嗨@hiew1 感谢您的更新。我只是设法推迟了一些使用它的脚本。但是 WP 插件向我扔了很多东西。这个需要一段时间。 :-) :-)
    【解决方案2】:

    据我所知,您已将 Facebook Messenger 聊天的“延迟”设置为 3 秒。但是,您的网站需要比这更长的时间来加载初始内容。

    由于网络延迟、服务器负载等原因,您的网站通常不会在 3 秒内加载“首屏”内容。

    因此,Facebook Messenger 聊天脚本会在 CPU 可能繁忙或不繁忙的地方加载。对于诸如“总阻塞时间”之类的事情,这很重要,因为它正在侦听 CPU 的第一个静默期,以确定页面何时可用。

    为了计算“第三方代码的影响”,它在尝试渲染“首屏”内容时查看 CPU 何时工作,因此有时它会显示为影响,而有时它有时不会在 Facebook Messenger 初始化之前,您的首屏内容已充分加载。

    此外,您还必须考虑何时加载包含超时的主 JS 文件,有时它会根据延迟等而更快地加载,因此这也会影响添加 fbDiv 的时间。

    为了简化答案(因为要解释为什么会发生这种情况,有很多东西要解释),有很多内容要介绍,那就是增加 Facebook Messenger 的延迟或仅在单击按钮时加载。

    例如,您可以有一个显示“与我们聊天”的按钮,然后使用点击事件加载 facebook messenger(并隐藏“与我们聊天”按钮)。 这是我的建议

    或者查看您网站上的加载速度,您可以将延迟设置为大约 7 秒,然后(可能)会保持一致。

    【讨论】:

    • 优秀的答案!投票!
    • 谢谢!这是问题所在,页面加载时间超过了我指定的延迟间隔。我没有增加延迟时间,而是将 setTimeOut 放在 $(window).load() 内,因此它只会在页面完全加载后加载,而 $(document).ready() 将在此之前被触发。与我们聊天按钮也是一个好主意。
    • 没问题,也执行@hiew1 建议的关于使用defer 或(如果可以的话)async 的建议,因为这是提高一般性能的好建议。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-02
    • 1970-01-01
    • 1970-01-01
    • 2021-08-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多