前端调试神器Eruda实战:从集成到高效排查问题
项目初期的技术选型
上个月接了个H5活动页的活儿,甲方要求快速上线,页面要适配各种安卓机,还得支持微信内置浏览器。说实话,这种项目最头疼的不是功能复杂,而是调试——真机上根本看不到 console.log,报错信息全靠猜。以前我都是用 alert 或者临时加个 div 打印日志,但这次逻辑有点绕,涉及 touch 事件、动态加载、还有几个异步回调嵌套,光靠肉眼 debug 简直折磨。
一开始想用 vConsole,但团队里有人之前用过说在低端安卓机上卡得不行。后来翻 GitHub 发现 Eruda 这个库,轻量(压缩后不到 100KB)、API 简单、还能动态开关。关键是它支持 Network 面板,能看请求头和响应体——这点对我特别重要,因为页面要调几个第三方接口,经常返回 403 或格式不对,没网络面板根本没法排查。于是决定试试 Eruda。
核心代码就这几行
引入方式很简单,CDN 直接塞进 HTML 头部就行:
<script src="https://cdn.jsdelivr.net/npm/eruda"></script>
<script>eruda.init();</script>
但项目是 Vue 单页应用,不能全局暴露调试器,尤其上线后必须关掉。所以我做了个环境判断:
if (process.env.NODE_ENV === 'development' || location.search.includes('debug=1')) {
const script = document.createElement('script');
script.src = 'https://cdn.jsdelivr.net/npm/eruda';
script.onload = () => eruda.init();
document.head.appendChild(script);
}
这样平时开发自动开启,线上环境加 ?debug=1 参数就能临时启用。亲测有效,省去了来回打包的麻烦。
最大的坑:性能问题
本以为万事大吉,结果测试同事拿一台红米 Note 8 Pro 跑页面,直接卡成幻灯片。我一开始还以为是业务逻辑问题,反复检查动画和循环,最后发现只要打开 Eruda 的 Console 面板,FPS 就掉到 10 以下。
折腾了半天才发现,Eruda 默认会记录所有 console 输出,包括高频的日志(比如我在 touchmove 里打了坐标日志)。低端机内存小,大量日志堆积导致频繁 GC,页面自然卡顿。更坑的是,即使关闭面板,日志还在后台默默记录——这设计有点反人类。
解决方法有两个方向:要么限制日志量,要么动态销毁实例。我试了第一种,在关键位置加了日志开关:
// 全局日志开关
const DEBUG_LOG = false;
function log(...args) {
if (DEBUG_LOG && window.eruda) {
console.log(...args);
}
}
// touchmove 里改成 log(e.touches[0].pageX, e.touches[0].pageY)
但这样改起来太麻烦,每个 log 都要包一层。后来翻 Eruda 文档发现它支持配置项,可以限制最大日志条数:
eruda.init({
defaults: {
console: {
displayUnenumerable: false,
maxLogCount: 50 // 默认是1000,改成50
}
}
});
改完后低端机流畅多了,不过还是有轻微卡顿。最终方案是:只在需要调试时手动开启,用完立刻点右上角 × 关闭面板。虽然麻烦点,但至少保证了基础体验。
另一个隐藏雷区:z-index 冲突
项目里有个弹窗组件用了 fixed 定位,z-index 设了 9999。结果 Eruda 的调试面板默认 z-index 是 100000,覆盖在弹窗上面——用户点不了弹窗按钮,以为页面坏了。这事在测试阶段差点被当成严重 bug。
查了源码发现 Eruda 的 z-index 是写死的,没法通过配置改。我只能暴力覆盖 CSS:
.eruda-app {
z-index: 2147483647 !important; /* 比弹窗高就行 */
}
但这样可能影响其他组件。后来想到个取巧办法:在初始化时动态调整弹窗的 z-index。不过考虑到调试器只是临时工具,最终决定让弹窗的 z-index 降到 10000 以下,毕竟正常用户看不到调试器,优先保证调试体验。
最终的解决方案
综合下来,我的 Eruda 使用方案定型了:
- 按需加载:仅开发环境或带 debug 参数时加载,避免污染生产环境
- 限制日志量:maxLogCount 设为 50,防止内存爆炸
- 手动开关:告诉测试同事“用完记得关面板”,并在页面加了个醒目的提示
- 样式隔离:用 !important 强制提升 z-index,避免 UI 冲突
附上完整初始化代码:
// utils/debug.js
export function initEruda() {
if (process.env.NODE_ENV !== 'production' || location.search.includes('debug=1')) {
const script = document.createElement('script');
script.src = 'https://cdn.jsdelivr.net/npm/eruda';
script.onload = () => {
eruda.init({
defaults: {
console: {
maxLogCount: 50
}
}
});
// 强制提升 z-index
const style = document.createElement('style');
style.textContent = .eruda-app { z-index: 2147483647 !important; };
document.head.appendChild(style);
// 页面顶部加提示
const tip = document.createElement('div');
tip.textContent = '【调试模式】用完请关闭右上角面板!';
tip.style.cssText =
position: fixed;
top: 0;
left: 0;
width: 100%;
background: #ff6b6b;
color: white;
text-align: center;
font-size: 14px;
padding: 4px 0;
z-index: 2147483646;
;
document.body.appendChild(tip);
};
document.head.appendChild(script);
}
}
在 main.js 里调用一下就行。这套方案上线后没再出过问题,测试效率也提上来了——以前查个接口错误要半小时,现在两分钟搞定。
回顾与反思
Eruda 确实解决了移动端调试的燃眉之急,尤其 Network 面板救了我好几次。但它的性能开销比想象中大,绝不能直接扔生产环境不管。另外文档有点简略,像 maxLogCount 这种关键配置藏得深,得自己翻源码。
现在回头看,其实还可以优化两点:一是把日志输出重定向到远程服务器(比如用 Sentry),彻底避开前端性能问题;二是做个简易的本地日志面板,只显示关键信息。不过项目周期紧,这些属于“锦上添花”,暂时搁置了。
目前方案虽然糙了点,但够用。唯一的小遗憾是,有些安卓机(比如华为老机型)偶尔会屏蔽 Eruda 的 touch 事件,导致面板点不动——但这概率很低,且不影响主流程,就没深究。
以上是我踩坑后的总结,希望对你有帮助。如果你有更好的 Eruda 使用姿势,或者遇到类似问题,欢迎评论区交流!

暂无评论