Lighthouse提示”优化流程”分数低,动态加载的JS脚本还是导致阻塞渲染怎么办?

轩辕建杰 阅读 25

我在React项目里用useEffect动态加载第三方统计脚本,虽然用了defer属性,但Lighthouse还是显示这个标签造成了渲染阻塞。代码是这样的:


useEffect(() => {
  const script = document.createElement('script');
  script.src = 'https://example.com/tracker.js';
  script.defer = true;
  document.head.appendChild(script);
  return () => script.remove();
}, []);

已经尝试过把script放在footer和设置async/defer,但评分里的”优化流程”还是只有20分。控制台也没报错,这个脚本到底该怎么加载才不会阻塞主线程呢?

我来解答 赞 6 收藏
二维码
手机扫码查看
1 条解答
欧阳一莹
动态加载第三方脚本确实是个常见的性能优化痛点,defer有时候并不能完全解决问题,尤其是Lighthouse这种工具对阻塞渲染的检测比较严格。这里给你一个更优雅的方案,直接通过async加载,并且把脚本放到非关键渲染路径中。

试试这样写:

useEffect(() => {
const loadScript = async () => {
const script = document.createElement('script');
script.src = 'https://example.com/tracker.js';
script.async = true; // 使用async确保不会阻塞渲染
script.onload = () => {
console.log('Tracker script loaded successfully');
};
script.onerror = () => {
console.error('Failed to load tracker script');
};
document.body.appendChild(script); // 放在body里比head更安全
};

loadScript();

return () => {
const existingScript = document.querySelector('script[src="https://example.com/tracker.js"]');
if (existingScript) {
existingScript.remove(); // 清理脚本
}
};
}, []);


这样改有几个好处:
1. 使用了async属性,确保脚本异步加载,不会阻塞HTML解析和渲染。
2. 把脚本加到document.body而不是document.head,进一步降低影响关键渲染路径的风险。
3. 加了onloadonerror事件处理,方便调试和监控加载情况。

如果还是有问题,可以考虑把脚本加载逻辑延迟到首屏渲染完成之后执行,比如用requestIdleCallback或者简单的setTimeout来推迟加载时机。这样更清晰,也能让Lighthouse满意。
点赞 10
2026-02-01 17:02