A colleague of mine who is building a Flex mobile application had some performance issues with a list. In short, when he used a pretty heavy custom item renderer (with checkboxes, buttons, and labels) the scrolling performance dropped a lot. When using just a label item renderer everything worked well.
So, we started to debug the code and, as I suspected, the culprit was the layout manager: the virtualization was off.
This was strange as he didn’t turn off the useVirtualLayout flag anywhere in the code – at least not explicitly. So why was the virtualization off? Because he used list.itemRenderFunction to change the item renderer at runtime. If you take a look at the documentation you will find this:
Function that returns an item renderer IFactory for a specific item. You should define an item renderer function similar to this sample function:
function myItemRendererFunction(item:Object):IFactory
Currently, when using itemRendererFunction with a virtual layout (useVirtualLayout=true), item renderer recycling is turned off. Because of this, using itemRendererFunction can cause a performance degradation and is not recommended for mobile. This may be fixed in future versions of Flex.
So, if you use a heavy item renderer and/or you have many items, don’t set the item renderer using the itemRendererFunction method.
Instead, you can wrap your custom item renderer in a ClassFactory object and then assign this object to the list.itemRenderer property. Like this:
var factory:ClassFactory = new ClassFactory(MyCustomItemRenderer);
// set the properties for custom item renderer
factory.properties = {iconField:"thumbnailSmall",
messageField:"description", iconHeight:180, iconWidth:180};
// set the ClassFactory object as the list item renderer
myList.itemRenderer = factory;
There is one more thing. In the example above I used the properties property of the ClassFactory object to set the properties I needed (for example what data property should be used for the message label). You can’t use this approach for setting CSS properties like fontSize. The only solution I found so far is to create setters that behind the scenes are doing something like this:
public class MyCustomItemRenderer {
//...
public function set fontSize(value:int):void {
setStyle("fontSize", value);
}
//...
}
This was my tip of the week. And don’t forget, stay away from useVirtualLayout = false;