HariPrasad kasavajjala
HariPrasad kasavajjala

Reputation: 340

Delete navigation cache in UWP

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

Answers (1)

György Gulyás
György Gulyás

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:

  1. Do not use the NavigationCacheMode in XAML code
  2. On every page must override OnNavigatedTo() and when the NavigationMode is New, the change the NavigationCacheMode Required
  3. On every page must override OnNavigatingFrom() and when the NavigationMode is Back, the change the NavigationCacheMode Disabled

With 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

Related Questions