¿Es lento Windows Phone reanudando aplicaciones?

Windows Phone Resuming screen

Todos hemos visto este mensaje alguna vez, ¿verdad? Este mensaje aparece cuando Windows Phone reanuda una aplicación que se encuentra en segundo plano. La idea de que Windows Phone es lento reanudando aplicaciones cuaja rápidamente al ver este mensaje más a menudo de lo que nos gustaría. A raíz de esto, muchas voces se han alzado pidiendo una mejora notable en la multitarea de Windows Phone. Pero, ¿Es realmente lento Windows Phone reanudando aplicaciones?

En este artículo daremos respuesta a esta cuestión y, para entender el razonamiento, explicaremos teoría y conceptos como los distintos estados de una aplicación Windows Phone, las principales causas de una reanudación lenta, el concepto de Velocidad Percibida y recomendaremos unas buenas prácticas a seguir para minimizar este problema.

Un poco de teoría

Para poder entender mejor el tema en cuestión, es imprescindible que conozcamos cómo gestiona Windows Phone el ciclo de vida de nuestra aplicación.

Una aplicación de Windows Phone puede tener varios estados:

  • Active: la aplicación está en primer plano y está actualmente en uso.
  • Deactivated o Dormant: la aplicación está en segundo plano y no realiza actividad alguna. El sistema operativo no la ha eliminado y la ha mantenido intacta en memoria.
  • Tombstoned: la aplicación ha sido desactivada y posteriormente desechada por el sistema operativo por falta de memoria. Se ha conservado su historial de páginas (back-stack) y los diccionarios de estado que hayamos usado durante su desactivación.

Una de las mayores confusiones entre los desarrolladores de Windows Phone aparece en la (no) distinción entre aplicaciones desactivadas y desechadas. En realidad esto es comprensible, ya que las aplicaciones desechadas quedan guardadas también en el historial del botón Atrás. Además, podemos navegar de vuelta a ellas tal y como lo hacemos con las aplicaciones desactivadas. Sin embargo, hay una gran diferencia entre estos dos estados a la hora de reanudarlas a primer plano.

Además de estos estados de aplicación, las aplicaciones de Windows Phone tienen un número de eventos y métodos relacionados con su ciclo de vida:

  • Launching: este evento se lanza cuando la aplicación se inicia.
  • Deactivated: este evento se lanza cuando la aplicación es desactivada (estado deactivated).
  • Activated: este evento se lanza cuando una aplicación desactivada o desechada se reanuda.
  • Closing: este evento se lanza cuando la aplicación se cierra usando el botón Atrás y cuando la página actual es la última del historial de páginas (back-stack).
  • OnNavigatedFrom: este método se llama cuando el usuario navega a otra página desde una de las páginas de la aplicación. También se ejecuta cuando el usuario navega fuera de la aplicación.
  • OnNavigatedTo: este método se llama cuando el usuario navega a una página. Esto incluye el inicio de la aplicación, cuando el usuario navega entre páginas y cuando la aplicación es reanudada después de estar en estado desactivada o desechada.

Causas de una reanudación lenta

Todo código que se ejecuta en el evento Launching retrasa el inicio de la aplicación. Es por esto que en ocasiones también vemos el mensaje Loading… en pantalla cuando iniciamos desde cero ciertas aplicaciones.

wp_ss_20130719_0003

Tal y como ocurre con el evento Launching, todo código que ejecutemos en el evento Activated hace más lenta la reanudación de la aplicación, y con ello, se muestra el mensaje Resuming… en pantalla.

Relacionado con esto último, una de las mayores causas de una reanudación lenta de una aplicación es ejecutar código innecesario de inicialización en el evento Activated. Al reanudar una aplicación, muchos desarrolladores no comprueban si ésta estaba en el estado desactivada (mantenida en memoria) o desechada. El manejo que debemos hacer para cada estado es distinto. Los desarrolladores pueden comprobar esto a través de la propiedad ActivatedEventArgs.IsApplicationInstancePreserved. Si la instancia de la aplicación ha sido preservada en memoria (deactivated), hay poca inicialización que debamos hacer (por no decir ninguna). En el caso contrario, estaremos ante una aplicación en estado desechada la cual necesitará código de reanudación para dar la sensación al usuario de que ha vuelto a ella tal y como la dejó.

