3 Replies Latest reply on Dec 12, 2006 11:27 AM by peterent

    Performance on Repeater with DataPrvider

    t3rMan
      Just using a tile object with a repeater within that binded to a dataprovider. I am using this to generate a bunch of thumbnails of images for a photoblog experiment. However it seems to be perform incredibly slowly when doing any reasonable amount of numbers. For instance if I make an array of 100 images (which is not alot) it takes for ever and quite frequently crashes Internet Explorer. Taking out the dataprovider element speeds it up in the output window which i have created where i just write out the array but obviously defeats the whole purpose. Am i missing something silly here? Is it not meant for this? Doing this in flash 8 would write it out in a flash, pardon the pun... Don't get it, even when i am just writing out plain boxes without an image in it, it takes forever. I am sure that this is not meant to be the case but a few examples of this where I have seen it it has been the same. The flickr example on flex examples page does the same.

      Is there another better way of doing this or is this the only and best solution flex has to offer. If so its back to flash i'm afraid which would be a shame as flex seems to have some lovely features.

      Code pasted below if anyone can help...


      main.mxml

      <?xml version="1.0" encoding="utf-8"?>
      <mx:Application
      xmlns:mx=" http://www.adobe.com/2006/mxml"
      layout="absolute"
      backgroundGradientColors="[#000000, #383838]"
      initialize="onCreationComplete( event );" xmlns:local="*">


      <mx:Script>
      <![CDATA[

      import mx.collections.ArrayCollection;
      import mx.utils.ObjectProxy;
      import flash.filters.*
      import flash.display.*;

      [Bindable]
      public var photos:ArrayCollection = new ArrayCollection([]);
      public function onCreationComplete(_event:Event):void{
      writeList();
      // for(var i:int = 0;i<100;i++){
      // var oTempObj:ObjectProxy = new ObjectProxy({name:'LisaThumb.jpg'})
      // photos.addItem(new ObjectProxy({name:'LisaThumb.jpg'}));
      // };
      };

      public function writeList():void{
      for(var i:int = 0;i<100;i++){
      var oTempObj:ObjectProxy = new ObjectProxy({name:'LisaThumb.jpg'})
      photos.addItem(new ObjectProxy({name:'LisaThumb.jpg'}));
      text0.htmlText += i + "<br/>";
      };
      };

      public function imageClicked(event:flash.events.MouseEvent):void{
      //var selectedItem = Thumbnail(event.currentTarget);
      //trace(selectedItem);
      }

      ]]>
      </mx:Script>

      <mx:Canvas id="myContainer" left="10" top="10" right="10" bottom="10">

      <mx:Tile id="myTile" left="10" direction="horizontal" top="150" right="300" bottom="30" borderStyle="solid" borderThickness="7" borderColor="#414141" paddingTop="10" paddingBottom="10" paddingRight="10" paddingLeft="10" verticalGap="10" horizontalGap="10">
      <mx:Repeater id="rp" dataProvider="{photos}">
      <local:Thumbnail click="imageClicked(event)" data="{rp.currentItem}" index="{rp.currentIndex}"/>
      </mx:Repeater>
      </mx:Tile>

      <mx:TextArea id="text0" text="This is where my text goes" width="280" right="10" bottom="30" top="200" fontFamily="Times New Roman" fontSize="14"/>
      <mx:HBox backgroundColor="#414141" left="10" right="10" top="10" height="90">
      </mx:HBox>
      <mx:HBox backgroundColor="#df285e" left="10" right="10" top="110" height="30">
      </mx:HBox>
      <mx:Button click="writeList()" y="150" label="Write List" right="10"/>
      </mx:Canvas>
      </mx:Application>



      Thumbnail.mxml


      <?xml version="1.0" encoding="utf-8"?>

      <mx:Canvas xmlns:mx=" http://www.adobe.com/2006/mxml" width="150" height="150" backgroundColor="#414141">
      <mx:Script>
      <![CDATA[

      public var index:int = 0;

      ]]>
      </mx:Script>

      <mx:Parallel id="darken">
      <mx:Fade alphaFrom=".4" alphaTo=".2" duration="500" target="{frame}" />
      </mx:Parallel>
      <mx:Parallel id="brighten">
      <mx:Fade alphaFrom=".2" alphaTo=".4" duration="500" target="{frame}" />
      </mx:Parallel>

      <mx:Canvas id="frame" x="0" y="0"
      width="150"
      height="150"
      alpha=".2"
      visible="true"
      rollOverEffect="brighten"
      rollOutEffect="darken"
      >


      </mx:Canvas>
      <!-- <mx:Label text="LOADING" left="10" right="10" textAlign="center" verticalCenter="0" color="#ffffff" fontWeight="bold"/>
      <mx:Image useHandCursor="true" source="LisaThumb.jpg" width="130" height="130" left="10" top="10"/> -->
      </mx:Canvas>


        • 1. Re: Performance on Repeater with DataPrvider
          peterent Level 2
          Using a Repeater with a Tile for images is something I've done a few times with reasonable performance. But I see a red flag in your code. In your writeList function you use addItem on the collection. That's correct, but the collection is dynamically bound to the Repeater - also correct. You normally want this so that changes can be picked up and reflected in the UI.

          However, doing this in a loop can cause the Repeater to re-execute code and re-create components. I recommend that you do these two things:

          1. In writeList, before the loop do: photos.disableAutoUpdate(); and then after the loop do photos.enableAutoUpdate(). This will prevent the collection from dispatching change events in the middle of loop.

          2. Add recycleChildren="true" to the Repeater. This will make sure the Repeater doesn't create any unnecessary components.

          • 2. Re: Performance on Repeater with DataPrvider
            t3rMan Level 1
            Thanks Peter, first time i've posted and its fixed the problem. 1 out of 1 = 100% :)
            Its still not amazing with massive amounts but I can understand that. I guess I will need to use pagination of sorts to get the best effect. Quick question. What is the best way to do this without taking a hit on the initial load of the app because at the moment it is done on the onCreationComplete and doesn't show anything until that command is done. Should I start an onEnterFrame and then execute on frame 10 or something??? Thanks for your help though - you can tell i'm a newb (embarrassingly) to flex. Give me 5 mins though and i'll catch up :)
            • 3. Re: Performance on Repeater with DataPrvider
              peterent Level 2
              The Repeater is the slowest Flex component. It really isn't meant as a data viewer, a TileList is more fitting. But TileList can be slow to scroll since it re-uses its renderers to bring in new data. Its kind of a trade-off.

              You can execute your writeList on the initialize event of the root tag of the file. Since you are using dataBinding and not directly modifying any UIComponents this is pretty safe.