zoukankan      html  css  js  c++  java
  • Windows Phone性能优化建议

    • 使用background thread解码图片

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

    <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中即可。

    <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>异步编程
  • 相关阅读:
    MVC设计模式
    二十三种设计模式
    描绘质量属性的六个常见属性场景。
    《架构漫谈》读后感
    软件架构师的工作过程
    《架构之美》阅读笔记06
    《架构之美》阅读笔记05
    《架构之法》阅读笔记04
    《架构之美》阅读笔记03
    《构架之美》阅读笔记02
  • 原文地址:https://www.cnblogs.com/ghostwutao/p/3650408.html
Copyright © 2011-2022 走看看