flutter-debugging
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseLogging
日志记录
- Use a centralized class for all logging — NEVER use
AppLoggeror rawprint()debugPrint() - Define log levels: ,
verbose,debug,info,warning,errorfatal - In dev flavor: log everything (verbose and above)
- In staging: log info and above
- In production: log warning and above only, route to Crashlytics
- Include context in logs:
AppLogger.error('Failed to fetch user', error: e, stackTrace: st) - NEVER log sensitive data (passwords, tokens, PII) at any level
- 使用统一的 类处理所有日志,绝对不要使用
AppLogger或原生print()debugPrint() - 定义日志等级:、
verbose、debug、info、warning、errorfatal - 开发环境:记录所有等级日志(verbose及以上)
- 预发布环境:记录info及以上等级日志
- 生产环境:仅记录warning及以上等级日志,并上报至Crashlytics
- 日志中需包含上下文信息:例如
AppLogger.error('Failed to fetch user', error: e, stackTrace: st) - 任何日志等级下都绝对不要记录敏感数据(密码、令牌、PII个人可识别信息)
Flutter DevTools
Flutter DevTools
- Use Widget Inspector to debug layout issues and identify unnecessary rebuilds
- Use Performance Overlay () to monitor frame rates
showPerformanceOverlay: true - Use Timeline View to identify jank — target 16ms per frame (60fps)
- Use Memory View to detect memory leaks and monitor allocation patterns
- Use Network Profiler to inspect Dio requests/responses during development
- 使用 Widget Inspector 调试布局问题,识别不必要的组件重绘
- 使用 Performance Overlay()监测帧率
showPerformanceOverlay: true - 使用 Timeline View 识别卡顿,目标为每帧16ms(60fps)
- 使用 Memory View 检测内存泄漏,监测内存分配模式
- 使用 Network Profiler 在开发阶段检查Dio请求/响应
Debugging Strategies
调试策略
- Layout Issues: Use to visualize widget boundaries
debugPaintSizeEnabled = true - Overflow Errors: Check — use
RenderFlex overflowed,Expanded, or constrain dimensionsFlexible - Unbounded Height: Wrap in
ListViewor useSizedBoxwithshrinkWrap: trueNeverScrollableScrollPhysics - Rebuild Tracking: Add temporarily to identify excessive rebuilds — remove before commit
debugPrint('$runtimeType rebuild') - Async Errors: Always catch and log errors in blocks with stack traces
try-catch - Use for development-time invariant checks that are stripped in release builds
assert()
- 布局问题:设置 可视化组件边界
debugPaintSizeEnabled = true - 溢出错误:排查 问题,使用
RenderFlex overflowed、Expanded或限制尺寸解决Flexible - 高度无界问题:将 包裹在
ListView中,或搭配SizedBox和shrinkWrap: true使用NeverScrollableScrollPhysics - 重绘追踪:临时添加 识别过度重绘,代码提交前务必删除
debugPrint('$runtimeType rebuild') - 异步错误:始终在 块中捕获并记录错误及堆栈信息
try-catch - 使用 做开发阶段不变量检查,该语句会在Release构建中自动移除
assert()
Memory Management
内存管理
- Dispose ALL controllers, subscriptions, , and
TimerinAnimationControllerdispose() - Use initialization in
late— never inline-initialize disposable objectsinitState() - Use for caches that should not prevent garbage collection
WeakReference - Profile memory with DevTools Memory tab — watch for monotonically increasing allocations
- Watch for common leaks: undisposed listeners, closures capturing , global streams without cancellation
BuildContext
- 在 方法中释放所有控制器、订阅、
dispose()和TimerAnimationController - 在 中使用
initState()初始化可释放对象,绝对不要内联初始化需要销毁的对象late - 缓存场景使用 ,避免阻止垃圾回收
WeakReference - 使用DevTools的Memory标签页分析内存,关注持续增长的内存分配情况
- 注意常见泄漏场景:未释放的监听器、捕获了的闭包、未取消的全局流
BuildContext
Performance Profiling
性能分析
- Always profile with mode (not debug):
--profileflutter run --profile --flavor dev -t lib/main_dev.dart - Use /
Timeline.startSyncfor custom performance tracing of critical pathsTimeline.finishSync - Monitor shader compilation jank on first run — use for warmup:
--cache-skslbashflutter run --profile --cache-sksl --purge-persistent-cache - Target metrics: < 16ms frame build time, < 100ms screen transition, < 2s cold start
- 始终使用 模式(而非debug模式)进行性能分析:
--profileflutter run --profile --flavor dev -t lib/main_dev.dart - 对关键路径使用 /
Timeline.startSync做自定义性能打点Timeline.finishSync - 监测首次运行时的着色器编译卡顿,使用 进行预热:
--cache-skslbashflutter run --profile --cache-sksl --purge-persistent-cache - 目标指标:帧构建耗时<16ms,页面切换耗时<100ms,冷启动耗时<2s
Error Boundaries
错误边界
- Route errors to Crashlytics in staging/prod ()
FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterFatalError - Set and
FlutterError.onErrorto catch framework and async errorsPlatformDispatcher.instance.onError - Wrap critical widget subtrees in custom error boundary widgets that show fallback UI instead of red screens
- In release mode: NEVER show stack traces to users — show user-friendly error messages only
- 预发布/生产环境将错误上报至Crashlytics:
FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterFatalError - 配置 和
FlutterError.onError捕获框架错误和异步错误PlatformDispatcher.instance.onError - 为关键组件子树包裹自定义错误边界组件,展示兜底UI而非红屏错误
- 生产环境:绝对不要向用户展示堆栈信息,仅展示友好的错误提示