Por tanto, en una situación ideal, únicamente deberíamos ver el mensaje Resuming… cuando volvemos desde una aplicación en estado desechada (tombstoned).

El concepto de Velocidad Percibida

A menudo, la velocidad subjetiva de una aplicación o sistema operativo poco tiene que ver con lo rápido que se ejecute. Para un usuario, una aplicación que se inicie y se reanude rápido y proporcione feedback continuo sobre lo que está pasando será más ligera que una aplicación que simplemente se congela mientras realiza su trabajo. Existen numerosas técnicas para provocar esta sensación en el usuario y cada sistema operativo o aplicación lo hace a su manera.

Entonces, la pregunta es: ¿es buena la velocidad percibida en Windows Phone? No demasiado. La continua aparición de los mensajes de Loading… y Resuming… arruina esa velocidad subjetiva que percibe el usuario frente a la pantalla. En este sentido, iOS es el rey de la velocidad percibida. Además, este sistema operativo no tiene un equivalente al estado de aplicación desechada (tombstoned), siendo más cómodo para los desarrolladores manejar la reanudación y ayudando enormemente a la percepción de velocidad.

Ya sea por malas prácticas del desarrollador o por una necesaria mejora en la gestión de la reanudación de aplicaciones por parte de Windows Phone (mostrar una captura de pantalla del estado de la aplicación justo cuando pasó a segundo plano mientras de reanuda, en vez de los mensajes de carga o reanudación), el resultado es una velocidad percibida deficiente en este sistema operativo. Se esperan mejoras en una próxima versión (Blue), y ya podemos ver mejores implementaciones en Windows 8 y sus aplicaciones de Store, por ejemplo.

Mejorando la reanudación de nuestra aplicación

En última instancia, es labor del desarrollador que la reanudación de las aplicaciones sea rápida. Los siguientes consejos nos ayudarán a conseguir este objetivo:

  • En el evento Launching: ejecutar el mínimo código necesario. No acceder al almacenamiento aislado (isolated storage) o cualquier otra operación intensiva en recursos. Si necesitamos acceder a servicios para autenticarnos, podemos retrasarlo hasta que la aplicación haya cargado o implementar nuestra propia splash screen de carga.
  • En el método OnNavigatedFrom: si no es una navegación hacia atrás, guardar el estado de la UI en el diccionario de Estado.
  • En el evento Deactivated: Guardar el estado de aplicación en el caso de que ésta sea desechada (tombstoned). Además, se recomienda guardar el estado persistente (aquel que siempre necesitaremos entre sesión y sesión) en el almacenamiento aislado en caso de que la aplicación sea terminada por cuestiones de memoria.
  • En el evento Activated: Comprobar la propiedad IsApplicationInstancePreserved. Si es verdadero, no hacer nada. En caso contrario, usar los datos en el Estado para restaurar el estado de la aplicación.
  • En el método OnNavigatedTo: Comprobar si la página es una nueva instancia. Si no lo es, el estado estará intacto. En caso contrario, habrá datos en el Estado. Usarlos para restaurar la UI.
  • En el evento Closing: Guardar datos persistentes de aplicación al almacenamiento aislado. El sistema operativo nos da como máximo 10 segundos para acometer esta tarea.

Aunque en muchos de estos eventos es buen momento para guardar datos de estado, se recomienda guardar estos datos en cuanto se modifiquen, y no esperar a que la aplicación de desactive o se cierre para acometer el guardado.

Conclusiones

¿Es lento Windows Phone reanudando aplicaciones? Sorpresa: la respuesta es No. Windows Phone reanuda las aplicaciones casi al instante. Son las aplicaciones las lentas al reanudar, que es distinto. Por supuesto, y de manera comprensible, para un usuario no técnico, Windows Phone puede parecer lento reanudando aplicaciones. Unido a una mejorable percepción de velocidad por parte de Windows Phone, la mayor razón de todas es una mala codificación de la aplicación que afecta enormemente a su reanudación.

