Lighthouse 报告里“未使用 JavaScript”是怎么回事?
我在用 Lighthouse 做性能审计时,发现报告里提示“未使用的 JavaScript”,但这些脚本明明是我页面必需的啊。比如下面这段代码:
import { initMap } from './map.js';
import { trackEvent } from './analytics.js';
document.addEventListener('DOMContentLoaded', () => {
initMap();
trackEvent('page_view');
});
我已经在页面加载时调用了这些函数,为什么还被判定为未使用?是不是 Lighthouse 识别不到动态导入或者事件监听里的调用?
DOMContentLoaded这种事件回调、动态import()、或者条件判断里的调用,它都可能误判为“未使用”。你这段代码里,Lighthouse 确实看不到
initMap和trackEvent被实际调用,因为它只扫了 import 语句和顶层作用域,没跑 runtime。解决办法直接用这个:
在构建阶段用
import语法 + 树摇(tree-shaking)支持的打包工具(比如 Vite、Webpack5+),确保只有真正被引用的模块被打进去。如果是自己写的模块,加个sideEffects: false到package.json,再配合 ES Modules 的静态结构,Lighthouse 才不会乱报。如果用了动态
import(),Lighthouse 更容易误判,可以考虑改成静态import,或者用/*#__PURE__*/注释标注无副作用调用,比如:/*#__PURE__*/ trackEvent('page_view')不过最稳妥的方式还是确保模块入口清晰、避免副作用、用标准 ES Modules 结构——别指望 Lighthouse 能像浏览器那样跑一遍代码,它只是个静态扫描器。
最后提醒一句:有时候 report 里标了“未使用”,但其实真有用,这种情况可以加
// @ts-nocheck或者在构建时配置忽略,但别乱忽略,先确认代码确实被用了再动手。你贴的那段代码本身没问题,但问题可能出在打包方式或者入口点没对上。比如你用 Webpack 或 Vite 打包时,如果入口文件没把 map.js 和 analytics.js 真正打进去,或者用了动态 import()(比如条件加载),Lighthouse 就可能把它当“未使用”——因为运行时根本没走到那个 import 分支。
还有个常见坑:Lighthouse 默认是跑在无交互状态下(比如不点按钮、不滚动),所以像你用
DOMContentLoaded触发的逻辑它能测到,但如果 initMap() 里又做了异步请求、DOM 查询失败,或者 map.js 本身被 Tree Shaking 掉了(比如它只 export 了没被用到的函数),也会被误判。建议你这么查:
1. 打开 Chrome DevTools 的 Coverage 面板(Ctrl+Shift+P 输入 coverage),重新加载页面,看 map.js 和 analytics.js 是否真的被标记为“已使用”
2. 如果打包后文件太大,试试用
wp_enqueue_script在 WordPress 里加个条件判断,比如只在特定页面加载 map.js,避免全站塞同一个 bundle3. 如果你用的是 WordPress 自带的 jQuery 或某些插件的 JS,Lighthouse 会把那些“只被老代码调用”的库也标成未使用——这种可以忽略,毕竟它不是你写的入口代码
说白了,Lighthouse 的“未使用 JS”是静态分析的“冷启动覆盖率”,不是“逻辑存在性报告”。你只要确认实际运行时没报错、功能正常,那它就是误报,别被吓到。真要优化,重点看打包体积和 Tree Shaking 配置,而不是硬删代码。