Return-Path: X-Original-To: apmail-flex-dev-archive@www.apache.org Delivered-To: apmail-flex-dev-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 8C5FECEB5 for ; Thu, 18 Jul 2013 19:22:27 +0000 (UTC) Received: (qmail 52191 invoked by uid 500); 18 Jul 2013 19:22:26 -0000 Delivered-To: apmail-flex-dev-archive@flex.apache.org Received: (qmail 51709 invoked by uid 500); 18 Jul 2013 19:22:20 -0000 Mailing-List: contact dev-help@flex.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@flex.apache.org Delivered-To: mailing list dev@flex.apache.org Received: (qmail 51699 invoked by uid 99); 18 Jul 2013 19:22:19 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 18 Jul 2013 19:22:19 +0000 X-ASF-Spam-Status: No, hits=-0.3 required=5.0 tests=FB_GET_MEDS,RCVD_IN_DNSWL_MED,SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (athena.apache.org: domain of aharui@adobe.com designates 64.18.1.189 as permitted sender) Received: from [64.18.1.189] (HELO exprod6og105.obsmtp.com) (64.18.1.189) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 18 Jul 2013 19:22:13 +0000 Received: from outbound-smtp-2.corp.adobe.com ([193.104.215.16]) by exprod6ob105.postini.com ([64.18.5.12]) with SMTP ID DSNKUehATx0ta2NExFNFRMimpAcMlTLZPDbB@postini.com; Thu, 18 Jul 2013 12:21:52 PDT Received: from inner-relay-2.corp.adobe.com (mail-321.pac.adobe.com [153.32.1.52]) by outbound-smtp-2.corp.adobe.com (8.12.10/8.12.10) with ESMTP id r6IJLnAI027538 for ; Thu, 18 Jul 2013 12:21:50 -0700 (PDT) Received: from nacas03.corp.adobe.com (nacas03.corp.adobe.com [10.8.189.121]) by inner-relay-2.corp.adobe.com (8.12.10/8.12.10) with ESMTP id r6IJLmw7009737 for ; Thu, 18 Jul 2013 12:21:49 -0700 (PDT) Received: from NAMBX02.corp.adobe.com ([10.8.127.96]) by nacas03.corp.adobe.com ([10.8.189.121]) with mapi; Thu, 18 Jul 2013 12:21:48 -0700 From: Alex Harui To: "dev@flex.apache.org" Date: Thu, 18 Jul 2013 12:21:44 -0700 Subject: Re: Flex mobile performance - Question on itemRenderers Thread-Topic: Flex mobile performance - Question on itemRenderers Thread-Index: Ac6D7AwRsBbXDRf/Sa2XgOpOJl5TwQ== Message-ID: In-Reply-To: Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: user-agent: Microsoft-MacOutlook/14.3.4.130416 acceptlanguage: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-Virus-Checked: Checked by ClamAV on apache.org The profiler can help measure performance. Besides creation and validation, another issue may be rendering. Look for [render] near the top of the performance profile. I recently discovered that fxg can be very non-optimal. There can be lots of empty groups or unnecessary levels of groups and that can make fxg images very costly. The authoring tools do that to preserve layers needed at authoring but there can be a cost at runtime. One quick test: comment out the FXG images and/or replace them with pngs and see if scrolling is better. On 7/18/13 11:25 AM, "flexcapacitor@gmail.com" wrote: >I would try creating a MXML based renderer, turn off virtualization on the >list and then compare the results. Virtualization allows reusing a >renderer >but if you are seeing issues during scrolling then either creation or >validation is too heavy. When you turn off virtualization the row is only >created once. The tradeoff is you use more memory. > >You might also try to optimize the FXG (either manually or with the >compiler). > >Also, things like this, >BitmapImage(iconDisplay).smooth =3D true; > >could be costly. Also, try disabling cacheAsBitmap. > >But you won't know unless you measure the performance. I had some code for >testing an item renderer. I'll see if I can dig it up. > >On Wed, Jul 17, 2013 at 4:29 AM, Christian Kiefer < >christian.kiefer@goal-games.de> wrote: > >> About the itemRenderer-Performance-**Issues... >> >> I've written an itemRenderer based no IconItemRenderer with some texts >>and >> a lot of (fxg) images... and the scrolling is horrible... >> >> Maybe someone can tell me what's wrong with my itemRenderer as all my >> other renderers performe quite good... >> >> Code is something like that (replaced some things with pseudo code... >>for >> better understanding)... >> >> /** >> * Created with IntelliJ IDEA. >> * User: Christian >> * Date: 11.03.13 >> * Time: 14:09 >> * To change this template use File | Settings | File Templates. >> */ >> package de.somePackage { >> import flash.display.GradientType; >> import flash.events.Event; >> import flash.events.MouseEvent; >> import flash.geom.Matrix; >> >> import spark.components.**IconItemRenderer; >> import spark.components.**supportClasses.**StyleableTextField; >> import spark.core.**SpriteVisualElement; >> import spark.primitives.BitmapImage; >> >> public class MyRenderer extends IconItemRenderer{ >> >> //////////////////////////////**//////////////////////////////** >> //////////////// >> // CONSTANTS >> //////////////////////////////**//////////////////////////////** >> //////////////// >> >> //////////////////////////////**//////////////////////////////** >> //////////////// >> // FIELDS >> //////////////////////////////**//////////////////////////////** >> //////////////// >> >> private var matrix:Matrix; >> >> //////////////////////////////**//////////////////////////////** >> //////////////// >> // USER INTERFACE COMPONENTS >> //////////////////////////////**//////////////////////////////** >> //////////////// >> >> >> private var textDisplay1:**StyleableTextField; >> private var textDisplay2:**StyleableTextField; >> private var textDisplay3:**StyleableTextField; >> >> private var fxgImg1:SpriteVisualElement; >> private var fxgImg2:SpriteVisualElement; >> private var fxgImg3:SpriteVisualElement; >> >> private var fxgImg4:SpriteVisualElement; >> private var fxgImg5:SpriteVisualElement; >> private var fxgImg6:SpriteVisualElement; >> >> >> private var dataChanged:Boolean; >> >> override public function set data(value:Object):void >> { >> super.data =3D value; >> dataChanged =3D true; >> invalidateProperties(); >> invalidateDisplayList() >> } >> >> >> //////////////////////////////**//////////////////////////////** >> //////////////// >> // CONSTRUCTOR >> //////////////////////////////**//////////////////////////////** >> //////////////// >> >> public function MyRenderer () >> { >> super(); >> //cacheAsBitmap =3D true; -> Already setted in >>LabelItemRenderer >> height =3D 55; >> iconWidth =3D 51; >> iconHeight =3D 51; >> >> mouseChildren =3D false; >> addEventListener(MouseEvent.**CLICK, handleMouseClick); >> >> iconScaleMode =3D "letterbox"; >> >> iconFunction =3D assignBitmap; >> messageFunction =3D assignMessage; >> labelFunction =3D assignLabel; >> } >> >> //////////////////////////////**//////////////////////////////** >> //////////////// >> // ITEM RENDERER OVERRIDES >> //////////////////////////////**//////////////////////////////** >> //////////////// >> >> override protected function createLabelDisplay():void >> { >> labelDisplay =3D StyleableTextField(**createInFontContext(** >> StyleableTextField)); >> labelDisplay.styleName =3D this; >> labelDisplay.editable =3D false; >> labelDisplay.selectable =3D false; >> labelDisplay.multiline =3D false; >> labelDisplay.wordWrap =3D false; >> labelDisplay.styleDeclaration =3D styleManager.** >> getStyleDeclaration(".**textField_S3_C1"); >> labelDisplay.commitStyles(); >> addChild(labelDisplay); >> } >> >> override protected function createMessageDisplay():void >> { >> messageDisplay =3D StyleableTextField(**createInFontContext(= ** >> StyleableTextField)); >> messageDisplay.styleName =3D this; >> messageDisplay.editable =3D false; >> messageDisplay.selectable =3D false; >> messageDisplay.multiline =3D false; >> messageDisplay.wordWrap =3D false; >> messageDisplay.**styleDeclaration =3D styleManager.** >> getStyleDeclaration(".**textField_S3_C1"); >> messageDisplay.commitStyles(); >> messageDisplay.setStyle("**textAlign", "center"); >> addChild(messageDisplay); >> } >> >> protected function createTextDisplay1():void >> { >> textDisplay1 =3D StyleableTextField(**createInFontContext(** >> StyleableTextField)); >> textDisplay1.styleName =3D this; >> textDisplay1.editable =3D false; >> textDisplay1.selectable =3D false; >> textDisplay1.multiline =3D false; >> textDisplay1.wordWrap =3D false; >> textDisplay1.styleDeclaration =3D styleManager.** >> getStyleDeclaration(".**textField_S3_C1"); >> textDisplay1.commitStyles(); >> textDisplay1.setStyle("**textAlign", "center"); >> addChild(textDisplay1); >> } >> >> protected function createTextDisplay2():void >> { >> textDisplay2 =3D StyleableTextField(**createInFontContext(** >> StyleableTextField)); >> textDisplay2.styleName =3D this; >> textDisplay2.editable =3D false; >> textDisplay2.selectable =3D false; >> textDisplay2.multiline =3D false; >> textDisplay2.wordWrap =3D false; >> textDisplay2.styleDeclaration =3D styleManager.** >> getStyleDeclaration(".**textField_S3_C0"); >> textDisplay2.commitStyles(); >> textDisplay2.setStyle("**textAlign", "center"); >> addChild(textDisplay2); >> } >> >> protected function createTextDisplay3():void >> { >> textDisplay3 =3D StyleableTextField(**createInFontContext(** >> StyleableTextField)); >> textDisplay3.styleName =3D this; >> textDisplay3.editable =3D false; >> textDisplay3.selectable =3D false; >> textDisplay3.multiline =3D false; >> textDisplay3.wordWrap =3D false; >> textDisplay3.styleDeclaration =3D styleManager.** >> getStyleDeclaration(".**textField_S3_C0"); >> textDisplay3.commitStyles(); >> textDisplay3.setStyle("**textAlign", "center"); >> addChild(textDisplay3); >> } >> >> private function get nameDisplay():**StyleableTextField >> { >> return labelDisplay; >> } >> >> private function get ageDisplay():**StyleableTextField >> { >> return messageDisplay; >> } >> >> //////////////////////////////**//////////////////////////////** >> //////////////// >> // >> //////////////////////////////**//////////////////////////////** >> //////////////// >> >> protected function assignMessage(value:Object):**String >> { >> return value.age + ""; >> } >> >> protected function assignLabel(value:Object):**String >> { >> return value.firstName.charAt(0) + ". " + value.lastName; >> } >> >> protected function assignBitmap(value:Object):**Object >> { >> if(value =3D=3D null) >> { >> return null; >> } >> >> return "GET_IMAGE_FROM_A_CACHE"; >> } >> >> //////////////////////////////**//////////////////////////////** >> //////////////// >> // LIFECYCLE STANDARD METHODS >> //////////////////////////////**//////////////////////////////** >> //////////////// >> >> override protected function createChildren():void >> { >> super.createChildren(); >> >> fxgImg1 =3D new FXG1(); >> addChild(fxgImg1); >> >> fxgImg2 =3D new FXG2(); >> addChild(fxgImg2); >> >> fxgImg3 =3D new FXG3(); >> addChild(fxgImg3); >> >> fxgImg4 =3D new FXG4(); >> addChild(fxgImg4); >> >> fxgImg5 =3D new FXG5(); >> addChild(fxgImg5); >> >> fxgImg6 =3D new FXG6(); >> addChild(fxgImg6); >> >> createTextDisplay1(); >> createTextDisplay2(); >> createTextDisplay3(); >> >> } >> >> override protected function commitProperties():void >> { >> >> if(dataChanged) >> { >> setImportantIcon(); >> } >> >> super.commitProperties(); >> >> if(dataChanged) >> { >> textDisplay1.text =3D data.someText + ""; >> dataChanged =3D false; >> } >> } >> >> override protected function measure():void >> { >> super.measure(); >> } >> >> override protected function >>updateDisplayList(**unscaledWidth:Number, >> unscaledHeight:Number):void >> { >> super.updateDisplayList(**unscaledWidth, unscaledHeight); >> if(iconDisplay && iconDisplay is BitmapImage) >> { >> BitmapImage(iconDisplay).**smooth =3D true; >> } >> } >> >> override protected function >>drawBackground(unscaledWidth:**Number, >> unscaledHeight:Number):void >> { >> if(!matrix) >> { >> matrix =3D new Matrix(); >> } >> >> matrix.createGradientBox(**unscaledWidth, unscaledHeight , >> Math.PI/2); >> >> graphics.clear(); >> graphics.beginGradientFill(**GradientType.LINEAR, [0x333333, >> 0x353535, 0x232323, 0x4E4E4E], [1,1,1,1], [0, 110, 115, 255], matrix); >> graphics.drawRect(0, 0, unscaledWidth, unscaledHeight); >> graphics.endFill(); >> >> drawVerticalStroke(56, unscaledHeight); >> drawVerticalStroke(125, unscaledHeight); >> drawVerticalStroke(406, unscaledHeight); >> drawVerticalStroke(446, unscaledHeight); >> drawVerticalStroke(495, unscaledHeight); >> drawVerticalStroke(546, unscaledHeight); >> } >> >> override protected function >>layoutContents(unscaledWidth:**Number, >> unscaledHeight:Number):void >> { >> >> var yPosForTexts:Number =3D (unscaledHeight - >> getElementPreferredHeight(**nameDisplay)) / 2; >> >> setElementSize(ageDisplay, 35, getElementPreferredHeight(** >> ageDisplay)); >> setElementPosition(ageDisplay, 408, yPosForTexts); >> >> setElementSize(nameDisplay, 236, >>getElementPreferredHeight(** >> nameDisplay)); >> setElementPosition(**nameDisplay, 148, yPosForTexts); >> >> setElementSize(textDisplay1, 45, >>getElementPreferredHeight(** >> textDisplay1)); >> setElementPosition(**textDisplay1, 550, yPosForTexts); >> >> setElementSize(iconDisplay, this.iconWidth, >>this.iconHeight); >> setElementPosition(**iconDisplay, 67, 2); >> >> >> if(decoratorDisplay) >> { >> decoratorDisplay.smooth =3D true; >> setElementSize(**decoratorDisplay, 55, 55); >> setElementPosition(**decoratorDisplay, 0, 0); >> } >> >> setElementPosition(fxgImg1, 502, 13); >> setElementPosition(fxgImg2, 502, 13); >> setElementPosition(fxgImg3, 510, 4); >> >> setElementPosition(fxgImg4, 452, 13); >> setElementPosition(fxgImg5, 452, 13); >> setElementPosition(fxgImg6, 460, 4); >> >> setElementPosition(**textDisplay3, 457, 23); >> setElementSize(textDisplay3, >>textDisplay3.**getPreferredBoundsWidth(), >> textDisplay3.**getPreferredBoundsHeight()); >> >> setElementPosition(**textDisplay2, 507, 23); >> setElementSize(textDisplay2, >>textDisplay2.**getPreferredBoundsWidth(), >> textDisplay2.**getPreferredBoundsHeight()); >> } >> >> //////////////////////////////**//////////////////////////////** >> //////////////// >> // EVENT HANDLER >> //////////////////////////////**//////////////////////////////** >> //////////////// >> >> private function handleMouseClick(event:**MouseEvent):void >> { >> dispatchEvent(new Event("SomeEvent")); >> } >> >> //////////////////////////////**//////////////////////////////** >> //////////////// >> // HELPER METHODS >> //////////////////////////////**//////////////////////////////** >> //////////////// >> >> protected function drawVerticalStroke(xPos:int, >> unscaledHeight:Number):void >> { >> graphics.beginFill(0xCCCCCC); >> graphics.drawRect(xPos, 0, 3, unscaledHeight); >> graphics.endFill(); >> >> graphics.beginFill(0x666666); >> graphics.drawRect(xPos + 1, 0, 1, unscaledHeight); >> graphics.endFill(); >> >> } >> >> private function setImportantIcon():void >> { >> if(decoratorDisplay) >> { >> decoratorDisplay.visible =3D true; >> } >> >> if(data.important1) >> { >> decorator =3D FXGImg1; >> } >> else if(data.important2) >> { >> decorator =3D FXGImg2; >> } >> else if(data.important3) >> { >> decorator =3D FXGImg3; >> } >> else >> { >> if(decoratorDisplay) >> { >> decoratorDisplay.visible =3D false; >> } >> decorator =3D null; >> } >> invalidateDisplayList(); >> } >> >> override public function styleChanged(styleName:String)**:void >> { >> if(getStyle("messageStyleName"**)) >> { >> setStyle("messageStyleName", null); >> } >> super.styleChanged(styleName); >> } >> >> >> >> } >> >> } >>