Por tanto, como desarrolladores debemos cuidar la manera en la que gestionamos el ciclo de vida de nuestra aplicación, seguir las buenas prácticas presentadas en este artículo y mejorar la velocidad percibida usando cualquiera de las técnicas que estén a nuestro alcance (splash screens, feedback continuo, precarga de datos, guardado continuo de datos persistentes, retraso de operaciones intensivas, etc.).

Referencias

App activation and deactivation for Windows Phone

4 comentarios en “¿Es lento Windows Phone reanudando aplicaciones?

  1. Buenas,
    Muy buen artículo. Efectivamente este tema es muy importante, y pocas aplicaciones le dan la importancia que debe tener. Ya que con un poco de empeño la reanudación de aplicaciones queda bastante bien.
    Pero si es verdad que Microsoft debe poner más de su parte. Por ejemplo, la característica FAR (Fast Appplication Resume) que se incluyó en WP8, está muy bien, pero debería ser el comportamiento por defecto, u obligar en la certificación su implementación… Ya que pocas aplicaciones lo implementan, y supongo que será por desconocimiento, ya que la dificultad es mínima…
    Por otro lado, la documentación es escasa, y el comportamiento de los eventos necesarios para implementarlo bien, es a veces algo extraño. Por ejemplo, en una App que tengo, necesito cerrar un socket cuando se salga de la aplicación. En WP7, esto se hacía automáticamente e instantáneamente, pero en WP8, puede tardar varios segundos en producirse el cierre del socket. Como lo necesito al instante, lo hago yo por código… pero claro hay estructuras que en esos métodos no se puede usar (Locks, ManualResetEvents,…) vale los elimino, y nada sigue tardando unos segundos en cerrarse el socket… finalmente y por casualidad vi que ejecutando otro código (que no tiene nada que ver) justo antes de efectuar el cierre del socket, este se cierra inmediatamente al salir de la App… (si lo comento, vuelve a tardar…) Algo sin sentido y que no he tenido tiempo de investigarlo bien, y que en la documentación no he encontrado nada…

    Finalmente, perdón por el tocho, y felicidades por el post de nuevo, a ver si mejoran muchas apps en este aspecto…

  2. Hola Daniel,
    Muchas gracias por tu comentario. No estaba al tanto de ese problema al cierre de la aplicación del que hablas. Es bueno saberlo y esperemos que Microsoft mejore en este aspecto porque hay ciertas funcionalidades implementadas de manera algo torpe. Respecto a FAR, no sé si es bueno habilitarlo siempre. Hablo sobre ello en un artículo pasado en este mismo blog (el artículo está en inglés). A ver qué te parece.
    Un saludo.

  3. Buenas,

    En tu post hablas de que hay ciertas apps donde realmente FAR no tiene una mejora notable y es cierto. Pero piensa que cuando la App se queda en estado Deactivated, es decir, se queda en memoria, y volvemos a abrir la App desde el tile o menú, el comportamiento por defecto, es eliminar de memoria la instancia de la App, y volverla a abrir. ¿Por qué no usar siempre la instancia en memoria? no sé si existirá algún problema que yo no veo.
    Pero en definitiva da igual el tipo de aplicación. En las apps ligeras no habría ningún problema (es como si usaras Fast switching), y en las apps donde realmente se saca provecho, estas aprovechando los datos en memoria y obligando a los desarrolladores a implementar correctamente el resume de las apps (algo en lo que fallan muchas apps).

    Así que no veo problema para usar FAR por defecto (ya sea volviendo a la última pagina abierta, o volviendo a cargar la página inicial y eliminado el stack de páginas, esto ya puede depender del tipo de app), pero los servicios, configuración, etc.. ya cargados no habría que volverlos a cargar e inicializar…

    Saludos

Deja un comentario