Skip to content

Commit

Permalink
perf: faster app startup time by ~1 second
Browse files Browse the repository at this point in the history
achieved by using sync methods. since most of the functions are executed on startup only
  • Loading branch information
MSOB7YY committed Aug 18, 2024
1 parent f7cc288 commit e3791da
Show file tree
Hide file tree
Showing 21 changed files with 83 additions and 79 deletions.
6 changes: 3 additions & 3 deletions lib/base/settings_file_writer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ mixin SettingsFileWriter {
Duration get delay => const Duration(seconds: 2);

@protected
Future<dynamic> prepareSettingsFile_() async {
final file = await File(filePath).create(recursive: true);
dynamic prepareSettingsFile_() {
final file = File(filePath)..createSync(recursive: true);
try {
return await file.readAsJson();
return file.readAsJsonSync();
} catch (e) {
printy(e, isError: true);
}
Expand Down
12 changes: 8 additions & 4 deletions lib/controller/backup_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,11 @@ class BackupController {
}

Future<void> _readNewFiles() async {
await settings.prepareSettingsFile();
settings.equalizer.prepareSettingsFile();
settings.player.prepareSettingsFile();
settings.youtube.prepareSettingsFile();
settings.prepareSettingsFile();

Indexer.inst.prepareTracksFile();

QueueController.inst.prepareAllQueuesFile();
Expand All @@ -289,12 +293,12 @@ class BackupController {

PlaylistController.inst.prepareAllPlaylists();
HistoryController.inst.prepareHistoryFile().then((_) => Indexer.inst.sortMediaTracksSubListsAfterHistoryPrepared());
await PlaylistController.inst.prepareDefaultPlaylistsFile();
// await QueueController.inst.prepareLatestQueue();
PlaylistController.inst.prepareDefaultPlaylistsFile();
// await QueueController.inst.prepareLatestQueueSync();

YoutubePlaylistController.inst.prepareAllPlaylists();
YoutubeHistoryController.inst.prepareHistoryFile();
await YoutubePlaylistController.inst.prepareDefaultPlaylistsFile();
YoutubePlaylistController.inst.prepareDefaultPlaylistsFile();
YoutubeInfoController.utils.fillBackupInfoMap(); // for history videos info.
}
}
17 changes: 9 additions & 8 deletions lib/controller/indexer_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -151,18 +151,18 @@ class Indexer {
return (null, null);
}

Future<void> prepareTracksFile() async {
void prepareTracksFile() {
_fetchMediaStoreTracks(); // to fill ids map

/// Only awaits if the track file exists, otherwise it will get into normally and start indexing.
if (await File(AppPaths.TRACKS).existsAndValid()) {
await readTrackData();
if (File(AppPaths.TRACKS).existsAndValidSync()) {
readTrackData();
_afterIndexing();
}

/// doesnt exists
else {
await File(AppPaths.TRACKS).create();
File(AppPaths.TRACKS).createSync();
refreshLibraryAndCheckForDiff(forceReIndex: true, useMediaStore: _defaultUseMediaStore);
}
}
Expand Down Expand Up @@ -994,24 +994,25 @@ class Indexer {
await File(AppPaths.TRACKS_STATS).writeAsJson(trackStatsMap.values.map((e) => e.toJson()).toList());
}

Future<void> readTrackData() async {
void readTrackData() {
// reading stats file containing track rating etc.
final statsResult = await _readTracksStatsCompute.thready(AppPaths.TRACKS_STATS);
final statsResult = _readTracksStatsCompute(AppPaths.TRACKS_STATS);
trackStatsMap.value = statsResult;

tracksInfoList.clear(); // clearing for cases which refreshing library is required (like after changing separators)

/// Reading actual track file.
final splitconfig = _createSplitConfig();

final tracksResult = _readTracksFileCompute(splitconfig);
allTracksMappedByPath.value = tracksResult.$1;
allTracksMappedByYTID = tracksResult.$2;
tracksInfoList.value = tracksResult.$3;

printy("All Tracks Length From File: ${tracksInfoList.length}");
}

static Future<Map<Track, TrackStats>> _readTracksStatsCompute(String path) async {
static Map<Track, TrackStats> _readTracksStatsCompute(String path) {
final map = <Track, TrackStats>{};
final list = File(path).readAsJsonSync() as List?;
if (list != null) {
Expand All @@ -1028,7 +1029,7 @@ class Indexer {
return map;
}

static (Map<Track, TrackExtended>, Map<String, List<Track>>, List<Track>) _readTracksFileCompute(_SplitArtistGenreConfig config) {
static (Map<Track, TrackExtended>, Map<String, List<Track>>, List<Track>) _readTracksFileCompute(SplitArtistGenreConfigsWrapper config) {
final map = <Track, TrackExtended>{};
final idsMap = <String, List<Track>>{};
final allTracks = <Track>[];
Expand Down
6 changes: 3 additions & 3 deletions lib/controller/playlist_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -537,11 +537,11 @@ class PlaylistController extends PlaylistManager<TrackWithDate, Track> {
}

@override
Future<GeneralPlaylist<TrackWithDate>?> prepareFavouritePlaylistFunction() async {
return await _prepareFavouritesFile.thready(favouritePlaylistPath);
GeneralPlaylist<TrackWithDate>? prepareFavouritePlaylistFunction() {
return _prepareFavouritesFile(favouritePlaylistPath);
}

static Future<LocalPlaylist?> _prepareFavouritesFile(String path) async {
static LocalPlaylist? _prepareFavouritesFile(String path) {
try {
final response = File(path).readAsJsonSync();
return LocalPlaylist.fromJson(response, TrackWithDate.fromJson);
Expand Down
4 changes: 2 additions & 2 deletions lib/controller/queue_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -221,13 +221,13 @@ class QueueController {
}

/// Assigns the last queue to the [Player]
Future<void> prepareLatestQueue() async {
void prepareLatestQueueSync() {
int index = 0;
final latestQueue = <Playable>[];

// -- Reading file.
try {
final res = await File(AppPaths.LATEST_QUEUE).readAsJson() as Map?;
final res = File(AppPaths.LATEST_QUEUE).readAsJsonSync() as Map?;
if (res != null) {
final t = res['type'] as String? ?? LibraryCategory.localTracks;
final items = res['items'] as List;
Expand Down
7 changes: 4 additions & 3 deletions lib/controller/settings.equalizer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,10 @@ class EqualizerSettings with SettingsFileWriter {
_writeToStorage();
}

Future<void> prepareSettingsFile() async {
final json = await prepareSettingsFile_();
if (json == null) return;
void prepareSettingsFile() {
final json = prepareSettingsFile_();
if (json is! Map) return;

try {
preset = json["preset"];
equalizerEnabled = json["equalizerEnabled"] ?? equalizerEnabled;
Expand Down
7 changes: 4 additions & 3 deletions lib/controller/settings.player.dart
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,10 @@ class _PlayerSettings with SettingsFileWriter {
_writeToStorage();
}

Future<void> prepareSettingsFile() async {
final json = await prepareSettingsFile_();
if (json == null) return;
void prepareSettingsFile() {
final json = prepareSettingsFile_();
if (json is! Map) return;

try {
enableVolumeFadeOnPlayPause.value = json['enableVolumeFadeOnPlayPause'] ?? enableVolumeFadeOnPlayPause.value;
volume.value = json['volume'] ?? volume.value;
Expand Down
8 changes: 4 additions & 4 deletions lib/controller/settings.youtube.dart
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,11 @@ class _YoutubeSettings with SettingsFileWriter {
_writeToStorage();
}

Future<void> prepareSettingsFile() async {
final json = await prepareSettingsFile_();
if (json == null) return;
void prepareSettingsFile() {
final json = prepareSettingsFile_();
if (json is! Map) return;

try {
json as Map;
showChannelWatermarkFullscreen.value = json['showChannelWatermarkFullscreen'] ?? showChannelWatermarkFullscreen.value;
autoStartRadio.value = json['autoStartRadio'] ?? autoStartRadio.value;

Expand Down
6 changes: 3 additions & 3 deletions lib/controller/settings_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -271,9 +271,9 @@ class _SettingsController with SettingsFileWriter {
bool canAskForBatteryOptimizations = true;
bool didSupportNamida = false;

Future<void> prepareSettingsFile() async {
final json = await prepareSettingsFile_();
if (json == null) return;
void prepareSettingsFile() {
final json = prepareSettingsFile_();
if (json is! Map) return;

try {
/// Assigning Values
Expand Down
6 changes: 3 additions & 3 deletions lib/core/translations/language.dart
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class Language extends LanguageKeys {

// -- Assigning default map, used as a backup in case a key doesnt exist in [lang].
final path = inst._getAssetPath(kDefaultLang);
final map = await jsonDecode(await rootBundle.loadString(path)) as Map<String, dynamic>;
final map = jsonDecode(await rootBundle.loadString(path)) as Map<String, dynamic>;
_defaultMap = map.cast();
// ---------

Expand All @@ -69,7 +69,7 @@ class Language extends LanguageKeys {
static Future<List<NamidaLanguage>> getAllLanguages() async {
const path = 'assets/language/langs.json';
final available = await rootBundle.loadString(path);
final availableLangs = await jsonDecode(available) as List?;
final availableLangs = jsonDecode(available) as List?;
return availableLangs?.mapped((e) => NamidaLanguage.fromJson(e)) ?? [];
}

Expand All @@ -82,7 +82,7 @@ class Language extends LanguageKeys {
try {
late Map<String, dynamic> map;
try {
map = trMap ?? await jsonDecode(await rootBundle.loadString(path)) as Map<String, dynamic>;
map = trMap ?? jsonDecode(await rootBundle.loadString(path)) as Map<String, dynamic>;
} catch (e) {
final backupLocal = _backupLocalMaps[lang];
if (backupLocal != null) {
Expand Down
47 changes: 21 additions & 26 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -138,17 +138,14 @@ void mainInitialization() async {
AppDirs.INTERNAL_STORAGE,
]);

await Future.wait([
settings.equalizer.prepareSettingsFile(),
settings.player.prepareSettingsFile(),
settings.youtube.prepareSettingsFile(),
settings.prepareSettingsFile(),
]);
settings.equalizer.prepareSettingsFile();
settings.player.prepareSettingsFile();
settings.youtube.prepareSettingsFile();
settings.prepareSettingsFile();

if (!shouldShowOnBoarding) Indexer.inst.prepareTracksFile();
await Language.initialize();

await Future.wait([
if (!shouldShowOnBoarding) Indexer.inst.prepareTracksFile(),
Language.initialize(),
]);
ConnectivityController.inst.initialize();
NamidaChannel.inst.setCanEnterPip(settings.enablePip.value);

Expand Down Expand Up @@ -179,26 +176,24 @@ void mainInitialization() async {

HistoryController.inst.prepareHistoryFile().then((_) => Indexer.inst.sortMediaTracksSubListsAfterHistoryPrepared());
YoutubeHistoryController.inst.prepareHistoryFile();
await Future.wait([
PlaylistController.inst.prepareDefaultPlaylistsFile(),
if (!shouldShowOnBoarding) QueueController.inst.prepareLatestQueue(),
YoutubePlaylistController.inst.prepareDefaultPlaylistsFile(),
YoutubeController.inst.loadDownloadTasksInfoFile(),
YoutubeSubscriptionsController.inst.loadSubscriptionsFile()
]);

PlaylistController.inst.prepareDefaultPlaylistsFile();
if (!shouldShowOnBoarding) QueueController.inst.prepareLatestQueueSync();

YoutubePlaylistController.inst.prepareDefaultPlaylistsFile();
YoutubeSubscriptionsController.inst.loadSubscriptionsFileSync();
YoutubeController.inst.loadDownloadTasksInfoFileSync();
YoutubePlaylistController.inst.prepareAllPlaylists();

YoutubeInfoController.utils.fillBackupInfoMap(); // for history videos info.

await _initializeIntenties();
_initializeIntenties();

await Future.wait([
SystemChrome.setPreferredOrientations(kDefaultOrientations),
NamidaNavigator.inst.setDefaultSystemUI(),
FlutterDisplayMode.setHighRefreshRate().catchError((_) {}),
]);
SystemChrome.setPreferredOrientations(kDefaultOrientations);
NamidaNavigator.inst.setDefaultSystemUI();
FlutterDisplayMode.setHighRefreshRate().catchError((_) {});

//
NamidaNavigator.inst.setDefaultSystemUIOverlayStyle();

ScrollSearchController.inst.initialize();
Expand Down Expand Up @@ -272,7 +267,7 @@ void _initLifeCycle() {
});
}

Future<void> _initializeIntenties() async {
void _initializeIntenties() {
Future<void> clearIntentCachedFiles() async {
final cacheDir = await pp.getTemporaryDirectory();
await for (final cf in cacheDir.list()) {
Expand All @@ -292,7 +287,7 @@ Future<void> _initializeIntenties() async {
});
}

Future<void> playFiles(List<SharedFile> files) async {
void playFiles(List<SharedFile> files) {
// -- deep links
if (files.length == 1) {
final linkRaw = files.first.value;
Expand Down Expand Up @@ -358,7 +353,7 @@ Future<void> _initializeIntenties() async {
}

// -- Recieving Initial Android Shared Intent.
await playFiles(await FlutterSharingIntent.instance.getInitialSharing());
FlutterSharingIntent.instance.getInitialSharing().then(playFiles);

// -- Listening to Android Shared Intents.
FlutterSharingIntent.instance.getMediaStream().listen(
Expand Down
2 changes: 1 addition & 1 deletion lib/ui/pages/onboarding.dart
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ class _FirstRunConfigureScreenState extends State<FirstRunConfigureScreen> {
},
));
Indexer.inst.prepareTracksFile();
QueueController.inst.prepareLatestQueue();
QueueController.inst.prepareLatestQueueSync();
}

void _onRestoreBackupIconTap() async {
Expand Down
4 changes: 2 additions & 2 deletions lib/ui/widgets/settings/indexer_settings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ class IndexerSettings extends SettingSubpageProvider {
subtitle: "${lang.EXTRACT_FEAT_ARTIST_SUBTITLE} ${lang.INSTANTLY_APPLIES}.",
onChanged: (isTrue) async {
settings.save(extractFeatArtistFromTitle: !isTrue);
await Indexer.inst.prepareTracksFile();
Indexer.inst.prepareTracksFile();
},
value: settings.extractFeatArtistFromTitle.valueR,
),
Expand Down Expand Up @@ -694,7 +694,7 @@ class IndexerSettings extends SettingSubpageProvider {
? null
: () async {
updatingLibrary.value = true;
await Indexer.inst.prepareTracksFile();
Indexer.inst.prepareTracksFile();
},
durationInMs: 200,
dialog: CustomBlurryDialog(
Expand Down
2 changes: 1 addition & 1 deletion lib/ui/widgets/settings/theme_settings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ class ThemeSetting extends SettingSubpageProvider {
if (path != null) {
try {
final st = await File(path).readAsString();
final map = await jsonDecode(st);
final map = jsonDecode(st);
final didUpdate = await Language.inst.loadLanguage(path.getFilenameWOExt, map);
if (didUpdate) {
NamidaNavigator.inst.closeDialog();
Expand Down
2 changes: 2 additions & 0 deletions lib/ui/widgets/video_widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,15 @@ import 'package:namida/youtube/yt_utils.dart';

class NamidaVideoControls extends StatefulWidget {
final bool showControls;
final double? disableControlsUnderPercentage;
final VoidCallback? onMinimizeTap;
final bool isFullScreen;
final bool isLocal;

const NamidaVideoControls({
super.key,
required this.showControls,
this.disableControlsUnderPercentage,
required this.onMinimizeTap,
required this.isFullScreen,
required this.isLocal,
Expand Down
6 changes: 3 additions & 3 deletions lib/youtube/controller/youtube_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -322,11 +322,11 @@ class YoutubeController {
static const String cleanupFilenameRegex = r'[*#\$|/\\!^:"]';
String cleanupFilename(String filename) => filename.replaceAll(RegExp(cleanupFilenameRegex, caseSensitive: false), '_');

Future<void> loadDownloadTasksInfoFile() async {
await for (final f in Directory(AppDirs.YT_DOWNLOAD_TASKS).list()) {
void loadDownloadTasksInfoFileSync() {
for (final f in Directory(AppDirs.YT_DOWNLOAD_TASKS).listSync()) {
if (f is File) {
final groupName = DownloadTaskGroupName(groupName: f.path.getFilename.splitFirst('.'));
final res = await f.readAsJson() as Map<String, dynamic>?;
final res = f.readAsJsonSync() as Map<String, dynamic>?;
if (res != null) {
final fileModified = f.statSync().modified;
youtubeDownloadTasksMap[groupName] ??= {};
Expand Down
6 changes: 3 additions & 3 deletions lib/youtube/controller/youtube_playlist_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -180,11 +180,11 @@ class YoutubePlaylistController extends PlaylistManager<YoutubeID, String> {
}

@override
Future<YoutubePlaylist?> prepareFavouritePlaylistFunction() async {
return await _prepareFavouritesFile.thready(favouritePlaylistPath);
YoutubePlaylist? prepareFavouritePlaylistFunction() {
return _prepareFavouritesFile(favouritePlaylistPath);
}

static Future<YoutubePlaylist?> _prepareFavouritesFile(String path) async {
static YoutubePlaylist? _prepareFavouritesFile(String path) {
try {
final response = File(path).readAsJsonSync();
return YoutubePlaylist.fromJson(response, (itemJson) => YoutubeID.fromJson(itemJson));
Expand Down
Loading

0 comments on commit e3791da

Please sign in to comment.