1
votes

A very well known fact to improve the performance of a Flex app is to reduce the amount of nested containers, yet doing so seems particularly hard for me to do.

I'm developing a mobile app and resizing some of my components at runtime is quite slow (I can switch components to fullscreen and back again), we're speaking of 500-1000ms, which isn't really nice. Less complex components resize instantly with no noticeable lag, which is what I'd like for all components.

Let's assume the following component (simplified of course and some groups are components by themselves, but the nesting level is quite accurate);

<VGroup "the component's base">

   // I guess this is fine
   <HGroup "the component's title bar">
       <SkinnableContainer "title bar skin">
            <title bar components, labels etc. />
       </SkinnableContainer>
   </HGroup>

   <HGroup "options bar that has switchable components">
      <button />
      <array "holds 'views' for the options bar that can be switched">
           <HGroup "one option view">
               <option view contents, labels etc. />
           </HGroup>
           <HGroup "another option view">
               <option view contents, labels etc. />
           </HGroup>
      </array>
     <button />
   </HGroup>

That's it for the basic component layout. I'm not sure if the options bar can be optimised, the two buttons are used to switch the content which itself is placed between the buttons, hence the upper HGroup. The components inside the array need to be aligned horizontally as well, hence the child HGroups. That's already down to nesting level 3 in this component, which by itself is already a level 3 container (due to my navigation).

To the component's content area;

     <Group "this is the content area">

     // this group needs two different layouts (vertical and horizontal) that
     // are switched based upon the user's choice of having the component maximised
     // or minimised 
     <layouts />

     // this list changes it's size based on the selected layout
     <List />

     this group also changes it's size based on the layout
     <VGroup>
        <scroller>
            // the group here holds a large label that needs to be scrollable
            <group>
        </scroller>
        <HGroup>
            <some basic components like `SkinnableContainer` and `Label` />
        </HGroup> 
     </VGroup>
   </Group>

And that's pretty much the layout of my worst performing (layout resizing wise) component, closing tag...

</VGroup>

... and we're done.

So the big question, is there room to optimise this? If so, where can I start? Obviously the layout manager has to calculate quite much during the layout switching process. Unfortunately, since this is a mobile app, I can't work with absolute sizes at all as I need this app to work on a variety of platforms and resolutions, thus all groups have relative sizes assigned, usually 100% for both width and height.

I'd really like to streamline this, but I just don't know where to start. Any tips what I could do?

2
Are you certain the lag is caused by the layout and not by the data? I mean: have you tried removing all bindings and all dynamic data and replaced it with static filler content to see whether the lag may come from there?RIAstar
During the resizing, the data is actually static and has been set to the corresponding fields directly, so no bindings whatsoever. That's why I thing the lag is caused by the layout process (which is switched using states).AlBirdie

2 Answers

2
votes

I was in charge of much of the same thing for a previous project, and while there was no 1 magic bullet that eliminated a chunk of problems, it fell in line with the "death by a thousand papercuts" theory.

A few examples of improvement based on yours:

The TitleBar: The skinnable container also has a layout property, why not just eliminate the outer Group shell, and start with the SC as the base?

<!-- <HGroup "the component's title bar"> -->
   <SkinnableContainer id="originalGroupId" "title bar skin">
       <layout>
          <HorizontalLayout /> 
       <layout>
       <title bar components, labels etc. />
   </SkinnableContainer>
<!-- </HGroup> -->

The OptionsBar: I don't know if there are limitations in the mobile space, but can you use a container that uses the INavigatorContent interface? IE. Something that will essentially use a creationPolicy flag that will only create the grandchildren of the container until the user actually requests it. With groups there is no concept of virtualization so all components get created at the instantiation of the parent.

<ViewStack "options bar that has switchable components">
  <button />
</ViewStack>

The Component Area: This gets a little more challenging, sometimes it helps (at least it does for me) to take a 10,000ft view of what information you really want to display. For instance, the scrolling for a really long label, can you use something like a TextAera instead? If so that would eliminate the outer shell:

// the group here holds a large label that needs to be scrollable
<TextArea text="my really large label">

</TextArea>

Hope that helps...

0
votes

Might be irrelevant, but I'd also advise against using Lists. Maybe it's not the same, but I changed one of my components from using List to dynamic skin parts and rendering of said component was noticeably faster (600 vs 100ms). Lists are pretty heavy in Spark.