Files
xianyan/lib/core/utils/performance_optimizer.dart
Developer d2bd53f3bc refactor: 完成v6.5.28版本迭代,修复多项体验问题
主要变更:
1. 重构多处Provider初始化逻辑,使用Future.microtask避免build阶段修改state
2. 重命名"灵感"模块为"工作流","天气诗词"改为"情景诗词"
3. 新增插件系统页面与路由,添加speech_to_text_windows插件支持
4. 优化玻璃容器性能,添加性能节流与模糊值适配
5. 新增离线横幅、阅读体验控制器、手势控制器等组件
6. 完善头像审核状态展示与缓存管理
7. 修复键盘弹出与页面路由问题
8. 更新依赖与项目配置,优化widget默认数据
2026-05-26 01:47:47 +08:00

200 lines
6.1 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// ============================================================
// 闲言APP — 性能优化工具类
// 创建时间: 2026-05-25
// 更新时间: 2026-05-25
// 作用: 全局帧率控制、动画节流、指针事件防抖、GPU负载降级
// 上次更新: 修复currentFrameTimeStamp断言崩溃—使用Stopwatch替代
// ============================================================
import 'dart:async';
import 'package:flutter/widgets.dart';
import 'package:xianyan/core/services/performance/performance_orchestrator.dart';
import 'package:xianyan/core/utils/logger.dart';
/// 动画帧率类别
enum AnimationFpsCategory {
/// 装饰性动画 — full:30fps balanced:24fps saver:15fps
decorative,
/// 空闲动画 — full:20fps balanced:15fps saver:10fps
idle,
/// 交互动画 — full:60fps balanced:40fps saver:30fps
interaction,
}
/// 帧率节流器 — 基于时间戳控制动画更新频率
///
/// AnimationController每帧(60/120fps)触发listener
/// 但widget rebuild才是CPU/GPU开销的大头。
/// FrameRateThrottler在listener中判断是否应该触发rebuild
/// 将rebuild频率从60fps降低到目标帧率。
///
/// 使用Stopwatch计时避免在非帧回调中访问currentFrameTimeStamp
/// 导致_AssertionError('scheduler/binding.dart': _currentFrameTimeStamp != null)
class FrameRateThrottler {
FrameRateThrottler(this._category)
: _stopwatch = Stopwatch()..start(),
_lastUpdateTime = Duration.zero;
final AnimationFpsCategory _category;
final Stopwatch _stopwatch;
Duration _lastUpdateTime;
/// 根据性能级别和动画类别获取目标帧率
int get targetFps {
final level = PerformanceOrchestrator.instance.level;
return switch (_category) {
AnimationFpsCategory.decorative => switch (level) {
PerformanceLevel.full => 30,
PerformanceLevel.balanced => 24,
PerformanceLevel.saver => 15,
},
AnimationFpsCategory.idle => switch (level) {
PerformanceLevel.full => 20,
PerformanceLevel.balanced => 15,
PerformanceLevel.saver => 10,
},
AnimationFpsCategory.interaction => switch (level) {
PerformanceLevel.full => 60,
PerformanceLevel.balanced => 40,
PerformanceLevel.saver => 30,
},
};
}
Duration get _targetInterval => Duration(microseconds: 1000000 ~/ targetFps);
/// 判断本帧是否应该触发UI更新
///
/// 使用Stopwatch.elapsed替代currentFrameTimeStamp
/// 避免在非帧回调期间访问currentFrameTimeStamp触发断言错误。
bool shouldUpdate() {
final now = _stopwatch.elapsed;
if (_lastUpdateTime == Duration.zero ||
now - _lastUpdateTime >= _targetInterval) {
_lastUpdateTime = now;
return true;
}
return false;
}
void reset() {
_stopwatch.reset();
_stopwatch.start();
_lastUpdateTime = Duration.zero;
}
}
/// 防抖值通知器 — 限制值变更通知频率
///
/// 适用于指针移动等高频事件避免每次pointer move都触发rebuild。
/// 在指定时间窗口内只发送最后一次值变更通知。
class DebouncedValueNotifier<T> extends ValueNotifier<T> {
DebouncedValueNotifier(
T initialValue, {
this.debounceDuration = const Duration(milliseconds: 16),
}) : _pendingValue = initialValue,
super(initialValue);
final Duration debounceDuration;
Timer? _debounceTimer;
T _pendingValue;
@override
set value(T newValue) {
if (newValue == _pendingValue) return;
_pendingValue = newValue;
_debounceTimer?.cancel();
_debounceTimer = Timer(debounceDuration, () {
if (_pendingValue != super.value) {
super.value = _pendingValue;
}
});
}
/// 立即更新值(跳过防抖),用于交互结束时确保最终值正确
void updateImmediate(T newValue) {
_debounceTimer?.cancel();
_pendingValue = newValue;
if (newValue != super.value) {
super.value = newValue;
}
}
@override
void dispose() {
_debounceTimer?.cancel();
super.dispose();
}
}
/// 全局性能优化器 — 提供GPU负载降级建议
///
/// 根据PerformanceOrchestrator的当前性能级别
/// 为各组件提供模糊值、粒子数等参数的降级建议。
class PerformanceOptimizer {
PerformanceOptimizer._();
static final PerformanceOptimizer instance = PerformanceOptimizer._();
/// 获取BackdropFilter模糊建议值
double suggestedBlurSigma(double originalSigma) {
final level = PerformanceOrchestrator.instance.level;
return switch (level) {
PerformanceLevel.full => originalSigma,
PerformanceLevel.balanced => originalSigma * 0.7,
PerformanceLevel.saver => originalSigma * 0.5,
};
}
/// 获取粒子数量建议值
int suggestedParticleCount(int originalCount) {
final level = PerformanceOrchestrator.instance.level;
return switch (level) {
PerformanceLevel.full => originalCount,
PerformanceLevel.balanced => (originalCount * 0.6).round().clamp(
1,
originalCount,
),
PerformanceLevel.saver => (originalCount * 0.3).round().clamp(
1,
originalCount,
),
};
}
/// 获取色块数量建议值
int suggestedBlobCount(int originalCount) {
final level = PerformanceOrchestrator.instance.level;
return switch (level) {
PerformanceLevel.full => originalCount,
PerformanceLevel.balanced => (originalCount * 0.8).round().clamp(
2,
originalCount,
),
PerformanceLevel.saver => (originalCount * 0.6).round().clamp(
2,
originalCount,
),
};
}
/// saver模式下禁用BackdropFilter
bool get shouldEnableBackdropFilter =>
PerformanceOrchestrator.instance.level != PerformanceLevel.saver;
/// saver模式下禁用粒子效果
bool get shouldEnableParticles =>
PerformanceOrchestrator.instance.level != PerformanceLevel.saver;
void logDiagnostics() {
final level = PerformanceOrchestrator.instance.level;
final isForeground = PerformanceOrchestrator.instance.isAppForeground;
Log.i(
'PerformanceOptimizer: level=${level.label}, foreground=$isForeground',
);
}
}