2009-06-10 9 views
3

私は最初のFlexカスタムコンポーネントをFlex 3で構築しています。これは、各セルに単純なテキストラベルを持つ 'Grid'コンテナクラスに基づくデータテーブルです。 (DataGridとAdvancedDataGridは私のニーズにとっては適切な出発点ではありませんでした)小さなテーブルを使用することでかなりうまく動作しますが、大きなテーブルを使用してストレステストを試みましたが、結果に失望しました。多数のUIオブジェクトを持つFlexアプリケーションは==遅いですか?

コンポーネントの作成プロセスには、いくつかのスロースポットがありますが、それらは最適化する権限があり、私の主な関心事ではありません。私が心配しているのは、Flexフレームワーク自体の限界と思われるものです。

この '大きな'サンプルテーブルには、7000個以上のセルがあります。これは大規模ですが、それでも私が対応する必要がある最大サイズよりも1〜2桁小さいです。標準グリッド構造では、コンポーネントの主要部分は、それぞれ16個のGridItemからなる400個のGridRowsと、それ以外の小さな補助グリッドからなるグリッドで構成されています。

表はレンダリングしたら、私は次を見つける:

  • マウス関連のイベントは、火災に遅いです。具体的には、各テーブルセルにrollOver/rollOutイベントハンドラを登録して、ポインタの下のセルをハイライト表示させます。小さなテーブルでは、テーブル上でマウスをすばやく動かすことができ、ハイライト表示はポインタをリアルタイムで追従します。大きなテーブルでは、強調表示は非常にぎくしゃくしており、1秒あたり約2回しか変化せず、多くのセルをスキップします。
  • マウスカーソルをコンポーネントの上に置き、そこに置いておくと、CPUが固定されて(プロセッサコアが1つ)、アイドル状態になったときにコンポーネントから離れるまでそのままの状態になります。私のコンポーネントは、この時点では何もしません。

Flexはこのようなコンポーネントツリーをサポートするために単純に拡張できないように感じます。私はそれが100,000個の細胞でどのように振る舞うかを想像しています。おそらく私はグリッドを意図した使い方を超えて押し進めようとしていますが、テーブルセル当たりのオブジェクトを持つことは不合理なモデルのようには見えず、ツリー内の14,000個のオブジェクト(1つのGridItemと1セルあたりのラベル)

私はまだFlexBuilderプロファイラから有用なデータを取得していません。私はそれに取り組んでいます。今のところ私の最大の質問は次のとおりです。

  • 私は本当にこの控えめなテストでFlexの限界を押していますか?
  • このコンポーネントのアプローチは完全にオフベースですか?

私はこれをFirefoxのWinXPでFlash Player 9で実行しています。

+0

Eh ...そのようなデザインのウィジェットは、ちょうどどのウィジェットマネージャにとってもかなり遅くなります。通常は、特定の時点でスクリーン上に実際に必要な要素を作成するだけの設計を行い、ユーザーが表示したいものを反映するために必要なときに配置します(スクロール、検索など) – Shog9

+0

私はユーザーが現在のアーキテクチャでサポートされている方法ですべてのデータをスムーズにスクロールできるようにしたいが、これを管理する必要があるように思えるフレームワークに頼るのではなく手動で実行します。 まあ...私はこれが私の最初のFlexコンポーネントだと言っていました。 :) – Aron

+0

このようなエフェクトをエミュレートするために、グリッドに新しいデータを送るカスタムスクロールバーを作成することができます。この方法では、データだけが必要で、Flexは1ページに必要な表示オブジェクトの数だけを割り当てます。 – CookieOfFortune

答えて

7

はい、Flexは非常に多数のコンポーネントをサポートするように設計されていません。コンポーネントの数を最小限に抑え、必要のない機能(Canvasの代わりにDisplayObject if余分な機能は必要ありません)。

表示されたオブジェクトと正確にデータをミラーリングすることは賢明ではありません。 DisplayObjects(および関連するクラス)は比較的ヘビーなので、持っているものの数を制御する必要があります。

私は1000 + Cellsとそれぞれのイベントリスナーで作業しているスケールがFlexの限界に達していると言います。

私はあなたのアプローチとアーキテクチャをよく見てください。私はあなたが1000以上のすべてのアイテムを同時に表示していないと仮定します。おそらくページングを使用し、各画面で100ishを表示し、別のページに移動する前/次のボタンを表示する必要があります。スクロール効果をシミュレートしてカスタムスクロールバーを使用して行を動的に追加および削除することも考えられます。これははるかに複雑です。

1

あなたのコードを見ずに何をしようとしているのかわからなくても、その多くのデータをフレームワークにまとめてプッシュすることで、Flexの限界を押しているようです。

Flashランタイムは、巨大なアプリケーションを処理するようには設計されていませんが、ブラウザ内でやや軽いアプリケーションを実行するように設計されています。また、ユーザーが一度にすべてのコントロールにアクセスする必要があるとは思われません。

アプリケーション内のデータを駆動するためのデータサービス(Java、.NETなど)を提供できます。フレームワークでは一度に200〜300+要素しか扱われないように、データをページします。

3

