Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Crea aplicaciones para la Plataforma universal de Windows (UWP) con tiempos de inicio óptimos mediante la mejora de la forma en que controlas el inicio y la activación.
Procedimientos recomendados para el rendimiento de inicio de la aplicación
En parte, los usuarios perciben si la aplicación es rápida o lenta en función del tiempo que se tarda en iniciarse. Para los fines de este tema, el tiempo de inicio de una aplicación comienza cuando el usuario inicia la aplicación y finaliza cuando el usuario puede interactuar con la aplicación de alguna manera significativa. En esta sección se proporcionan sugerencias sobre cómo sacar un mejor rendimiento de la aplicación cuando se inicia.
Medición del tiempo de inicio de la aplicación
Asegúrese de iniciar la aplicación varias veces antes de medir realmente su tiempo de inicio. Esto le proporciona un punto de referencia para su medición y asegura que está midiendo el tiempo de inicio lo más breve y razonable posible.
Cuando la aplicación para UWP llega a los equipos de los clientes, la aplicación se ha compilado con la cadena de herramientas .NET Native. .NET Native es una tecnología de compilación anticipada que convierte MSIL en código de máquina ejecutable de forma nativa. Las aplicaciones .NET Native se inician más rápido, usan menos memoria y usan menos batería que sus homólogos de MSIL. Las aplicaciones construidas con .NET Native vinculan estáticamente un tiempo de ejecución personalizado y el nuevo .NET Core convergente que puede ejecutarse en todos los dispositivos, por lo que no dependen de la implementación de .NET preinstalada. En tu máquina de desarrollo, de forma predeterminada, tu aplicación usa .NET Native si la compilas en configuración de lanzado, y usa CoreCLR si la compilas en configuración de depuración. Puede configurarlo en Visual Studio desde la página Compilar de "Propiedades" (C#) o Compilar>Avanzadas en "Mi proyecto" (VB). Busque una casilla que diga "Compile with .NET Native Toolchain" (Compilar con la cadena de herramientas nativa de .NET).
Por supuesto, debe tomar medidas que sean representativas de lo que experimentará el usuario final. Por lo tanto, si no está seguro de que está compilando la aplicación en código nativo en el equipo de desarrollo, puede ejecutar la herramienta Generador de imágenes nativas (Ngen.exe) para precompilar la aplicación antes de medir su tiempo de inicio.
En el procedimiento siguiente se describe cómo ejecutar Ngen.exe para precompilar la aplicación.
Ejecutar Ngen.exe
Ejecute la aplicación al menos una vez para asegurarse de que Ngen.exe lo detecte.
Abra el programador de tareas realizando una de las siguientes acciones:
- Busque "Programador de tareas" en la pantalla de inicio.
- Ejecute "taskschd.msc".
En el panel izquierdo de Programador de Tareas, expanda Biblioteca del Programador de Tareas.
Expanda Microsoft.
Expanda Windows.
Seleccione .NET Framework.
Seleccione .NET Framework NGEN 4.x en la lista de tareas.
Si usa un ordenador de 64 bits, también hay un .NET Framework NGEN v4.x 64. Si va a compilar una aplicación de 64 bits, seleccione .NET Framework NGEN v4.x 64.
En el menú de acción , haga clic en Ejecutar.
Ngen.exe precompila todas las aplicaciones del equipo que se han usado y no tienen imágenes nativas. Si hay muchas aplicaciones que deben precompilarse, esto puede tardar mucho tiempo, pero las ejecuciones posteriores son mucho más rápidas.
Al volver a compilar la aplicación, la imagen nativa ya no se usa. En su lugar, la aplicación se compila Just-In-Time, lo que significa que se compila a medida que se ejecuta la aplicación. Debe volver a ejecutar Ngen.exe para obtener una nueva imagen nativa.
Aplazar el trabajo siempre que sea posible
Para mejorar el tiempo de inicio de la aplicación, haga solo el trabajo que absolutamente debe realizarse para permitir que el usuario empiece a interactuar con la aplicación. Esto puede ser especialmente beneficioso si puede retrasar la carga de ensamblajes adicionales. Common Language Runtime carga un ensamblado la primera vez que se usa. Si puedes minimizar el número de ensamblados que se cargan, es posible que puedas mejorar el tiempo de inicio de la aplicación y su consumo de memoria.
Realizar trabajos de ejecución prolongada de forma independiente
La aplicación puede ser interactiva aunque haya partes de la aplicación que no sean totalmente funcionales. Por ejemplo, si la aplicación muestra datos que tardan un tiempo en recuperarse, puede hacer que ese código se ejecute independientemente del código de inicio de la aplicación recuperando los datos de forma asincrónica. Cuando los datos estén disponibles, rellene la interfaz de usuario de la aplicación con los datos.
Muchas de las API de la Plataforma universal de Windows (UWP) que recuperan datos son asincrónicas, por lo que probablemente recuperará datos de forma asincrónica de todos modos. Para obtener más información sobre las API asincrónicas, consulte Llamada a API asincrónicas en C# o Visual Basic. Si haces trabajo que no usa API asincrónicas, puedes usar la clase Task para realizar trabajos de larga duración para que no impidas que el usuario interactúe con la aplicación. Esto mantendrá la capacidad de respuesta de la aplicación al usuario mientras se cargan los datos.
Si la aplicación tarda mucho tiempo en cargar parte de su interfaz de usuario, considere la posibilidad de agregar una cadena en esa área que diga algo parecido a "Obtener datos más recientes" para que los usuarios sepan que la aplicación sigue procesando.
Minimizar el tiempo de inicio
Todas las aplicaciones más sencillas requieren una cantidad de tiempo perceptible para cargar recursos, analizar XAML, configurar estructuras de datos y ejecutar lógica en la activación. Aquí, analizamos el proceso de activación dividiendolo en tres fases. También proporcionamos sugerencias para reducir el tiempo invertido en cada fase y técnicas para hacer que cada fase del inicio de la aplicación sea más palatable para el usuario.
El período de activación es el tiempo entre el momento en que un usuario inicia la aplicación y el momento en que la aplicación es funcional. Este es un momento crítico porque es la primera impresión de un usuario de la aplicación. Esperan comentarios instantáneos y continuos del sistema y las aplicaciones. El sistema y la aplicación se perciben rotos o mal diseñados cuando las aplicaciones no se inician rápidamente. Aún peor, si una aplicación tarda demasiado tiempo en activarse, el Administrador de duración del proceso (PLM) podría matarlo o el usuario podría desinstalarlo.
Introducción a las fases de inicio
El inicio implica una serie de piezas móviles y todas ellas deben coordinarse correctamente para obtener la mejor experiencia del usuario. Los pasos siguientes se producen entre el usuario que hace clic en el icono de la aplicación y el contenido de la aplicación que se muestra.
- El shell de Windows inicia el proceso y se llama a Main.
- Se crea el objeto Application.
- (Plantilla de proyecto) El constructor llama a InitializeComponent, lo que hace que App.xaml se analice y se creen objetos.
- Se genera el evento Application.OnLaunched.
- (ProjectTemplate) El código de la aplicación crea un marco y navega a MainPage.
- (ProjectTemplate) El constructor Mainpage llama a InitializeComponent, lo que hace que MainPage.xaml se analice y se creen objetos.
- ProjectTemplate) Se llama a Window.Current.Activate().
- La plataforma XAML ejecuta el pase de diseño, incluida la medición y disposición.
- ApplyTemplate hará que el contenido de la plantilla de control se cree para cada control, lo que suele representar la mayor parte del tiempo de disposición durante el inicio.
- Se llama a Render para crear visuales para todo el contenido de la ventana.
- Frame se presenta al Administrador de Windows de escritorio (DWM).
Haz menos en el camino de tu emprendimiento
Mantenga la ruta del código de inicio libre de cualquier cosa que no sea necesaria para su primer fotograma.
- Si tiene dlls de usuario que contienen controles que no son necesarios durante el primer fotograma, considere la posibilidad de retrasar su carga.
- Si tiene una parte de la interfaz de usuario que depende de los datos de la nube, divida esa interfaz de usuario. En primer lugar, abra la interfaz de usuario que no depende de los datos en la nube y abra de forma asincrónica la interfaz de usuario dependiente de la nube. También debe considerar la posibilidad de almacenar en caché los datos localmente para que la aplicación funcione sin conexión o no se vea afectada por la conectividad de red lenta.
- Muestra el indicador de progreso si tu interfaz está esperando datos.
- Tenga cuidado con los diseños de aplicaciones que implican un gran análisis de archivos de configuración o interfaz de usuario que se genera dinámicamente mediante código.
Reducción del número de elementos
El rendimiento de inicio en una aplicación XAML se correlaciona directamente con el número de elementos que se crean durante el inicio. Cuantos menos elementos cree, menos tiempo tardará la aplicación en iniciarse. Como un punto de referencia aproximado, considere que cada elemento tarda 1 milisegundo en crearse.
- Las plantillas usadas en los controles de elementos pueden tener el mayor impacto, ya que se repiten varias veces. Consulte la optimización de la interfaz de usuario de ListView y GridView.
- Los controles de usuario y las plantillas de control se expandirán, por lo que también se deben tener en cuenta.
- Si creas cualquier XAML que no aparezca en la pantalla, debes justificar si esas partes de XAML deben crearse durante el inicio.
La ventana Árbol Visual en Tiempo Real de Visual Studio muestra las cantidades de elementos secundarios para cada nodo del árbol.
Usar aplazamiento. Contraer un elemento o establecer su opacidad en 0 no impedirá que se cree el elemento. Con x:Load o x:DeferLoadStrategy, puede retrasar la carga de una parte de la interfaz de usuario y cargarla cuando sea necesario. Esta es una buena manera de retrasar el procesamiento de la interfaz de usuario que no está visible en la pantalla de inicio, para poder cargarla cuando sea necesario o como parte de un conjunto de lógica diferida. Para desencadenar la carga, solo necesita llamar a FindName para el elemento . Para obtener un ejemplo y más información, vea de atributo x:Load y atributo x:DeferLoadStrategy.
virtualización. Si tiene contenido de lista o repetidor en la interfaz de usuario, se recomienda encarecidamente usar la virtualización de la interfaz de usuario. Si la interfaz de usuario de la lista no está virtualizada, se incurre en el costo de crear todos los elementos por adelantado, lo que puede ralentizar el inicio. Consulte la optimización de la interfaz de usuario de ListView y GridView.
El rendimiento de la aplicación no solo se trata del rendimiento sin procesar, sino también de la percepción. Cambiar el orden de las operaciones para que los aspectos visuales se produzcan primero hará que el usuario sienta que la aplicación es más rápida. Los usuarios considerarán la aplicación cargada cuando el contenido esté en la pantalla. Normalmente, las aplicaciones deben hacer varias cosas como parte del inicio y no todo eso es necesario para abrir la interfaz de usuario, por lo que deben retrasarse o priorizarse por debajo de la interfaz de usuario.
En este tema se habla sobre el "primer fotograma" que procede de la animación/televisión, y es una medida de cuánto tiempo hasta que el usuario final ve el contenido.
Mejora de la percepción del inicio
Vamos a usar el ejemplo de un juego en línea sencillo para identificar cada fase de inicio y diferentes técnicas para proporcionar a los usuarios comentarios a lo largo del proceso. En este ejemplo, la primera fase de activación es el tiempo entre el usuario que pulsa el icono del juego y el juego que empieza a ejecutar su código. Durante este tiempo, el sistema no tiene ningún contenido para mostrar al usuario para incluso indicar que se ha iniciado el juego correcto. Pero proporcionar una pantalla de presentación proporciona ese contenido al sistema. A continuación, el juego informa al usuario de que la primera fase de activación se ha completado reemplazando la pantalla de presentación estática por su propia interfaz de usuario cuando comienza a ejecutar código.
La segunda fase de activación abarca la creación e inicialización de estructuras críticas para el juego. Si una aplicación puede crear rápidamente su interfaz de usuario inicial con los datos disponibles después de la primera fase de activación, la segunda fase es trivial y puede mostrar la interfaz de usuario inmediatamente. De lo contrario, se recomienda que la aplicación muestre una página de carga mientras se inicializa.
El aspecto de la página de carga depende de ti y puede ser tan sencillo como mostrar una barra de progreso o un anillo de progreso. El punto clave es que la aplicación indica que está realizando tareas antes de responder. En el caso del juego, le gustaría mostrar su pantalla inicial, pero esa interfaz de usuario requiere que algunas imágenes y sonidos se carguen desde el disco en la memoria. Estas tareas tardan un par de segundos, por lo que la aplicación mantiene informado al usuario reemplazando la pantalla de presentación por una página de carga, que muestra una animación sencilla relacionada con el tema del juego.
La tercera fase comienza después de que el juego tenga un conjunto mínimo de información para crear una interfaz de usuario interactiva, que reemplaza la página de carga. En este momento, la única información disponible para el juego en línea es el contenido que la aplicación cargó desde el disco. El juego puede enviar con suficiente contenido para crear una interfaz de usuario interactiva; pero como es un juego en línea, no será funcional hasta que se conecte a Internet y descargue información adicional. Hasta que tenga toda la información que necesita para ser funcional, el usuario puede interactuar con la interfaz de usuario, pero las funcionalidades que requieren datos adicionales de la web deben informar que el contenido aún se está cargando. Una aplicación puede tardar algún tiempo en funcionar completamente, por lo que es importante que la funcionalidad esté disponible lo antes posible.
Ahora que hemos identificado las tres fases de activación en el juego en línea, vamos a vincularlas al código real.
Fase 1
Antes de que se inicie una aplicación, debe indicar al sistema lo que quiere mostrar como pantalla de presentación. Para ello, proporciona una imagen y un color de fondo al elemento SplashScreen en el manifiesto de una aplicación, como en el ejemplo. Windows muestra esto después de que la aplicación inicie la activación.
<Package ...>
...
<Applications>
<Application ...>
<VisualElements ...>
...
<SplashScreen Image="Images\splashscreen.png" BackgroundColor="#000000" />
...
</VisualElements>
</Application>
</Applications>
</Package>
Para obtener más información, consulta Agregar una pantalla de presentación.
Use el constructor de la aplicación solo para inicializar estructuras de datos críticas para la aplicación. Solo se llama al constructor la primera vez que se ejecuta la aplicación y no necesariamente cada vez que se activa la aplicación. Por ejemplo, no se llama al constructor para una aplicación que se ha ejecutado, se coloca en segundo plano y, a continuación, se activa a través del contrato de búsqueda.
Fase 2
Hay varias razones para que una aplicación se active, cada una de las cuales puede que quiera controlar de forma diferente. Puede sobrescribir OnActivated, OnCachedFileUpdaterActivated, OnFileActivated, OnFileOpenPickerActivated, OnFileSavePickerActivated, OnLaunched, OnSearchActivatedy OnShareTargetActivated métodos para controlar cada motivo de activación. Una de las cosas que debe hacer una aplicación en estos métodos es crear una interfaz de usuario, asignarla a Window.Contenty, a continuación, llamar a Window.Activate. En este momento, la pantalla de presentación se reemplaza por la interfaz de usuario que creó la aplicación. Este elemento visual podría ser una pantalla de carga o la interfaz de usuario real de la aplicación si hay suficiente información disponible en el momento de la activación para crearlo.
public partial class App : Application
{
// A handler for regular activation.
async protected override void OnLaunched(LaunchActivatedEventArgs args)
{
base.OnLaunched(args);
// Asynchronously restore state based on generic launch.
// Create the ExtendedSplash screen which serves as a loading page while the
// reader downloads the section information.
ExtendedSplash eSplash = new ExtendedSplash();
// Set the content of the window to the extended splash screen.
Window.Current.Content = eSplash;
// Notify the Window that the process of activation is completed
Window.Current.Activate();
}
// a different handler for activation via the search contract
async protected override void OnSearchActivated(SearchActivatedEventArgs args)
{
base.OnSearchActivated(args);
// Do an asynchronous restore based on Search activation
// the rest of the code is the same as the OnLaunched method
}
}
partial class ExtendedSplash : Page
{
// This is the UIELement that's the game's home page.
private GameHomePage homePage;
public ExtendedSplash()
{
InitializeComponent();
homePage = new GameHomePage();
}
// Shown for demonstration purposes only.
// This is typically autogenerated by Visual Studio.
private void InitializeComponent()
{
}
}
Partial Public Class App
Inherits Application
' A handler for regular activation.
Protected Overrides Async Sub OnLaunched(ByVal args As LaunchActivatedEventArgs)
MyBase.OnLaunched(args)
' Asynchronously restore state based on generic launch.
' Create the ExtendedSplash screen which serves as a loading page while the
' reader downloads the section information.
Dim eSplash As New ExtendedSplash()
' Set the content of the window to the extended splash screen.
Window.Current.Content = eSplash
' Notify the Window that the process of activation is completed
Window.Current.Activate()
End Sub
' a different handler for activation via the search contract
Protected Overrides Async Sub OnSearchActivated(ByVal args As SearchActivatedEventArgs)
MyBase.OnSearchActivated(args)
' Do an asynchronous restore based on Search activation
' the rest of the code is the same as the OnLaunched method
End Sub
End Class
Partial Friend Class ExtendedSplash
Inherits Page
Public Sub New()
InitializeComponent()
' Downloading the data necessary for
' initial UI on a background thread.
Task.Run(Sub() DownloadData())
End Sub
Private Sub DownloadData()
' Download data to populate the initial UI.
' Create the first page.
Dim firstPage As New MainPage()
' Add the data just downloaded to the first page
' Replace the loading page, which is currently
' set as the window's content, with the initial UI for the app
Window.Current.Content = firstPage
End Sub
' Shown for demonstration purposes only.
' This is typically autogenerated by Visual Studio.
Private Sub InitializeComponent()
End Sub
End Class
Las aplicaciones que muestran una página de carga en el controlador de activación comienzan a funcionar para crear la interfaz de usuario en segundo plano. Una vez creado ese elemento, se produce su evento FrameworkElement.Loaded. En el controlador de eventos, reemplaza el contenido de la ventana, que actualmente es la pantalla de carga, por la página principal recién creada.
Es fundamental que una aplicación con un período de inicialización extendido muestre una página de carga. Además de proporcionar los comentarios del usuario sobre el proceso de activación, el proceso se finalizará si no se llama a Window.Activate en un plazo de 15 segundos desde el inicio del proceso de activación.
partial class GameHomePage : Page
{
public GameHomePage()
{
InitializeComponent();
// add a handler to be called when the home page has been loaded
this.Loaded += ReaderHomePageLoaded;
// load the minimal amount of image and sound data from disk necessary to create the home page.
}
void ReaderHomePageLoaded(object sender, RoutedEventArgs e)
{
// set the content of the window to the home page now that it's ready to be displayed.
Window.Current.Content = this;
}
// Shown for demonstration purposes only.
// This is typically autogenerated by Visual Studio.
private void InitializeComponent()
{
}
}
Partial Friend Class GameHomePage
Inherits Page
Public Sub New()
InitializeComponent()
' add a handler to be called when the home page has been loaded
AddHandler Me.Loaded, AddressOf ReaderHomePageLoaded
' load the minimal amount of image and sound data from disk necessary to create the home page.
End Sub
Private Sub ReaderHomePageLoaded(ByVal sender As Object, ByVal e As RoutedEventArgs)
' set the content of the window to the home page now that it's ready to be displayed.
Window.Current.Content = Me
End Sub
' Shown for demonstration purposes only.
' This is typically autogenerated by Visual Studio.
Private Sub InitializeComponent()
End Sub
End Class
Para ver un ejemplo de uso de pantallas de presentación extendidas, consulte el ejemplo de pantalla de inicio .
Fase 3
Solo porque la aplicación muestra la interfaz de usuario no significa que esté completamente lista para su uso. En el caso de nuestro juego, la interfaz de usuario se muestra con marcadores de posición para las características que requieren datos de Internet. En este momento, el juego descarga los datos adicionales necesarios para que la aplicación sea totalmente funcional y permite progresivamente las características a medida que se adquieren los datos.
A veces, gran parte del contenido necesario para la activación se puede empaquetar con la aplicación. Tal es el caso de un juego simple. Esto hace que el proceso de activación sea bastante sencillo. Pero muchos programas (como lectores de noticias y visores de fotos) deben extraer información de la web para ser funcional. Estos datos pueden ser grandes y tardar bastante tiempo en descargarse. La forma en que la aplicación obtiene estos datos durante el proceso de activación puede tener un gran impacto en el rendimiento percibido de una aplicación.
Puedes mostrar una página de carga, o peor, una pantalla de presentación, durante minutos si una aplicación intentó descargar un conjunto de datos completo que necesita para la funcionalidad en la fase uno o dos de la activación. Esto hace que una aplicación parezca bloqueada o que el sistema la termine. Se recomienda que una aplicación descargue la cantidad mínima de datos para mostrar una interfaz de usuario interactiva con elementos de marcador de posición en la fase 2 y, a continuación, cargar progresivamente los datos, que reemplaza los elementos de marcador de posición, en la fase 3. Para obtener más información sobre cómo tratar los datos, consulta Optimizar ListView y GridView.
La forma en que una aplicación reacciona a cada fase de inicio depende completamente de ti, pero proporcionar al usuario tanta retroalimentación como sea posible (pantalla de presentación, pantalla de carga, interfaz de usuario mientras se cargan los datos) hace que el usuario perciba que la aplicación y el sistema en su conjunto son rápidos.
Minimizar los ensamblados administrados en la ruta de inicio
El código reutilizable suele tener la forma de módulos (DLL) incluidos en un proyecto. Cargar estos módulos requiere acceder al disco y, como imaginarás, el costo de hacerlo puede acumularse. Esto tiene el mayor impacto en el inicio en frío, pero también puede tener un impacto en el inicio cálido. En el caso de C# y Visual Basic, CLR intenta retrasar ese costo tanto como sea posible cargando ensamblados a petición. Es decir, CLR no carga un módulo hasta que un método ejecutado hace referencia a él. Por lo tanto, haga referencia solo a los ensamblados necesarios para el inicio de la aplicación en el código de inicio para que CLR no cargue módulos innecesarios. Si tiene rutas de acceso de código no usadas en la ruta de acceso de inicio que tienen referencias innecesarias, puede mover estas rutas de acceso de código a otros métodos para evitar las cargas innecesarias.
Otra manera de reducir las cargas de módulos es combinar los módulos de la aplicación. La carga de un ensamblado grande suele tardar menos tiempo que cargar dos pequeños. Esto no siempre es posible y solo debe combinar módulos si no hace una diferencia material para la productividad del desarrollador o la reutilización de código. Puede usar herramientas como PerfView o el Analizador de rendimiento de Windows (WPA) para averiguar qué módulos se cargan al iniciarse.
Realización de solicitudes web inteligentes
Puedes mejorar drásticamente el tiempo de carga de una aplicación empaquetando su contenido localmente, incluidos XAML, imágenes y cualquier otro archivo importante para la aplicación. Las operaciones de disco son más rápidas que las operaciones de red. Si una aplicación necesita un archivo determinado en la inicialización, puede reducir el tiempo de inicio general cargando desde el disco en lugar de recuperarlo desde un servidor remoto.
Páginas de registro y caché de forma eficiente
El control Frame proporciona características de navegación. Ofrece navegación a un Page (método Navigate), registro en diario de navegación (propiedades BackStack/ForwardStack, método GoForward/GoBack), almacenamiento en caché de páginas (Page.NavigationCacheMode) y compatibilidad con la serialización (método GetNavigationState).
El rendimiento que se debe tener en cuenta con Frame se basa principalmente en el registro en diario y el almacenamiento en caché de páginas.
de registro en diario frame . Al navegar a una página con Frame.Navigate(), se agrega una clase PageStackEntry para la página actual a la colección Frame.BackStack. PageStackEntry es relativamente pequeño, pero no hay ningún límite integrado para el tamaño de la colección BackStack. Potencialmente, un usuario podría navegar por un bucle y aumentar esta colección indefinidamente.
PageStackEntry también incluye el parámetro que se pasó al método Frame.Navigate(). Se recomienda que ese parámetro sea un tipo serializable primitivo (como int o string), para permitir que el método Frame.GetNavigationState() funcione. Pero ese parámetro podría hacer referencia a un objeto que tenga en cuenta cantidades más significativas de conjuntos de trabajo u otros recursos, lo que hace que cada entrada en BackStack sea mucho más costosa. Por ejemplo, podría usar un StorageFile como parámetro y, por tanto, BackStack mantiene abierto un número indefinido de archivos.
Por lo tanto, se recomienda mantener pequeños los parámetros de navegación y limitar el tamaño de BackStack. BackStack es un vector estándar (IList en C#, Platform::Vector en C++/CX), por lo que se puede recortar simplemente quitando entradas.
almacenamiento en caché de páginas. De forma predeterminada, al navegar a una página con el método Frame.Navigate, se crea una instancia nueva de la página. Del mismo modo, si vuelve a la página anterior con Frame.GoBack, se asigna una nueva instancia de la página anterior.
Sin embargo, Frame ofrece una caché de páginas opcional que puede evitar estas instanciaciones. Para obtener una página puesta en la memoria caché, use la propiedad Page.NavigationCacheMode. Si establece ese modo en Obligatorio, la página se almacenará en caché, si se establece en Habilitado, se permitirá almacenarla en caché. De forma predeterminada, el tamaño de caché es de 10 páginas, pero esto se puede invalidar con la propiedad Frame.CacheSize. Todas las páginas requeridas se almacenarán en caché y, si hay menos páginas requeridas que el tamaño del caché, también se pueden almacenar en caché las páginas habilitadas.
El almacenamiento en caché de páginas puede ayudar al rendimiento evitando las instancias y, por tanto, mejorando el rendimiento de la navegación. El almacenamiento en caché de páginas puede afectar al rendimiento mediante el almacenamiento en caché excesivo y, por tanto, afectar al conjunto de trabajo.
Por lo tanto, se recomienda usar el almacenamiento en caché de páginas según corresponda para la aplicación. Por ejemplo, supongamos que tiene una aplicación que muestra una lista de elementos en un marco y, al pulsar en un elemento, navega el marco a una página de detalles de ese elemento. Es probable que la página de lista se establezca en caché. Si la página de detalles es la misma para todos los elementos, probablemente también debe almacenarse en caché. Pero si la página de detalles es más heterogénea, es posible que sea mejor dejar el almacenamiento en caché.