Windows Phone性能优化建议

  • 使用background thread解码图片

     在Windows Phone中支持的图片格式有jpg和png,微软建议使用jpg格式的图片,由于jpg格式的图片在解码速度上要比png快。那么咱们怎么来控制用后台线程来解码图片呢?看下面的代码。html

<Image Height="100" Width="100" Margin="12,0,9,0">
  <Image.Source>
    <BitmapImage UriSource="{Binding ImgURL}" CreateOptions="BackgroundCreation"/>
  </Image.Source>
</Image>
var bi = new BitmapImage();
bi.CreateOptions = BitmapCreateOptions.BackgroundCreation;

     这两段代码都设置了BitmapImage的CreateOptions属性,这样作避免了在UI线程来对图片解码,在使用过程当中BackgroundCreation确实有效地提升了页面的响应效率,尤为是在图片密集型的页面。须要注意的是,图片位置可能出现短暂的空白,不过这段时间咱们能够经过一个图片占位符的方法来处理。CreateOptions属性包括有四种:编程

  1. None                           不对CreateOptions作任何设置。
  2. DelayCreation             是BitmapImage的默认属性,在必要时建立图片。
  3. IgnoreImageCache      图片将不启用缓存,适合于频繁须要更新的图片。
  4. BackgroundCreation    图片的解码在后台线程完成。
  • 减小没必要要的PropertyChanged事件的触发

     在MVVM模式的开发中,经过设置INotifyPropertyChanged接口使View做为一个观察者,可使咱们方便的经过DataBinding更新UI内容,这里咱们要说的其实PropertyChanged事件是一个冗长的方法。若是你使用的是VS2012或更高的版本使用工具栏的Code Map按钮能够看到系统监听的add_PropertyChanged事件,并且它在UI线程上执行。为了减小没必要要的PropertyChanged事件的触发,咱们能够采用下面这种方法来对value的值提早作出判断。缓存

public string Text
{
    get { return _text;}
    set
        {
           if( _text == value) return;
           _text = value;
           RaisePropertyChanged("Text");
         }
}
  • 减小Databinding中Converter的使用

     在Databinding中咱们能够建立一个继承自IValueConverter的类实现Convert方法来对绑定的值作进一步处理,这个处理会直接影响到绑定的速度,并且这个转换是在UI线程执行的,若是咱们把一个很重的方法放在了这个Converter里,那绑定的速度就可想而知了。总之,对后台数据的处理仍是在后台线程中准备好以后在通知UI更新,尽可能避免由于Converter形成的UI阻塞。异步

  • 开启集合控件的虚拟化

     在以前的一篇博客中咱们介绍了在Windows Phone中集合控件的使用VirtualizingStackPanel是一个重要的概念,在ListBox中默认的Itmes的容器就是VirtualizingStackPanel,这个容器是虚拟化的,不一样于StackPanel。它只建立了大约屏幕可见的数量,而非将ListBox中的Items一次所有建立,随着上下滚动再次建立剩下为显示在屏幕上的内容。这样就大大节省了页面首次渲染的时间。异步编程

     VirtualizingStackPanel还有一个比较重要的属性,就是VirtualizationMode。这个属性有两个值。工具

  1. Standard 每次都会为容器的Item建立新的VirtualizingStackPanel,并回收以前建立的容器。
  2. Recycling 重用以前建立的VirtualizingStackPanel

     显然咱们开启VirtualizingStackPanel的Recycling模式来重用容器,避免新的容器的建立。下面是一个ListBox的示例代码。布局

<ListBox ItemsSource="{StaticResource data}" 
         VirtualizingStackPanel.IsVirtualizing="True"
         VirtualizingStackPanel.VirtualizationMode="Recycling" />
  • 动态加载PivotItem

     在Windows Phone开发中轴心控件Pivot绝对是一个布局很好的选择。可是若是咱们的页面的PivotItem比较多,会直接影响到咱们页面的渲染时间,尤为是在首页的时候,等待的时间可能会更加长。这时候咱们能够考虑动态的加载PivotItem的方法来减轻首次加载页面的时间,咱们只须要在页面定义空的PivotItem,再在OnLoadingPivotItem的事件中动态的建立UserControl并加入到相应的PivotItem的Content中便可。spa

<controls:Pivot x:Name="pivot" OnLoadingPivotItem="OnLoading">
          <controls:PivotItem x:Name="firstItem"/>
</controls:Pivot>                
public void OnLoading(PivotItem item)
{
    if(item.Content == null)
      {
           var userControl = new CustemControl();
           item.Content = userControl;
      }
}
  • 为ObservableCollection添加AddRange方法

     ObservableCollection绝对是数据绑定过程当中重要的集合,使用这个集合能够经过Add方法方便的更新集合。但当数据量大的状况下咱们是否能够考虑自定义一个AddRange方法,来替换掉每次Add的时候触发的NotifyCollectionChangedAction.Add类型的事件。而改用NotifyCollectionChangedAction.Reset使整个页面只刷新一次。那么就来看看这个扩展类的写法。线程

public class ObservableCollectionEx<T> : ObservableCollection<T>
{
    public void AddRange(IEnumerable<T> list)
    {
        foreach (T item in list)
        {
            Items.Add(item);
        }
        OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
        OnPropertyChanged(“Count”);
    }
}
  • 使用Async、await、Task<TResult>异步编程
相关文章
相关标签/搜索