Thursday, May 03, 2012

Windows Phone development: Improving the startup time and responsiveness of your application

I’m sure you all know the certification rule of how long your app is allowed to load (if not, here’s a big tip: go read the certification requirements and guides – it’ll save you a lot of time later on). Now, assuming you’re familiar with that rule I won’t cover it any further, nor will I cover the how & why of the below, I’m just going to leave you with one more option to improve startup time instead of just transferring load to the Loaded event..

Here’s what you really should avoid

Fetching data in the constructor is never a good idea.

    public partial class MainPage : PhoneApplicationPage
    {
        // Constructor
        public MainPage()
        {
            InitializeComponent();

            // here you really shouldn't be loading anything since the first frame hasn't fired yet, but let's assume that you did..
            ViewModel.RunMyDataFetchingStuff();
        }
    }

And here’s how you normally avoid the above

Deferring load to the Loaded event of the page let’s the app fire the first rendered frame.

    public partial class MainPage : PhoneApplicationPage
    {
        // Constructor
        public MainPage()
        {
            InitializeComponent();
            // transfer loading to only run after the first frame..
            this.Loaded += new RoutedEventHandler(MainPage_Loaded);
        }

        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            // aaaaaand here we load some data..
            ViewModel.RunMyDataFetchingStuff(); 
        }
    }

If you still experience delays here’s an extension to the above alternative

If you think there’s still room for improvement when it comes to loading your views, try using a timer to further defer the load past the regular Loaded event.

    public partial class MainPage : PhoneApplicationPage
    {
        DispatcherTimer firstTimer = new DispatcherTimer();

        // Constructor
        public MainPage()
        {
            InitializeComponent();

            // hook up timer..
            firstTimer.Interval = TimeSpan.FromMilliseconds(500);
            firstTimer.Tick += new EventHandler(firstTimer_Tick);
            // transfer loading to only run after the first frame..
            this.Loaded += new RoutedEventHandler(MainPage_Loaded);
        }

        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            // and off we go - tick, tick, tick, tick, boom!
            firstTimer.Start();
        }
        void firstTimer_Tick(object sender, EventArgs e)
        {
            firstTimer.Stop(); 
            // aaaaaand here we instead load some data, ‘cause here we really should be clear of any initial freeze..
            ViewModel.RunMyDataFetchingStuff(); 
        }
    }

Performance issues can be a pain for any developer to tackle, but also for the end user. Try to focus on the experience you initially set out to create, then attack each issue one at a time. There’s plenty of patterns, tutorials and guidance out there in case you need help. As a start you can look here, here, here, here or here.

Needless to say the above won’t act as a cleaver on your startup time, but it might help.

No comments: