Search code examples
performanceapache-flexitemrenderer

The optimized way to show text


I am in a process of optimizing item renderers that display a character in a Rect, I notice that the action of dynamically setting the text is slow, now I am thinking of creating premade objects with text hard-coded in them and inside the item-renderer have a switch to select the proper text object instead of using .text = , does anyone have any other idea on how to optimize the renderer , it is a tile layout that displays about 100 renderers on screen.

also - what is the cheapest(performance-wize) text object I can use in a renderer?

Thanks

<!-- DNA Plus -->
<s:Group height="26" width="100%" y="20">
    <s:Rect id="backgroundTop" left="0" right="0" top="0" bottom="0"
            alpha="{(data as MiniBrick).brick.strand == StrandEnum.PLUS.value ? 1 : 0.7}">
        <s:fill>
            <s:SolidColor id="bgFillTop" color="{BrickColors.getColor((data as MiniBrick).brick)}"/>
        </s:fill>
    </s:Rect>

    <s:Rect id="selectedBackgroundTop" left="0" right="0" top="2" bottom="1" includeIn="selected">
        <s:fill>
            <s:SolidColor id="sBgFillTop" color.selected="0xB6E0F2"/>
        </s:fill>
    </s:Rect>

    <!--- @copy spark.components.supportClasses.SkinnableTextBase#textDisplay -->
    <s:Label id="textDisplayTop" width="100%" top="4" fontFamily="Consolas" text="{(data as MiniBrick).origin}"
             fontSize="20" lineBreak="explicit" verticalAlign="middle" textAlign="center"/>
</s:Group>


<!-- DNA Minus -->

<s:Group height="26" width="100%" y="46">
    <s:Rect id="backgroundBottom" left="0" right="0" top="0" bottom="0" 
            alpha="{(data as MiniBrick).brick.strand == StrandEnum.MINUS.value ? 1 : 0.7}">
        <s:fill>
            <s:SolidColor id="bgFillBottom" color="{BrickColors.getColor((data as MiniBrick).brick)}"/>
        </s:fill>
    </s:Rect>

    <s:Rect id="selectedBackgroundBottom" left="0" right="0" top="1" bottom="2" includeIn="selected">
        <s:fill>
            <s:SolidColor id="sBgFillBottom" color.selected="0xB6E0F2"/>
        </s:fill>
    </s:Rect>

    <!--- @copy spark.components.supportClasses.SkinnableTextBase#textDisplay -->
    <s:Label id="textDisplayBottom" width="100%" top="4" fontFamily="Consolas" text="{DnaDictionary.getComplementSequenceOneLetter((data as MiniBrick).origin)}"
             fontSize="20" lineBreak="explicit" verticalAlign="middle" textAlign="center"/>
</s:Group>

<!-- DNA index [tick list] -->
<s:Group width="15" id="dnaTick" y="72">
    <s:Rect horizontalCenter="0" width="2" height="2" radiusX="1">
        <s:fill>
            <s:SolidColor color="#666666"/>
        </s:fill>
    </s:Rect>
    <s:Label id="dnaTickLabel" horizontalCenter="0" y="5" height="9" color="#888888" fontFamily="Arial" fontSize="9"
             textAlign="left" />
</s:Group>

<s:Line id="firstMiniBrickInBrickLine" x="0" y="20" yFrom="72">
    <s:stroke>
        <s:SolidColorStroke caps="none" color="#FFFFFF" weight="1"/>
    </s:stroke>
</s:Line> 

Solution

  • To answer your question directly: the most optimized way to display text is to use the UITextField class. But you're going to have a hard time implementing that into your ItemRenderer since it doesn't inherit from UIComponent.

    Also that is not where the most performance gain is to be made in your code. The biggest problem is that this renderer has 6 data bindings in it. If you have 100 items on screen, that makes for 600 listeners watching for data changes.

    So you should remove all those bindings and set those properties by overriding the ItemRenderer's data setter, like so:

    override public function set data(value:Object):void {
        super.data = value;
    
        var brick:MiniBrick = value as MiniBrick;
        backgroundTop.alpha = brick.brick.strand == StrandEnum.PLUS.value ? 1 : 0.7;
        bgFillTop.color = BrickColors.getColor(brick.brick);
        ...
    }
    

    If you want to optimize even further, I would suggest you put the information for the renderers directly on the data so that it doesn't have to be evaluated every time and you can write the following:

    override public function set data(value:Object):void {
        super.data = value;
    
        var brick:MiniBrick = value as MiniBrick;
        backgroundTop.alpha = brick.alpha;
        bgFillTop.color = brick.color;
        ...
    }