Reputation: 340
In my UWP app, i constantly navigate from page1 to page 2 and again from page2 to page1 and again this navigation loop repeats on submit button in both the pages. In the application starting it's performance is good but while the page navigates further it is taking more memory and app gets slow after 15 or 20 times of navigation. I tried deleting navigation cache by decreasing it's size but it didn't help and in my research i found if navigation mode is set to enabled it reduces some memory usage. But when i keep it enabled the previous data is not wiping off. I need a solution to delete the memory of previous pages and also make my app to use less memory even after it navigates many times.
Upvotes: 3
Views: 1832
Reputation: 1588
The Problem is the UWP engine does not destroy your page, even if it is no longer in the navigaton Stack.
But there is solution for it:
NavigationCacheMode
in XAML codeOnNavigatedTo()
and when the NavigationMode
is New, the change the NavigationCacheMode
RequiredOnNavigatingFrom()
and when the NavigationMode
is Back, the change the NavigationCacheMode
DisabledWith this mechanism, you can achieve the following: Every page on navigation stack is Cache=Required and every page which is not on navigation stack the Cache=Disabled.
But the are some when the user press the forward the page is newly allocated so the previous state is lost.
In some cases, the Disabled Cache mode in not enough, the UWP still keep the page in memory. In this case we have to delete the cache. We can do this if we reset the current frame cache size to zero and back to original.
Here is my code in every page:
protected override void OnNavigatedTo( NavigationEventArgs navigationEvent )
{
// call the original OnNavigatedTo
base.OnNavigatedTo( navigationEvent );
// when the dialog displays then we create viewmodel and set the cache mode
if( CreatedViewModel == null || navigationEvent.NavigationMode == NavigationMode.New )
{
// set the cache mode
NavigationCacheMode = NavigationCacheMode.Required;
// create viewmodel
CreatedViewModel = CreateViewModel( navigationEvent.Parameter );
DataContext = CreatedViewModel;
CreatedViewModel.InitializeAsync().ConfigureAwait( false );
}
}
protected override void OnNavigatingFrom( NavigatingCancelEventArgs navigationEvent )
{
// call the original OnNavigatingFrom
base.OnNavigatingFrom( navigationEvent );
// when the dialog is removed from navigation stack
if( navigationEvent.NavigationMode == NavigationMode.Back )
{
// set the cache mode
NavigationCacheMode = NavigationCacheMode.Disabled;
ResetPageCache();
}
}
private void ResetPageCache()
{
int cacheSize = ((Frame)Parent).CacheSize;
((Frame)Parent).CacheSize = 0;
((Frame)Parent).CacheSize = cacheSize;
}
Some note: Is more comfortable when you create a BasePage and put this code to it, and you can derive from this BasePage in every Page.
Upvotes: 3