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调试布局问题,识别不必要的组件重绘
- 使用性能浮层()监控帧率
showPerformanceOverlay: true - 使用时间线视图识别卡顿,目标单帧耗时≤16ms(60fps)
- 使用内存视图检测内存泄漏,监控内存分配模式
- 开发阶段使用网络分析器查看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
- 所有控制器、订阅对象、、
Timer都要在AnimationController方法中销毁dispose() - 在中使用
initState()初始化对象,绝对不要内联初始化需要销毁的对象late - 缓存场景使用,避免阻止垃圾回收
WeakReference - 使用DevTools的内存标签页分析内存,注意持续增长的内存分配情况
- 警惕常见泄漏场景:未销毁的监听器、捕获了的闭包、未取消的全局流
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.startSyncTimeline.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而不是红屏报错
- 生产环境绝对不要向用户展示堆栈信息,仅展示友好的错误提示