リストフレームベースのコントロールをFlexフレームワークで見ると、リサイクルされたアイテムレンダラーが大幅に使用されていることがわかります。そのため、20行のDataGridを表示すると、リストをスクロールするたびに約22のレンダラーが作成され、リサイクルされます。これは、DataGridが何千ものレコードを保持することができ、それでもかなり素晴らしいパフォーマンスを持つ理由です。あなたが使用している場合、Flexで

http://weblogs.macromedia.com/pent/archives/2008/03/itemrenderers_p.html

+0

リンクありがとう! – Aron

0

、:私はあなたがアイテムレンダラー上の記事のピーター・耳鼻咽喉科のシリーズをチェックアウトして、似たようなを構築する方法を理解するためにListBaseから/リストおよび関連するクラスのいくつかを見てみましょうお勧めしますイベントをマウスで移動して何かを再描画します。非常に遅いレンダリングを経験したかもしれません。

例:

this.addEventListener(のMouseEvent.MOUSE_MOVE、再描画);

public function redraw(anything:Object=null):void{ 
     //draw something here 
      this.graphics.clear(); 
      this.graphics.lineStyle(3, 0x000000); 
      this.graphics.moveTo(startPoint.x, startPoint.y); 
      this.graphics.lineTo(endPoint.x, endPoint.y); 
      this.scaleTextInput.x = centerPoint.x; 
      this.scaleTextInput.y = centerPoint.y; 

    } 

上記のコードの結果は非常に遅いレンダリング...

策:代わりに

使用Event.ENTER_FRAMEイベント?マウス移動イベントよりも多くのリソースが消費しますが、マウスがユーザにとってより応答性の出現することができ、毎秒かなり多くの更新を受信する必要があります

例:

this.addEventListener(Event.ENTER_FRAME、再描画します) ;

this.addEventListener(MouseEvent.MOUSE_MOVE、redraw);代わりに。

とあなたは..Happy屈曲に

より行ってもいいです: http://www.deepakdhakal.com

6

少年は、我々がこのトピックに関する本を書くことができそうです。または少なくとも章を少なくとも1つ。私たちが製品を開発しているうちに、この分野でかなりのことを学びました。

ボトムライン - はい、1000以上の「もの」を画面に追加すると、Flexは停止するまで遅くなります。ここでは、いくつかの箇条書きの点と既に述べたことのいくつかの繰り返し(簡潔にするために)

1)表示されているものだけを常に描画します。新しいSpark DataGridの設計者であるHans Muller氏は、ViewPortsについて素晴らしい記事を書いています。 http://hansmuller-flex.blogspot.com/2009/06/introduction-to-viewports-and-scrolling.html。したがって、可視領域を埋めるために十分な "セル"をインスタンス化し、基本的にユーザーがスクロールしながらリサイクルします。

2)リサイクル、リサイクル、リサイクル:さらに、上に示したように、ユーザーがスクロールすると、明らかに現在表示されていないセルをリサイクルして、表示されているセルを表示する必要があります。 - >新しいセルを廃棄して作成するのではなく、新しいセルを使用するか、再配置を使用するか、再配置を使用するか(再配置を好む)

これは次のことを意味します:10X10ユーザーが100X100データプロバイダを表示するグリッド(可視)になります。ユーザーがセル20X20にスクロールすると、既存のセルのXとYを新しい場所に設定し、それぞれのセットデータを呼び出します。シナリオは一連の関連するコンテナであったため、以前はリパイントを使用していました。したがって、これはあなたには当てはまりません。しかし、ボトムライン - 可視領域の周りに単に「行」を移動するだけです。したがって、作成と破棄は遅くなります。表示オブジェクトのリストを削除して追加する方が高速になり、ちょうど周りを(x、y)移動するのが最速になります。

3)賢明に継承するものを選択します。Flex SDKは獣です。だからあなたの "細胞"基本クラスを賢明に選択してください。たとえば、SDK DataGridsには、LabelではなくUITextField(Halo)から継承する軽量レンダラーがあります。特定のシナリオでは、UIComponentでさえ重くなります。 UIComponentのためのasdocを探し、そこにすべてが必要かどうかを見てください。そうでなければ、それ以上の階層から継承することを検討してください。

4)キャッシュ計算:これは開発サイクルの最後に行います。フィーチャを終了したら、flexプロファイラを実行します。最も長く実行されているメソッドと最もよく呼び出されるメソッドを識別します。私たちは常にリリースするときにこれを行います。常に改善が行われるからです。高度なビジュアルコンポーネントを開発するときには数学が必要ですが、計算が多すぎると処理が遅くなります。

5)メモリのプロファイルを確認してください:有線イベントリスナー、不正なオブジェクト参照などがパフォーマンスを低下させます。 Flexプロファイラはこれに対抗する優れたツールですので、必ず使用してください。

ここには良いリンクがいくつかあります: http://www.flexicious.com/resources/Ultimate/Docs/LargeDataset.htm

希望すると便利です。

+0

素敵な要約。私たちは、これらのレッスンのほとんどを自分たちで学び、最終的にパフォーマンスはかなり上品です。しかしプロファイラに関しては、私はこれが、YourKit for Javaと比べてやや残酷なツールであることが判明しました。漏れたオブジェクトを追跡するのに無駄なのは次のようだった。私は1年前からFlexに触れる必要がなかったので、それ以来改善されているかもしれません。 – Aron

関連する問題