Performance for Silverlight Mobile
You can go straight at source to explore this yourself from my skydrive BingImageSearch
This kind of application is pretty common:
Read on to see how I attempted to make this list scroll faster.
I started experimenting with list scrolling for images fetched from Bing, the ImageSearch Apis; Bing Image Search Sample.
Key things to note in the sample
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
// copy the list of bingimages over
this.Items.Add(myItem);
});
So this logic was added
int sleepcounter = 2;
int itemcounter = 0;
foreach (ItemViewModel item in bingImageList)
itemcounter++;
if (itemcounter % sleepcounter == 0)
System.Threading.Thread.Sleep(20);
}
//add a dummy item
var myItem = item;
// copy the data over
HttpWebRequest downloadthumbnailrequest = (HttpWebRequest)thumbnailState.AsyncRequest;
// end the async request
thumbnailState.AsyncResponse = (HttpWebResponse)downloadthumbnailrequest.EndGetResponse(asyncResult);
Stream imageStream = thumbnailState.AsyncResponse.GetResponseStream();
byte[] b = new byte[this.ThumbNailSize];
imageStream.Read(b, 0, this.ThumbNailSize);
imageStream.Close();
MemoryStream ms = new MemoryStream(b);
BitmapImage bmp = new BitmapImage();
bmp.SetSource(ms);
this.ThumbNailImage = bmp;
long deviceTotalMemory = (long)DeviceExtendedProperties.GetValue("DeviceTotalMemory");
long applicationCurrentMemoryUsage = (long)DeviceExtendedProperties.GetValue("ApplicationCurrentMemoryUsage");
long applicationPeakMemoryUsage = (long)DeviceExtendedProperties.GetValue("ApplicationPeakMemoryUsage");
if((((PAGECOUNT*this._currentoffset)+PAGECOUNT)>this.TotalCount)||(applicationCurrentMemoryUsage>(deviceTotalMemory*0.33)) )
return false;
NOTE: Using device memory APIs when submitting to MarketPlace is not a good practice, you might be flagged. Use it only for diagnostic purposes.
private ScrollViewer FindScrollViewerRecursive(UIElement element)
int childCount = VisualTreeHelper.GetChildrenCount(element);
for (int i = 0; i < childCount; i++)
if (VisualTreeHelper.GetChild(element, i) as ScrollViewer != null)
return (VisualTreeHelper.GetChild(element, i) as ScrollViewer);
else
FindScrollViewerRecursive(VisualTreeHelper.GetChild(element, i) as UIElement);
return null;
Used the High Performance Progress Bar from Jeff's blog.
Finally, I implemented the double tap gestures, to launch the browser. Using the Manipulation events is the recommended and performant way to implementing this as opposed to Mouse Events or TouchPanel. ManipulationEvents maintain less data about the touch points and for a simple scenario like double tap, using manipulation events is not a big deal. Wheverever possible, use manipulation events.
This implementation takes benefits of the List's Virtualized Stack Panel to recycle UI containers. There are other solutions that might suit your application like David Anson's solution which removed the VSP and does deferred loading of images, he talks about it in Delay's Blog
Feel free to ask questions, I will get answers to your questions from the team and your feedback will help improve the platform.
Also, any feedback on the blog/article is appreciated. It will help improve how I present the information to you guys.