Google Page Speed Insight 显示不一致的结果
Google Page Speed Insight Shows In-Consistent Results
我有一个 wordpress 网站 运行,我正在使用 W3Total 缓存插件来加快网站加载速度。当我在 Google Page Speed Insight 中扫描站点时,我注意到我得到的扫描结果不一致。我有一个浮动在网页上的 Facebook Messenger 聊天和一个 google 地图。由于这两个给了我 减少第三方代码的影响 警告我已经做了更改,以便只有在 DOM 完全加载后才会加载这两个。实际上我为此使用了 jQuery SetTimeOut。通过这样做,我实际上设法从结果中删除了警告。但时不时地,即使我进行了调整,我也会注意到同样的警告再次出现。如果我经常浏览该网站两到三遍,warnong 可能会关闭,但我会在一段时间后再次尝试。
这些是频繁扫描的结果。你们知道这里会出什么问题吗?我花了很多时间搜索,但无法理解它。
使用经典的 HTTP/1.0 超文本传输协议,Javascript、CSS、HTML、图像等资源在请求/响应对中加载,这意味着浏览器发送一个请求来请求资源(可以是 CSS、Javascript 等),并会等待响应返回,然后再请求另一个资源。尽管它们以请求/响应对的形式加载,但由于网络延迟、服务器响应时间、服务器当前正在承受的负载等的随机性,请求和响应对并不总是严格遵循相同的顺序。
使用 HTTP/2 和 HTTP/3 的较新版本的 HTTP 协议,可以一次发送所有请求,而不是等待响应返回再发送另一个请求。我查看了您的网站,发现您的网站正在使用 HTTP/2 和 HTTP/3。使用 HTTP/2 和 HTTP/3 协议,由于可以一次发送所有请求,因此它也会导致一定程度的“不一致”,等等。即使使用 HTTP 1,也始终存在一定程度的随机性,因为有很多因素会影响它,例如服务器响应时间会有所不同,网络延迟会有所不同等。
为了说明这一点,如果您使用的是 Chrome 浏览器,请单击浏览器右上角的三个点,打开“开发人员工具”选项卡,然后单击“更多工具”然后单击“开发人员工具”。或者,如果您在 Mac 上使用 Windows 或“Command + Option + I”,则可以执行“Ctrl+Shift+I”。然后转到其“网络”选项卡,并刷新页面。每次刷新页面,资源加载的顺序有点不同:
在上图中,以 Google Tag Manager UA-174548329-1 Javascript 为例(我知道它可能不是 Google Map),它被加载为第 4 个资源。
当我再次刷新页面时,您的 Google 标签管理器 UA-174548329-1 Javascript 被加载为 11th 资源:
当页面正在加载时,或者如果您在 Google 的 PageSpeed Insight 上 运行 页面,由于随机性的性质,主线程有时忙,有时不忙请求和响应。您的主线程也在构建 DOM,并做了很多工作。有时它会被 render-blocking 资源阻止,例如 Javascript.
Javascript 默认情况下总是会阻止关键渲染路径。如果不查看您的 Javascript SetTimeOut,很难说出您使用什么实现来延迟您的 Javascript 但可以肯定地假设它可能无助于清除关键渲染路径。您应该使用 defer or async.
而不是使用 SetTimeOut
您可以查看 Critical Rendering Path here. The main thread is the main process your browser is running to do most of the work to process and render the CSS, Javascript, HTML on a page. The critical rendering path is "the sequence of steps the browser goes through to convert the HTML, CSS, and JavaScript into pixels on the screen". - Quoted from Critical Rendering Path。关键渲染路径是 Javascript、HTML、CSS、图像和其他资源的下载和渲染顺序。优化您的关键渲染路径需要大量知识,这绝非易事。但是,您可以尝试在脚本标记中使用两个属性,即“async”和“defer”来控制何时执行您的Javascript。
看看这张图片:
来源:与 Web 一起成长
如您所见,您可以尝试将 async attribute in your script or the defer 属性放入脚本标记中,看看是否有帮助。
在script标签中带有'async'属性,意味着你的Javascript会在下载后立即异步执行。如图所示,<script async>
下方的蓝色条显示在解析 HTML 的同时下载脚本,因为可以看到绿色条和蓝色条正在执行平行线。一旦脚本下载完成,就会立即执行脚本。此时,HTML 解析暂停,直到脚本执行完毕。如果没有 'async' 属性,您的 HTML 解析将在下载和执行脚本时暂停(或阻止)。
在脚本标签中使用 'defer' 属性,这意味着您将推迟 Javascript 的执行,直到 DOM 完成解析。虽然浏览器一收到javascript资源就会下载,但是下载不会阻塞HTML解析。
总而言之,您可以在您的第三方脚本中使用 'async' 属性在一定程度上 'unblock' 您的主线程,它们将在您的 DOM 正在渲染。这会稍微加快主线程的速度。然而,需要注意的是,执行仍将是 render-blocking。需要注意的一个非常重要的事情是,通过使用 'async' 属性,准备好看到页面的一些可能的不稳定行为,因为现在可能会发生更多 'inconsistencies'e Javascript 可以在渲染路径中的任何时间执行,因此如果脚本之前或之后需要发生某些事情,您可能会破坏流程及其逻辑。
或者您可以在第三方脚本中使用 'defer' 属性来告诉您的脚本仅在 DOM 完全加载后才执行。这只能加快进程的速度,只有一点点,因为脚本的下载现在可以在 HTML 解析进行时并行进行,而不是使用默认脚本标记而不指定延迟或异步,但是执行仍然会在主线程上产生开销。
根据Google的支持文档,有一个关于How do you load third-party script efficiently?的部分,这里有一些方法:
"
使用 async 或 defer 属性加载脚本以避免阻止文档解析。
如果 third-party 服务器速度慢,请考虑 self-hosting 脚本。
如果脚本不能为您的站点增加明确的价值,请考虑删除它。
考虑 <link rel=preconnect>
或 <link rel=dns-prefetch>
等资源提示,以对托管 third-party 脚本的域执行 DNS 查找。
"
其他方法:
查看如何将各种 Javascript 文件压缩、缩小或合并为一个文件(如果您使用文件形式的 Javascript)。使用GZIP compression压缩你的Javascript、CSS。另请查看如何使用 CDN(内容分发网络/内容分发网络)等加载第三方脚本。
2020 年 8 月 12 日更新:
针对您的评论,由于您提到您的第三方脚本来自您无法将 'async' 或 'defer' 属性编码到脚本标签中的插件,您可以考虑在你的其他脚本之前添加这个:
<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,包括第三方的。
据我所知,您已将 Facebook Messenger 聊天的“延迟”设置为 3 秒。但是,您的网站加载初始内容所需的时间比这长得多。
由于网络延迟、服务器负载等原因,您的网站通常不会在 3 秒内加载“首屏”内容。
因此,Facebook Messenger 聊天脚本在 CPU 可能忙也可能不忙的时候加载。对于诸如“总阻塞时间”之类的事情,这很重要,因为它正在监听 CPU 何时有第一个安静期来确定页面何时可用。
为了计算“第三方代码的影响”,它正在查看 CPU 何时在尝试呈现“首屏”内容时工作,因此有时它显示为影响和其他有时它不会,因为有时您的首屏内容在 Facebook Messenger 初始化之前已经加载得足够多。
此外,您还必须考虑何时加载包含超时的主 JS 文件,有时它会根据延迟等因素更快地加载。因此这也会影响添加 fbDiv
的时间。
要简化答案(因为有很多东西要解释为什么会发生)要涵盖很多内容,就是增加 Facebook Messenger 的延迟或仅在单击按钮时加载它。
例如,您可以有一个显示“与我们聊天”的按钮,然后使用点击事件加载 facebook Messenger(并隐藏“与我们聊天”按钮)。 这是我的推荐
或者查看您网站上的加载速度,您可以将延迟设置为大约 7 秒,然后它(可能)会保持一致。
我有一个 wordpress 网站 运行,我正在使用 W3Total 缓存插件来加快网站加载速度。当我在 Google Page Speed Insight 中扫描站点时,我注意到我得到的扫描结果不一致。我有一个浮动在网页上的 Facebook Messenger 聊天和一个 google 地图。由于这两个给了我 减少第三方代码的影响 警告我已经做了更改,以便只有在 DOM 完全加载后才会加载这两个。实际上我为此使用了 jQuery SetTimeOut。通过这样做,我实际上设法从结果中删除了警告。但时不时地,即使我进行了调整,我也会注意到同样的警告再次出现。如果我经常浏览该网站两到三遍,warnong 可能会关闭,但我会在一段时间后再次尝试。
这些是频繁扫描的结果。你们知道这里会出什么问题吗?我花了很多时间搜索,但无法理解它。
使用经典的 HTTP/1.0 超文本传输协议,Javascript、CSS、HTML、图像等资源在请求/响应对中加载,这意味着浏览器发送一个请求来请求资源(可以是 CSS、Javascript 等),并会等待响应返回,然后再请求另一个资源。尽管它们以请求/响应对的形式加载,但由于网络延迟、服务器响应时间、服务器当前正在承受的负载等的随机性,请求和响应对并不总是严格遵循相同的顺序。
使用 HTTP/2 和 HTTP/3 的较新版本的 HTTP 协议,可以一次发送所有请求,而不是等待响应返回再发送另一个请求。我查看了您的网站,发现您的网站正在使用 HTTP/2 和 HTTP/3。使用 HTTP/2 和 HTTP/3 协议,由于可以一次发送所有请求,因此它也会导致一定程度的“不一致”,等等。即使使用 HTTP 1,也始终存在一定程度的随机性,因为有很多因素会影响它,例如服务器响应时间会有所不同,网络延迟会有所不同等。
为了说明这一点,如果您使用的是 Chrome 浏览器,请单击浏览器右上角的三个点,打开“开发人员工具”选项卡,然后单击“更多工具”然后单击“开发人员工具”。或者,如果您在 Mac 上使用 Windows 或“Command + Option + I”,则可以执行“Ctrl+Shift+I”。然后转到其“网络”选项卡,并刷新页面。每次刷新页面,资源加载的顺序有点不同:
在上图中,以 Google Tag Manager UA-174548329-1 Javascript 为例(我知道它可能不是 Google Map),它被加载为第 4 个资源。
当我再次刷新页面时,您的 Google 标签管理器 UA-174548329-1 Javascript 被加载为 11th 资源:
当页面正在加载时,或者如果您在 Google 的 PageSpeed Insight 上 运行 页面,由于随机性的性质,主线程有时忙,有时不忙请求和响应。您的主线程也在构建 DOM,并做了很多工作。有时它会被 render-blocking 资源阻止,例如 Javascript.
Javascript 默认情况下总是会阻止关键渲染路径。如果不查看您的 Javascript SetTimeOut,很难说出您使用什么实现来延迟您的 Javascript 但可以肯定地假设它可能无助于清除关键渲染路径。您应该使用 defer or async.
而不是使用 SetTimeOut您可以查看 Critical Rendering Path here. The main thread is the main process your browser is running to do most of the work to process and render the CSS, Javascript, HTML on a page. The critical rendering path is "the sequence of steps the browser goes through to convert the HTML, CSS, and JavaScript into pixels on the screen". - Quoted from Critical Rendering Path。关键渲染路径是 Javascript、HTML、CSS、图像和其他资源的下载和渲染顺序。优化您的关键渲染路径需要大量知识,这绝非易事。但是,您可以尝试在脚本标记中使用两个属性,即“async”和“defer”来控制何时执行您的Javascript。
看看这张图片:
来源:与 Web 一起成长
如您所见,您可以尝试将 async attribute in your script or the defer 属性放入脚本标记中,看看是否有帮助。
在script标签中带有'async'属性,意味着你的Javascript会在下载后立即异步执行。如图所示,<script async>
下方的蓝色条显示在解析 HTML 的同时下载脚本,因为可以看到绿色条和蓝色条正在执行平行线。一旦脚本下载完成,就会立即执行脚本。此时,HTML 解析暂停,直到脚本执行完毕。如果没有 'async' 属性,您的 HTML 解析将在下载和执行脚本时暂停(或阻止)。
在脚本标签中使用 'defer' 属性,这意味着您将推迟 Javascript 的执行,直到 DOM 完成解析。虽然浏览器一收到javascript资源就会下载,但是下载不会阻塞HTML解析。
总而言之,您可以在您的第三方脚本中使用 'async' 属性在一定程度上 'unblock' 您的主线程,它们将在您的 DOM 正在渲染。这会稍微加快主线程的速度。然而,需要注意的是,执行仍将是 render-blocking。需要注意的一个非常重要的事情是,通过使用 'async' 属性,准备好看到页面的一些可能的不稳定行为,因为现在可能会发生更多 'inconsistencies'e Javascript 可以在渲染路径中的任何时间执行,因此如果脚本之前或之后需要发生某些事情,您可能会破坏流程及其逻辑。
或者您可以在第三方脚本中使用 'defer' 属性来告诉您的脚本仅在 DOM 完全加载后才执行。这只能加快进程的速度,只有一点点,因为脚本的下载现在可以在 HTML 解析进行时并行进行,而不是使用默认脚本标记而不指定延迟或异步,但是执行仍然会在主线程上产生开销。
根据Google的支持文档,有一个关于How do you load third-party script efficiently?的部分,这里有一些方法:
"
使用 async 或 defer 属性加载脚本以避免阻止文档解析。
如果 third-party 服务器速度慢,请考虑 self-hosting 脚本。
如果脚本不能为您的站点增加明确的价值,请考虑删除它。
考虑
<link rel=preconnect>
或<link rel=dns-prefetch>
等资源提示,以对托管 third-party 脚本的域执行 DNS 查找。
"
其他方法:
查看如何将各种 Javascript 文件压缩、缩小或合并为一个文件(如果您使用文件形式的 Javascript)。使用GZIP compression压缩你的Javascript、CSS。另请查看如何使用 CDN(内容分发网络/内容分发网络)等加载第三方脚本。
2020 年 8 月 12 日更新:
针对您的评论,由于您提到您的第三方脚本来自您无法将 'async' 或 'defer' 属性编码到脚本标签中的插件,您可以考虑在你的其他脚本之前添加这个:
<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,包括第三方的。
据我所知,您已将 Facebook Messenger 聊天的“延迟”设置为 3 秒。但是,您的网站加载初始内容所需的时间比这长得多。
由于网络延迟、服务器负载等原因,您的网站通常不会在 3 秒内加载“首屏”内容。
因此,Facebook Messenger 聊天脚本在 CPU 可能忙也可能不忙的时候加载。对于诸如“总阻塞时间”之类的事情,这很重要,因为它正在监听 CPU 何时有第一个安静期来确定页面何时可用。
为了计算“第三方代码的影响”,它正在查看 CPU 何时在尝试呈现“首屏”内容时工作,因此有时它显示为影响和其他有时它不会,因为有时您的首屏内容在 Facebook Messenger 初始化之前已经加载得足够多。
此外,您还必须考虑何时加载包含超时的主 JS 文件,有时它会根据延迟等因素更快地加载。因此这也会影响添加 fbDiv
的时间。
要简化答案(因为有很多东西要解释为什么会发生)要涵盖很多内容,就是增加 Facebook Messenger 的延迟或仅在单击按钮时加载它。
例如,您可以有一个显示“与我们聊天”的按钮,然后使用点击事件加载 facebook Messenger(并隐藏“与我们聊天”按钮)。 这是我的推荐
或者查看您网站上的加载速度,您可以将延迟设置为大约 7 秒,然后它(可能)会保持一致。