第三方代码阻塞了主线程 - Defer 和 Async 不能解决这个问题

lui*_*7up 6 javascript frontend lighthouse

我正在尝试提高使用第三方 JS 的网站的性能(他们都这样做:))。

运行灯塔分析后,报告显示:

减少第三方代码的影响第三方代码阻塞主线程

由于每个 JS 通过下载、解析和执行脚本来阻塞关键路径,因此我将所有非关键 JS 推到页面底部并添加了defer属性

尽管如此,我仍然认为特定的 JS 资源阻塞了主线程。

推迟资源应该并行下载它,并在渲染完成后执行它,所以我真的不明白为什么 Lighthouse 一直在主线程阻塞资源列表中显示它。当然,它会在主线程上解析和执行,但它不会阻塞关键路径,也不会对用户体验产生太大影响

例如,在不影响 Lighthouse 性能分数的情况下向网页添加 Tidio 聊天小部件的最佳解决方案是什么?

干杯

编辑

我已经测试过,延迟和异步都会阻止主线程

下面的代码也阻止了它

  window.addEventListener('DOMContentLoaded', (event) => {
    var tidioScript = document.createElement("script");
    tidioScript.src = "//code.tidio.co/xxxx.js";
    document.body.appendChild(tidioScript);
  });

Run Code Online (Sandbox Code Playgroud)

有效的方法是显式延迟将脚本标签注入到 DOM 中:

setTimeout(function() {
    var tidioScript = document.createElement("script");
    tidioScript.src = "//code.tidio.co/#{tidio_id}.js";
    document.body.appendChild(tidioScript);
  }, 3 * 1000);
Run Code Online (Sandbox Code Playgroud)

但这感觉就是错误的:/我认为 defer 应该达到相同的结果:/

小智 3

我建议您不要修改任何代码以适应第 3 方脚本。

\n

相反,第 3 方脚本应该适应您的脚本!

\n

因此,要完全控制第 3 方脚本的加载时间,请不要\xe2\x80\x99t 通过 HTML 加载它们,如下所示...

\n
<script src="https://someplace.com/ThirdParty.js" async>\n
Run Code Online (Sandbox Code Playgroud)\n

而是通过 JS 并选择你选择的时间延迟,就像这样......

\n
setTimeout(function(){\n\n let S=document.createElement('script'); S.type='text/javascript';\n\n S.src='https://someplace.com/ThirdParty.js';\n\n try{document.getElementsByTagName('HEAD')[0].appendChild(S);} catch(e){alert(e);}\n\n},3000);\n
Run Code Online (Sandbox Code Playgroud)\n

另外,请尝试保留允许的任何第三方脚本的本地副本,以便尽可能避免加载/计时困境。

\n