2

アイテムのレンダリングが含まれるコンボボックスのパフォーマンスを向上させる方法を見つけようとしています。カスタムアイテムレンダラーなしでコンボボックスを使用すると、ドロップダウンがすぐに開き、コンボボックスの応答性が非常に高くなります。単純なアイテムレンダラーを追加すると、コンボボックスを開くまでに1秒かかります。これは、すべての子を作成してからキャッシュするようなものです。その後、アイテムを選択するまで、コンボボックスは正常に開きます。次に、コンボボックスを開くのにもしばらく時間がかかります。

この問題を示すサンプルアプリケーションを次に示します。

<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
            height="100%" width="100%" xmlns:local="*"
    >
<mx:Script><![CDATA[
    import mx.collections.ArrayCollection;

    public var dataProvider:ArrayCollection = new ArrayCollection(
               [{label:"test1"}, 
                {label:"test2"}, 
                {label:"test3"}]);

    ]]></mx:Script>

<!-- combobox with item renderer, this has a delay when opening -->

<mx:ComboBox width="200"
             dataProvider="{dataProvider}">
    <mx:itemRenderer>
        <mx:Component>
            <mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml">
                <mx:Label text="'item renderer' + {data.label}"/>
            </mx:HBox>
        </mx:Component>
    </mx:itemRenderer>
</mx:ComboBox>

<!-- default combobox, this works fine -->

<mx:ComboBox width="200"
             dataProvider="{dataProvider}"/>
</mx:Application>

ここで何が欠けていますか?これが起こっているはずではないようです。

4

2 に答える 2

4

解決策を見つけるためにしばらく時間を費やした後、私が見つけたのは、で定義される「クリーンな」子コンポーネントが1つしかない場合<mx:Component>、パフォーマンスがはるかに向上することです。

したがって、以下は優れたパフォーマンスを提供します。

<mx:Component>
    <mx:HBox /> ( "clean" )
</mx:Component>

そしてこれは悪いパフォーマンス(遅延)を与えます:

<mx:Component>
    <mx:HBox>
        <mx:Label /> ( not "clean" )
    </mx:HBox>
</mx:Component>

この問題を解決するために、コードを使用して子コンポーネントを作成できます。

<mx:itemRenderer>
    <mx:Component>
        <mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml">
            <mx:Script>
                <![CDATA[
                    import mx.controls.Label;

                    // Define the label instance
                    private var lbl:Label = new Label();

                    // Add the label as a child component
                    override protected function createChildren(): void {
                        super.createChildren();
                        addChild( lbl );
                    }

                    // Set the data
                    override public function set data( value:Object ): void {
                        super.data = value;
                        if ( value ) {
                            lbl.text = value.label;
                        }
                    }
                ]]>
            </mx:Script>
        </mx:HBox>
    </mx:Component>
</mx:itemRenderer>

デモ:https ://github.com/jeantimex/flex-combobox-itemrenderer

お役に立てば幸いです。

于 2012-10-05T22:07:55.990 に答える
3

これは正しい方向への一歩かもしれません。しかし、解決を保証することはできません。バインディングを使用しないように itemRenderer を書き直すことから始めることをお勧めします。私はクライアントにそれを教えることで、有料クライアントの多くのメモリ リークを解決しました。バインドは、itemRenderers でパフォーマンスの高い操作であることも知られています。そのため、操作から削除することをお勧めします。

itemRenderer で Binding を使用する代わりに、dataChange メソッドに応答することを好みます。

itemRenderer から HBox を削除することもお勧めします。ラベルをそのまま使用できるはずです。

<mx:ComboBox width="200"
             dataProvider="{dataProvider}">
    <mx:itemRenderer>
        <mx:Component>
            <mx:Label dataChange="onDataChange(event)">
              <mx:Script>
                 protected function onDataChange(event:Event):void{
                    this.text='item renderer' + data.label;
                 }
              </mx:Script>
            </mx:Label>
        </mx:Component>
    </mx:itemRenderer>
</mx:ComboBox>

それがパフォーマンスの問題に対処するかどうかはわかりません。Flextras AutoComplete を作成する際に対処しなければならなかった Flex ComboBox には、多くの奇妙な点があります。

Flex 3.4 (およびそれ以前) では、ドロップダウンが閉じられるたびにメモリがそれを教えてくれます。それは破棄されました - 基本的にメモリにキャッシュされませんでした。これはFlex 3.5で変更されましたが、キャッシュが開始され、同じドロップダウンオブジェクトが再利用されました。あなたの知覚されたパフォーマンスの問題は、何らかの形でそれに関連しているのだろうか.


編集 1: 根底にある問題に対処していないこの投稿に関する苦情に基づいています。元のポスター コードと提案された変更に基づいて、このテスト ケースをまとめました。私が提案した変更は、元のポスターが抱えていた問題を実際に解決します。サンプルのソースは次のとおりです。

    [Bindable]
    public var dataProvider:ArrayCollection = new ArrayCollection(
        [{label:"test1"}, 
            {label:"test2"}, 
            {label:"test3"}]);

]]></mx:Script>

<!-- combobox with item renderer, this has a delay when opening -->

<mx:VBox>

<!-- ComboBox provided by original poster -->
<mx:ComboBox width="200"
             dataProvider="{dataProvider}">
    <mx:itemRenderer>
        <mx:Component>
            <mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml">
                <mx:Label text="'item renderer' + {data.label}"/>
            </mx:HBox>
        </mx:Component>
    </mx:itemRenderer>
</mx:ComboBox>


<!-- ComboBox with rewritten itemRenderer; which does not exhibit the problem -->
<mx:ComboBox width="200"
             dataProvider="{dataProvider}">
    <mx:itemRenderer>
        <mx:Component>
            <mx:Label dataChange="label1_dataChangeHandler(event)">
                <mx:Script>
                    <![CDATA[
                        import mx.events.FlexEvent;

                        protected function label1_dataChangeHandler(event:FlexEvent):void
                        {
                            this.text = "item renderer" + data.label;
                        }

                    ]]>
                </mx:Script>
            </mx:Label>
        </mx:Component>
    </mx:itemRenderer>
</mx:ComboBox>


<!-- default combobox, this works fine -->

<mx:ComboBox width="200"
             dataProvider="{dataProvider}"/>
</mx:VBox>


編集 2: devshorts は、コンポーネントをスタンドアロンの itemRenderer として作成すると、私のコードが機能しないと言います。ただし、理由がわかりません。

以下は、com.flextras.listRenderers.CustomLabelRenderer という名前のスタンドアロン itemRenderer のコードです。

<?xml version="1.0" encoding="utf-8"?>
<mx:Label xmlns:mx="http://www.adobe.com/2006/mxml" dataChange="label1_dataChangeHandler(event)">

    <mx:Script>
        <![CDATA[
            import mx.events.FlexEvent;

            protected function label1_dataChangeHandler(event:FlexEvent):void
            {
                this.text = "item renderer" + data.label;
            }

        ]]>
    </mx:Script>    
</mx:Label>

上記のメール アプリケーションに追加してテストするコードを次に示します。

<!-- ComboBox, like above with the itemRenderer as a separate component -->
    <mx:ComboBox width="200"
             dataProvider="{dataProvider}" itemRenderer="com.flextras.listRenderers.CustomLabelRenderer" />

提供されたリンクでアプリケーションを更新して、この新しい ComboBox インスタンスを含めました。現在、リストの3番目です。

于 2012-08-27T18:58:27.760 に答える