refactor: optimize startup

This commit is contained in:
cogwheel0
2025-09-28 20:59:19 +05:30
parent ba1176a181
commit f08259be2b
5 changed files with 85 additions and 67 deletions

View File

@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:shared_preferences/shared_preferences.dart';
@@ -207,9 +208,12 @@ final socketServiceProvider = Provider<SocketService?>((ref) {
authToken: token,
websocketOnly: transportMode == 'ws',
);
// best-effort connect; errors handled internally
// ignore unawaited_futures
s.connect();
// best-effort connect, but defer to post-frame with a small delay
WidgetsBinding.instance.addPostFrameCallback((_) async {
await Future.delayed(const Duration(milliseconds: 150));
// ignore: discarded_futures
s.connect();
});
// Keep socket token up-to-date without reconstructing the service
ref.listen<String?>(authTokenProvider3, (prev, next) {
s.updateAuthToken(next);
@@ -881,24 +885,28 @@ final backgroundModelLoadProvider = Provider<void>((ref) {
// Ensure API token updater is initialized
ref.watch(apiTokenUpdaterProvider);
// Schedule background loading without blocking
Future.microtask(() async {
// Wait a bit to ensure auth is complete
await Future.delayed(const Duration(milliseconds: 200));
// Only run when authenticated, and defer until after first frame
final navState = ref.read(authNavigationStateProvider);
if (navState != AuthNavigationState.authenticated) {
return;
}
DebugLogger.log('bg-start', scope: 'models/background');
WidgetsBinding.instance.addPostFrameCallback((_) {
// Schedule background loading without blocking startup frame
Future.microtask(() async {
// Small delay to allow initial build/layout to settle
await Future.delayed(const Duration(milliseconds: 250));
// Load default model in background
try {
await ref.read(defaultModelProvider.future);
DebugLogger.log('bg-complete', scope: 'models/background');
} catch (e) {
// Ignore errors in background loading
DebugLogger.error('bg-failed', scope: 'models/background', error: e);
}
DebugLogger.log('bg-start', scope: 'models/background');
try {
await ref.read(defaultModelProvider.future);
DebugLogger.log('bg-complete', scope: 'models/background');
} catch (e) {
DebugLogger.error('bg-failed', scope: 'models/background', error: e);
}
});
});
// Return immediately, don't block the UI
return;
});

View File

@@ -149,11 +149,15 @@ final appStartupFlowProvider = Provider<void>((ref) {
Future.microtask(() async {
final online = ref.read(isOnlineProvider);
if (!online) return;
// Slightly increase jitter to reduce contention on startup
final jitter = Duration(
milliseconds: 50 + (DateTime.now().millisecond % 100),
milliseconds: 150 + (DateTime.now().millisecond % 200),
);
await Future.delayed(jitter);
_scheduleConversationWarmup(ref);
// Defer until after first frame to keep first paint smooth
WidgetsBinding.instance.addPostFrameCallback((_) async {
await Future.delayed(jitter);
_scheduleConversationWarmup(ref);
});
});
// One-time, post-frame system UI polish: set status bar icon brightness to