Profiling

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

Profiling

Paul Stearns
I have a routine that "disappears" for a few seconds. I would like to turn profiling on just before this begins and off when it comes back. Is this possible?

Since the app does many things, I want to isolate just this section where as far as I can tell it is not executing any code from my application.

I am currently using FlexBuilder 3, but will use whatever is available as long as the learning curve isn't too steep and it works with my 3.6 code.


Reply | Threaded
Open this post in threaded view
|

Re: Profiling

Paul Stearns
OK, I downloaded Scout & ScoutEnabler. I learned enough to be able to run it and I found the problem area.

The swf in question has 10 tabs with more than 300 objects spread among the tabs. The TabNavigator has creationPolicy="all" set so that once the swf is loaded the "as" code can start populating various comboBoxes and other components on the hidden tabs.

My working hypothesis is flash get's "hung" building all those components at once.

If this is the case, how can I get rid of creationPolicy="all" and once the screen becomes visible, force the creation of all the hidden tabs before I try to populate them? While this may take a little longer, it would provide a better user interface.

----------------------------------------
From: "Paul Stearns" <[hidden email]>
Sent: 2/10/19 6:55 AM
To: "[hidden email]" <[hidden email]>
Subject: Profiling
I have a routine that "disappears" for a few seconds. I would like to turn profiling on just before this begins and off when it comes back. Is this possible?

Since the app does many things, I want to isolate just this section where as far as I can tell it is not executing any code from my application.

I am currently using FlexBuilder 3, but will use whatever is available as long as the learning curve isn't too steep and it works with my 3.6 code.


Reply | Threaded
Open this post in threaded view
|

Re: Profiling

Alex Harui-2
There are several ways.

The "theoretical" way is to rewrite your code.  Populating ComboBoxes on hidden tabs is not a recommended practice.  That is effectively having code in the app "pushing data down" into the controls.  Instead, in any pattern that has MV in it, the recommended practice is that the components pull what they need from a model.  If you do that rewrite, you may find that each Tab loads sufficiently fast when clicked on "on-demand".  Maybe a busy cursor spins for a few seconds.  Web pages often take a few seconds to load.  But that may be a better experience than waiting 30 seconds for the first screen to show up.

Related, any tab that takes a few seconds to load may have its own "push data down" code in it and is initializing controls that may be in a sub-tab or has even sucked in a module or two.  Profile each slow Tab and see what is going on.

The "hacky" way is to use Pseudo-Threads.  There are fancy Pseudo-Thread patterns, but the cheapest one is just a chain of CallLater functions.  Maybe each one initializes a Tab then callLater's the function to initialize the next Tab.   Still to slow?  Then initialize half a Tab and callLater to initialize the other half.

Other ideas involve re-designing the UI to use more deferred-instantiation components.

FWIW, many years ago I saw a great presentation on UI design by a magician.  He talked about understanding human behavior to create illusions.  There is also a classic book called "Computers As Theatre" by Brenda Laurel.  In live theatre (as opposed to movies), there is the reality of having to find ways to get people and props on and off the stage without distracting the audience.  These ideas can apply to problems like this one.  If you know that folks will dwell on the first screen for N seconds before they can even decide what to click on, then you've got N seconds to initialize stuff in a pseudo-thread.  If you have Tabs that scroll, you can just initialize the first screenful of UI widgets, then you probably have another second or two to initialize stuff off-screen.  Busy cursors, UI effects, progressive reveals are all techniques that can be used to create the illusion that the UI is ready to go, when in reality, your stage crew is hustling in the dark behind the sofa.

HTH,
-Alex

On 2/10/19, 4:57 AM, "Paul Stearns" <[hidden email]> wrote:

    OK, I downloaded Scout & ScoutEnabler. I learned enough to be able to run it and I found the problem area.
   
    The swf in question has 10 tabs with more than 300 objects spread among the tabs. The TabNavigator has creationPolicy="all" set so that once the swf is loaded the "as" code can start populating various comboBoxes and other components on the hidden tabs.
   
    My working hypothesis is flash get's "hung" building all those components at once.
   
    If this is the case, how can I get rid of creationPolicy="all" and once the screen becomes visible, force the creation of all the hidden tabs before I try to populate them? While this may take a little longer, it would provide a better user interface.
   
    ----------------------------------------
    From: "Paul Stearns" <[hidden email]>
    Sent: 2/10/19 6:55 AM
    To: "[hidden email]" <[hidden email]>
    Subject: Profiling
    I have a routine that "disappears" for a few seconds. I would like to turn profiling on just before this begins and off when it comes back. Is this possible?
   
    Since the app does many things, I want to isolate just this section where as far as I can tell it is not executing any code from my application.
   
    I am currently using FlexBuilder 3, but will use whatever is available as long as the learning curve isn't too steep and it works with my 3.6 code.
   
   
   

Reply | Threaded
Open this post in threaded view
|

Re: Profiling

Alex Harui-2
In reply to this post by Paul Stearns
Re-adding users@

IIRC, the key piece is a loop in ViewStack’s setActualCreationPolicies (around line 1058)
https://github.com/apache/flex-sdk/blob/master/frameworks/projects/mx/src/mx/containers/ViewStack.as

It calls each child’s createDeferredContent().  The trick is to figure out when to call it on each child.  Apparently, calling it on all 9 other tabs at once causes so much code to run that it freezes the UI.

Like the magicians I referred to upthread, it is important to know your audience.  If the user is typing, it is hard to sneak in one second of computation.  If the user is not typing and moving a mouse, you might be able to get away with a one second pause.  But if a user makes a query, they might expect a pause and if the query is asynchronous, that’s a good time to sneak in some computation.  And if 90% of the users go to tab 2, that may be the only one you need to initialize during the query.  And then initialize the other 8 when the results come back and the user is pondering the results.

Or maybe they will put up with 9 one-second pauses while they are typing and all you have to do is use callLater to “unravel” the loop.  Put the iterator in a variable, call one createDeferredContent, (and maybe validateNow()) then increment the variable and callLater.

HTH,
-Alex

From: Paul Stearns <[hidden email]>
Reply-To: "[hidden email]" <[hidden email]>
Date: Monday, February 11, 2019 at 4:37 AM
To: Alex Harui <[hidden email]>
Subject: Re: Profiling

Alex:

I would like to take a middle road...

Upon startup there are a number of combo boxes which get populated. Then the user enters some query data, a query is performed and the rest get populated.

I took the time to rewrite the initialization of the 22 combo boxes using bindable Array Collections so that the TabNavigator can load just the 1st page. I would like to have each of the hidden tabs populate while waiting for the user to enter the query data. I have been unable to find how to tell each hidden tab to render individually.

You mention Initializing tabs, code wise, how is that accomplished? I've tried a few things with no luck.

I found that I can define the TabNavigator's creationPolicy as "auto", wait until the 1st tab is rendered, and switch the TabNavigator's creation policy to "all" it will then populate the other 9 tabs. This does show the first tab much quicker but it doesn't allow the entry of data until all of the other tabs are rendered. I was hoping to be able to do the callLater trick to give a break in between each load. Somewhat similar to a .NET Application.doevents().

I will look into the "magical" reference material you mentioned.


________________________________
From: Alex Harui <[hidden email]>
Sent: 2/11/19 12:12 AM
To: "[hidden email]" <[hidden email]>, "[hidden email]" <[hidden email]>
Subject: Re: Profiling
There are several ways.

The "theoretical" way is to rewrite your code. Populating ComboBoxes on hidden tabs is not a recommended practice. That is effectively having code in the app "pushing data down" into the controls. Instead, in any pattern that has MV in it, the recommended practice is that the components pull what they need from a model. If you do that rewrite, you may find that each Tab loads sufficiently fast when clicked on "on-demand". Maybe a busy cursor spins for a few seconds. Web pages often take a few seconds to load. But that may be a better experience than waiting 30 seconds for the first screen to show up.

Related, any tab that takes a few seconds to load may have its own "push data down" code in it and is initializing controls that may be in a sub-tab or has even sucked in a module or two. Profile each slow Tab and see what is going on.

The "hacky" way is to use Pseudo-Threads. There are fancy Pseudo-Thread patterns, but the cheapest one is just a chain of CallLater functions. Maybe each one initializes a Tab then callLater's the function to initialize the next Tab. Still to slow? Then initialize half a Tab and callLater to initialize the other half.

Other ideas involve re-designing the UI to use more deferred-instantiation components.

FWIW, many years ago I saw a great presentation on UI design by a magician. He talked about understanding human behavior to create illusions. There is also a classic book called "Computers As Theatre" by Brenda Laurel. In live theatre (as opposed to movies), there is the reality of having to find ways to get people and props on and off the stage without distracting the audience. These ideas can apply to problems like this one. If you know that folks will dwell on the first screen for N seconds before they can even decide what to click on, then you've got N seconds to initialize stuff in a pseudo-thread. If you have Tabs that scroll, you can just initialize the first screenful of UI widgets, then you probably have another second or two to initialize stuff off-screen. Busy cursors, UI effects, progressive reveals are all techniques that can be used to create the illusion that the UI is ready to go, when in reality, your stage crew is hustling in the dark behind the sofa.

HTH,
-Alex

On 2/10/19, 4:57 AM, "Paul Stearns" wrote:

OK, I downloaded Scout & ScoutEnabler. I learned enough to be able to run it and I found the problem area.

The swf in question has 10 tabs with more than 300 objects spread among the tabs. The TabNavigator has creationPolicy="all" set so that once the swf is loaded the "as" code can start populating various comboBoxes and other components on the hidden tabs.

My working hypothesis is flash get's "hung" building all those components at once.

If this is the case, how can I get rid of creationPolicy="all" and once the screen becomes visible, force the creation of all the hidden tabs before I try to populate them? While this may take a little longer, it would provide a better user interface.

----------------------------------------
From: "Paul Stearns"
Sent: 2/10/19 6:55 AM
To: "[hidden email]"
Subject: Profiling
I have a routine that "disappears" for a few seconds. I would like to turn profiling on just before this begins and off when it comes back. Is this possible?

Since the app does many things, I want to isolate just this section where as far as I can tell it is not executing any code from my application.

I am currently using FlexBuilder 3, but will use whatever is available as long as the learning curve isn't too steep and it works with my 3.6 code.




Reply | Threaded
Open this post in threaded view
|

Re: Profiling

Paul Stearns
In reply to this post by Paul Stearns
Alex:

I am not sure how I can use the link you referenced. I thought perhaps I could use "containerChild.createDeferredContent " but I am unable to find any components it is applicable to.

----------------------------------------
From: Alex Harui <[hidden email]>
Sent: 2/11/19 4:07 PM
To: "[hidden email]" <[hidden email]>, "[hidden email]" <[hidden email]>
Subject: Re: Profiling
Re-adding users@

IIRC, the key piece is a loop in ViewStack’s setActualCreationPolicies (around line 1058)
https://github.com/apache/flex-sdk/blob/master/frameworks/projects/mx/src/mx/containers/ViewStack.as

It calls each child’s createDeferredContent(). The trick is to figure out when to call it on each child. Apparently, calling it on all 9 other tabs at once causes so much code to run that it freezes the UI.

Like the magicians I referred to upthread, it is important to know your audience. If the user is typing, it is hard to sneak in one second of computation. If the user is not typing and moving a mouse, you might be able to get away with a one second pause. But if a user makes a query, they might expect a pause and if the query is asynchronous, that’s a good time to sneak in some computation. And if 90% of the users go to tab 2, that may be the only one you need to initialize during the query. And then initialize the other 8 when the results come back and the user is pondering the results.

Or maybe they will put up with 9 one-second pauses while they are typing and all you have to do is use callLater to “unravel” the loop. Put the iterator in a variable, call one createDeferredContent, (and maybe validateNow()) then increment the variable and callLater.

HTH,
-Alex

From: Paul Stearns
Reply-To: "[hidden email]"
Date: Monday, February 11, 2019 at 4:37 AM
To: Alex Harui
Subject: Re: Profiling

Alex:

I would like to take a middle road...

Upon startup there are a number of combo boxes which get populated. Then the user enters some query data, a query is performed and the rest get populated.

I took the time to rewrite the initialization of the 22 combo boxes using bindable Array Collections so that the TabNavigator can load just the 1st page. I would like to have each of the hidden tabs populate while waiting for the user to enter the query data. I have been unable to find how to tell each hidden tab to render individually.

You mention Initializing tabs, code wise, how is that accomplished? I've tried a few things with no luck.

I found that I can define the TabNavigator's creationPolicy as "auto", wait until the 1st tab is rendered, and switch the TabNavigator's creation policy to "all" it will then populate the other 9 tabs. This does show the first tab much quicker but it doesn't allow the entry of data until all of the other tabs are rendered. I was hoping to be able to do the callLater trick to give a break in between each load. Somewhat similar to a .NET Application.doevents().

I will look into the "magical" reference material you mentioned.

________________________________
From: Alex Harui
Sent: 2/11/19 12:12 AM
To: "[hidden email]" , "[hidden email]"
Subject: Re: Profiling
There are several ways.

The "theoretical" way is to rewrite your code. Populating ComboBoxes on hidden tabs is not a recommended practice. That is effectively having code in the app "pushing data down" into the controls. Instead, in any pattern that has MV in it, the recommended practice is that the components pull what they need from a model. If you do that rewrite, you may find that each Tab loads sufficiently fast when clicked on "on-demand". Maybe a busy cursor spins for a few seconds. Web pages often take a few seconds to load. But that may be a better experience than waiting 30 seconds for the first screen to show up.

Related, any tab that takes a few seconds to load may have its own "push data down" code in it and is initializing controls that may be in a sub-tab or has even sucked in a module or two. Profile each slow Tab and see what is going on.

The "hacky" way is to use Pseudo-Threads. There are fancy Pseudo-Thread patterns, but the cheapest one is just a chain of CallLater functions. Maybe each one initializes a Tab then callLater's the function to initialize the next Tab. Still to slow? Then initialize half a Tab and callLater to initialize the other half.

Other ideas involve re-designing the UI to use more deferred-instantiation components.

FWIW, many years ago I saw a great presentation on UI design by a magician. He talked about understanding human behavior to create illusions. There is also a classic book called "Computers As Theatre" by Brenda Laurel. In live theatre (as opposed to movies), there is the reality of having to find ways to get people and props on and off the stage without distracting the audience. These ideas can apply to problems like this one. If you know that folks will dwell on the first screen for N seconds before they can even decide what to click on, then you've got N seconds to initialize stuff in a pseudo-thread. If you have Tabs that scroll, you can just initialize the first screenful of UI widgets, then you probably have another second or two to initialize stuff off-screen. Busy cursors, UI effects, progressive reveals are all techniques that can be used to create the illusion that the UI is ready to go, when in reality, your stage crew is hustling in the dark behind the sofa.

HTH,
-Alex

On 2/10/19, 4:57 AM, "Paul Stearns" wrote:

OK, I downloaded Scout & ScoutEnabler. I learned enough to be able to run it and I found the problem area.

The swf in question has 10 tabs with more than 300 objects spread among the tabs. The TabNavigator has creationPolicy="all" set so that once the swf is loaded the "as" code can start populating various comboBoxes and other components on the hidden tabs.

My working hypothesis is flash get's "hung" building all those components at once.

If this is the case, how can I get rid of creationPolicy="all" and once the screen becomes visible, force the creation of all the hidden tabs before I try to populate them? While this may take a little longer, it would provide a better user interface.

----------------------------------------
From: "Paul Stearns"
Sent: 2/10/19 6:55 AM
To: "[hidden email]"
Subject: Profiling
I have a routine that "disappears" for a few seconds. I would like to turn profiling on just before this begins and off when it comes back. Is this possible?

Since the app does many things, I want to isolate just this section where as far as I can tell it is not executing any code from my application.

I am currently using FlexBuilder 3, but will use whatever is available as long as the learning curve isn't too steep and it works with my 3.6 code.


Reply | Threaded
Open this post in threaded view
|

Re: Profiling

Alex Harui-2
If you have a TabNavigator in a variable/id "tn",

Then you should be able to write:

var containerChild:INavigatorContent = tn.getChildAt(i) as INavigatorContent;
containerChild.createDeferredContent();

HTH,
-Alex

On 2/11/19, 4:37 PM, "Paul Stearns" <[hidden email]> wrote:

    Alex:
   
    I am not sure how I can use the link you referenced. I thought perhaps I could use "containerChild.createDeferredContent " but I am unable to find any components it is applicable to.
   
    ----------------------------------------
    From: Alex Harui <[hidden email]>
    Sent: 2/11/19 4:07 PM
    To: "[hidden email]" <[hidden email]>, "[hidden email]" <[hidden email]>
    Subject: Re: Profiling
    Re-adding users@
   
    IIRC, the key piece is a loop in ViewStack’s setActualCreationPolicies (around line 1058)
    https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fapache%2Fflex-sdk%2Fblob%2Fmaster%2Fframeworks%2Fprojects%2Fmx%2Fsrc%2Fmx%2Fcontainers%2FViewStack.as&amp;data=02%7C01%7Caharui%40adobe.com%7C5a60c62e798c4d337ee808d690823bea%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636855286357686522&amp;sdata=I03rmfnRqEdQdCUk1ASZQMldT7TkHJAf2g7%2BWHIKYUA%3D&amp;reserved=0
   
    It calls each child’s createDeferredContent(). The trick is to figure out when to call it on each child. Apparently, calling it on all 9 other tabs at once causes so much code to run that it freezes the UI.
   
    Like the magicians I referred to upthread, it is important to know your audience. If the user is typing, it is hard to sneak in one second of computation. If the user is not typing and moving a mouse, you might be able to get away with a one second pause. But if a user makes a query, they might expect a pause and if the query is asynchronous, that’s a good time to sneak in some computation. And if 90% of the users go to tab 2, that may be the only one you need to initialize during the query. And then initialize the other 8 when the results come back and the user is pondering the results.
   
    Or maybe they will put up with 9 one-second pauses while they are typing and all you have to do is use callLater to “unravel” the loop. Put the iterator in a variable, call one createDeferredContent, (and maybe validateNow()) then increment the variable and callLater.
   
    HTH,
    -Alex
   
    From: Paul Stearns
    Reply-To: "[hidden email]"
    Date: Monday, February 11, 2019 at 4:37 AM
    To: Alex Harui
    Subject: Re: Profiling
   
    Alex:
   
    I would like to take a middle road...
   
    Upon startup there are a number of combo boxes which get populated. Then the user enters some query data, a query is performed and the rest get populated.
   
    I took the time to rewrite the initialization of the 22 combo boxes using bindable Array Collections so that the TabNavigator can load just the 1st page. I would like to have each of the hidden tabs populate while waiting for the user to enter the query data. I have been unable to find how to tell each hidden tab to render individually.
   
    You mention Initializing tabs, code wise, how is that accomplished? I've tried a few things with no luck.
   
    I found that I can define the TabNavigator's creationPolicy as "auto", wait until the 1st tab is rendered, and switch the TabNavigator's creation policy to "all" it will then populate the other 9 tabs. This does show the first tab much quicker but it doesn't allow the entry of data until all of the other tabs are rendered. I was hoping to be able to do the callLater trick to give a break in between each load. Somewhat similar to a .NET Application.doevents().
   
    I will look into the "magical" reference material you mentioned.
   
    ________________________________
    From: Alex Harui
    Sent: 2/11/19 12:12 AM
    To: "[hidden email]" , "[hidden email]"
    Subject: Re: Profiling
    There are several ways.
   
    The "theoretical" way is to rewrite your code. Populating ComboBoxes on hidden tabs is not a recommended practice. That is effectively having code in the app "pushing data down" into the controls. Instead, in any pattern that has MV in it, the recommended practice is that the components pull what they need from a model. If you do that rewrite, you may find that each Tab loads sufficiently fast when clicked on "on-demand". Maybe a busy cursor spins for a few seconds. Web pages often take a few seconds to load. But that may be a better experience than waiting 30 seconds for the first screen to show up.
   
    Related, any tab that takes a few seconds to load may have its own "push data down" code in it and is initializing controls that may be in a sub-tab or has even sucked in a module or two. Profile each slow Tab and see what is going on.
   
    The "hacky" way is to use Pseudo-Threads. There are fancy Pseudo-Thread patterns, but the cheapest one is just a chain of CallLater functions. Maybe each one initializes a Tab then callLater's the function to initialize the next Tab. Still to slow? Then initialize half a Tab and callLater to initialize the other half.
   
    Other ideas involve re-designing the UI to use more deferred-instantiation components.
   
    FWIW, many years ago I saw a great presentation on UI design by a magician. He talked about understanding human behavior to create illusions. There is also a classic book called "Computers As Theatre" by Brenda Laurel. In live theatre (as opposed to movies), there is the reality of having to find ways to get people and props on and off the stage without distracting the audience. These ideas can apply to problems like this one. If you know that folks will dwell on the first screen for N seconds before they can even decide what to click on, then you've got N seconds to initialize stuff in a pseudo-thread. If you have Tabs that scroll, you can just initialize the first screenful of UI widgets, then you probably have another second or two to initialize stuff off-screen. Busy cursors, UI effects, progressive reveals are all techniques that can be used to create the illusion that the UI is ready to go, when in reality, your stage crew is hustling in the dark behind the sofa.
   
    HTH,
    -Alex
   
    On 2/10/19, 4:57 AM, "Paul Stearns" wrote:
   
    OK, I downloaded Scout & ScoutEnabler. I learned enough to be able to run it and I found the problem area.
   
    The swf in question has 10 tabs with more than 300 objects spread among the tabs. The TabNavigator has creationPolicy="all" set so that once the swf is loaded the "as" code can start populating various comboBoxes and other components on the hidden tabs.
   
    My working hypothesis is flash get's "hung" building all those components at once.
   
    If this is the case, how can I get rid of creationPolicy="all" and once the screen becomes visible, force the creation of all the hidden tabs before I try to populate them? While this may take a little longer, it would provide a better user interface.
   
    ----------------------------------------
    From: "Paul Stearns"
    Sent: 2/10/19 6:55 AM
    To: "[hidden email]"
    Subject: Profiling
    I have a routine that "disappears" for a few seconds. I would like to turn profiling on just before this begins and off when it comes back. Is this possible?
   
    Since the app does many things, I want to isolate just this section where as far as I can tell it is not executing any code from my application.
   
    I am currently using FlexBuilder 3, but will use whatever is available as long as the learning curve isn't too steep and it works with my 3.6 code.
   
   
   

Reply | Threaded
Open this post in threaded view
|

Re: Profiling

Alex Harui-2
In reply to this post by Paul Stearns
Re-adding users@  Please figure out why the ML keeps getting dropped.

I forgot you are using 3.x



From: Paul Stearns <[hidden email]>
Reply-To: "[hidden email]" <[hidden email]>
Date: Monday, February 11, 2019 at 6:56 PM
To: Alex Harui <[hidden email]>
Subject: Re: Profiling

Alex:

I had tried that, but INavigatorContent is not found. I tried to manually add;

import mx.core.INavigatorContent;

That didn't help either. Perhaps it is called something different in v3.6?
Try:

var containerChild:Container = tn.getChildAt(i) as Container;
containerChild.createComponentsFromDescriptors();


________________________________
From: Alex Harui <[hidden email]>
Sent: 2/11/19 7:39 PM
To: "[hidden email]" <[hidden email]>, "[hidden email]" <[hidden email]>
Subject: Re: Profiling
If you have a TabNavigator in a variable/id "tn",

Then you should be able to write:

var containerChild:INavigatorContent = tn.getChildAt(i) as INavigatorContent;
containerChild.createDeferredContent();

HTH,
-Alex

On 2/11/19, 4:37 PM, "Paul Stearns" wrote:

Alex:

I am not sure how I can use the link you referenced. I thought perhaps I could use "containerChild.createDeferredContent " but I am unable to find any components it is applicable to.

----------------------------------------
From: Alex Harui
Sent: 2/11/19 4:07 PM
To: "[hidden email]" , "[hidden email]"
Subject: Re: Profiling
Re-adding users@

IIRC, the key piece is a loop in ViewStack’s setActualCreationPolicies (around line 1058)
https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fapache%2Fflex-sdk%2Fblob%2Fmaster%2Fframeworks%2Fprojects%2Fmx%2Fsrc%2Fmx%2Fcontainers%2FViewStack.as&data=02%7C01%7Caharui%40adobe.com%7C5a60c62e798c4d337ee808d690823bea%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636855286357686522&sdata=I03rmfnRqEdQdCUk1ASZQMldT7TkHJAf2g7%2BWHIKYUA%3D&reserved=0<https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fapache%2Fflex-sdk%2Fblob%2Fmaster%2Fframeworks%2Fprojects%2Fmx%2Fsrc%2Fmx%2Fcontainers%2FViewStack.as&data=02%7C01%7Caharui%40adobe.com%7C1665d84192f3470a9c5a08d69095a69a%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636855369804198471&sdata=qga8OsX0yWf7K5R9dus1AV46eu6XdlxBr4rSvs092XM%3D&reserved=0>

It calls each child’s createDeferredContent(). The trick is to figure out when to call it on each child. Apparently, calling it on all 9 other tabs at once causes so much code to run that it freezes the UI.

Like the magicians I referred to upthread, it is important to know your audience. If the user is typing, it is hard to sneak in one second of computation. If the user is not typing and moving a mouse, you might be able to get away with a one second pause. But if a user makes a query, they might expect a pause and if the query is asynchronous, that’s a good time to sneak in some computation. And if 90% of the users go to tab 2, that may be the only one you need to initialize during the query. And then initialize the other 8 when the results come back and the user is pondering the results.

Or maybe they will put up with 9 one-second pauses while they are typing and all you have to do is use callLater to “unravel” the loop. Put the iterator in a variable, call one createDeferredContent, (and maybe validateNow()) then increment the variable and callLater.

HTH,
-Alex

From: Paul Stearns
Reply-To: "[hidden email]"
Date: Monday, February 11, 2019 at 4:37 AM
To: Alex Harui
Subject: Re: Profiling

Alex:

I would like to take a middle road...

Upon startup there are a number of combo boxes which get populated. Then the user enters some query data, a query is performed and the rest get populated.

I took the time to rewrite the initialization of the 22 combo boxes using bindable Array Collections so that the TabNavigator can load just the 1st page. I would like to have each of the hidden tabs populate while waiting for the user to enter the query data. I have been unable to find how to tell each hidden tab to render individually.

You mention Initializing tabs, code wise, how is that accomplished? I've tried a few things with no luck.

I found that I can define the TabNavigator's creationPolicy as "auto", wait until the 1st tab is rendered, and switch the TabNavigator's creation policy to "all" it will then populate the other 9 tabs. This does show the first tab much quicker but it doesn't allow the entry of data until all of the other tabs are rendered. I was hoping to be able to do the callLater trick to give a break in between each load. Somewhat similar to a .NET Application.doevents().

I will look into the "magical" reference material you mentioned.

________________________________
From: Alex Harui
Sent: 2/11/19 12:12 AM
To: "[hidden email]" , "[hidden email]"
Subject: Re: Profiling
There are several ways.

The "theoretical" way is to rewrite your code. Populating ComboBoxes on hidden tabs is not a recommended practice. That is effectively having code in the app "pushing data down" into the controls. Instead, in any pattern that has MV in it, the recommended practice is that the components pull what they need from a model. If you do that rewrite, you may find that each Tab loads sufficiently fast when clicked on "on-demand". Maybe a busy cursor spins for a few seconds. Web pages often take a few seconds to load. But that may be a better experience than waiting 30 seconds for the first screen to show up.

Related, any tab that takes a few seconds to load may have its own "push data down" code in it and is initializing controls that may be in a sub-tab or has even sucked in a module or two. Profile each slow Tab and see what is going on.

The "hacky" way is to use Pseudo-Threads. There are fancy Pseudo-Thread patterns, but the cheapest one is just a chain of CallLater functions. Maybe each one initializes a Tab then callLater's the function to initialize the next Tab. Still to slow? Then initialize half a Tab and callLater to initialize the other half.

Other ideas involve re-designing the UI to use more deferred-instantiation components.

FWIW, many years ago I saw a great presentation on UI design by a magician. He talked about understanding human behavior to create illusions. There is also a classic book called "Computers As Theatre" by Brenda Laurel. In live theatre (as opposed to movies), there is the reality of having to find ways to get people and props on and off the stage without distracting the audience. These ideas can apply to problems like this one. If you know that folks will dwell on the first screen for N seconds before they can even decide what to click on, then you've got N seconds to initialize stuff in a pseudo-thread. If you have Tabs that scroll, you can just initialize the first screenful of UI widgets, then you probably have another second or two to initialize stuff off-screen. Busy cursors, UI effects, progressive reveals are all techniques that can be used to create the illusion that the UI is ready to go, when in reality, your stage crew is hustling in the dark behind the sofa.

HTH,
-Alex

On 2/10/19, 4:57 AM, "Paul Stearns" wrote:

OK, I downloaded Scout & ScoutEnabler. I learned enough to be able to run it and I found the problem area.

The swf in question has 10 tabs with more than 300 objects spread among the tabs. The TabNavigator has creationPolicy="all" set so that once the swf is loaded the "as" code can start populating various comboBoxes and other components on the hidden tabs.

My working hypothesis is flash get's "hung" building all those components at once.

If this is the case, how can I get rid of creationPolicy="all" and once the screen becomes visible, force the creation of all the hidden tabs before I try to populate them? While this may take a little longer, it would provide a better user interface.

----------------------------------------
From: "Paul Stearns"
Sent: 2/10/19 6:55 AM
To: "[hidden email]"
Subject: Profiling
I have a routine that "disappears" for a few seconds. I would like to turn profiling on just before this begins and off when it comes back. Is this possible?

Since the app does many things, I want to isolate just this section where as far as I can tell it is not executing any code from my application.

I am currently using FlexBuilder 3, but will use whatever is available as long as the learning curve isn't too steep and it works with my 3.6 code.




Reply | Threaded
Open this post in threaded view
|

Re: Profiling

Paul Stearns
In reply to this post by Paul Stearns
Alex:

Is there an analogous section of code for 3.5 I can go look at?

If so where can I find it?

----------------------------------------
From: Alex Harui <[hidden email]>
Sent: 2/11/19 10:05 PM
To: "[hidden email]" <[hidden email]>, "[hidden email]" <[hidden email]>
Subject: Re: Profiling
Re-adding users@ Please figure out why the ML keeps getting dropped.

I forgot you are using 3.x

From: Paul Stearns
Reply-To: "[hidden email]"
Date: Monday, February 11, 2019 at 6:56 PM
To: Alex Harui
Subject: Re: Profiling

Alex:

I had tried that, but INavigatorContent is not found. I tried to manually add;

import mx.core.INavigatorContent;

That didn't help either. Perhaps it is called something different in v3.6?
Try:

var containerChild:Container = tn.getChildAt(i) as Container;
containerChild.createComponentsFromDescriptors();

________________________________
From: Alex Harui
Sent: 2/11/19 7:39 PM
To: "[hidden email]" , "[hidden email]"
Subject: Re: Profiling
If you have a TabNavigator in a variable/id "tn",

Then you should be able to write:

var containerChild:INavigatorContent = tn.getChildAt(i) as INavigatorContent;
containerChild.createDeferredContent();

HTH,
-Alex

On 2/11/19, 4:37 PM, "Paul Stearns" wrote:

Alex:

I am not sure how I can use the link you referenced. I thought perhaps I could use "containerChild.createDeferredContent " but I am unable to find any components it is applicable to.

----------------------------------------
From: Alex Harui
Sent: 2/11/19 4:07 PM
To: "[hidden email]" , "[hidden email]"
Subject: Re: Profiling
Re-adding users@

IIRC, the key piece is a loop in ViewStack’s setActualCreationPolicies (around line 1058)
https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fapache%2Fflex-sdk%2Fblob%2Fmaster%2Fframeworks%2Fprojects%2Fmx%2Fsrc%2Fmx%2Fcontainers%2FViewStack.as&data=02%7C01%7Caharui%40adobe.com%7C5a60c62e798c4d337ee808d690823bea%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636855286357686522&sdata=I03rmfnRqEdQdCUk1ASZQMldT7TkHJAf2g7%2BWHIKYUA%3D&reserved=0

It calls each child’s createDeferredContent(). The trick is to figure out when to call it on each child. Apparently, calling it on all 9 other tabs at once causes so much code to run that it freezes the UI.

Like the magicians I referred to upthread, it is important to know your audience. If the user is typing, it is hard to sneak in one second of computation. If the user is not typing and moving a mouse, you might be able to get away with a one second pause. But if a user makes a query, they might expect a pause and if the query is asynchronous, that’s a good time to sneak in some computation. And if 90% of the users go to tab 2, that may be the only one you need to initialize during the query. And then initialize the other 8 when the results come back and the user is pondering the results.

Or maybe they will put up with 9 one-second pauses while they are typing and all you have to do is use callLater to “unravel” the loop. Put the iterator in a variable, call one createDeferredContent, (and maybe validateNow()) then increment the variable and callLater.

HTH,
-Alex

From: Paul Stearns
Reply-To: "[hidden email]"
Date: Monday, February 11, 2019 at 4:37 AM
To: Alex Harui
Subject: Re: Profiling

Alex:

I would like to take a middle road...

Upon startup there are a number of combo boxes which get populated. Then the user enters some query data, a query is performed and the rest get populated.

I took the time to rewrite the initialization of the 22 combo boxes using bindable Array Collections so that the TabNavigator can load just the 1st page. I would like to have each of the hidden tabs populate while waiting for the user to enter the query data. I have been unable to find how to tell each hidden tab to render individually.

You mention Initializing tabs, code wise, how is that accomplished? I've tried a few things with no luck.

I found that I can define the TabNavigator's creationPolicy as "auto", wait until the 1st tab is rendered, and switch the TabNavigator's creation policy to "all" it will then populate the other 9 tabs. This does show the first tab much quicker but it doesn't allow the entry of data until all of the other tabs are rendered. I was hoping to be able to do the callLater trick to give a break in between each load. Somewhat similar to a .NET Application.doevents().

I will look into the "magical" reference material you mentioned.

________________________________
From: Alex Harui
Sent: 2/11/19 12:12 AM
To: "[hidden email]" , "[hidden email]"
Subject: Re: Profiling
There are several ways.

The "theoretical" way is to rewrite your code. Populating ComboBoxes on hidden tabs is not a recommended practice. That is effectively having code in the app "pushing data down" into the controls. Instead, in any pattern that has MV in it, the recommended practice is that the components pull what they need from a model. If you do that rewrite, you may find that each Tab loads sufficiently fast when clicked on "on-demand". Maybe a busy cursor spins for a few seconds. Web pages often take a few seconds to load. But that may be a better experience than waiting 30 seconds for the first screen to show up.

Related, any tab that takes a few seconds to load may have its own "push data down" code in it and is initializing controls that may be in a sub-tab or has even sucked in a module or two. Profile each slow Tab and see what is going on.

The "hacky" way is to use Pseudo-Threads. There are fancy Pseudo-Thread patterns, but the cheapest one is just a chain of CallLater functions. Maybe each one initializes a Tab then callLater's the function to initialize the next Tab. Still to slow? Then initialize half a Tab and callLater to initialize the other half.

Other ideas involve re-designing the UI to use more deferred-instantiation components.

FWIW, many years ago I saw a great presentation on UI design by a magician. He talked about understanding human behavior to create illusions. There is also a classic book called "Computers As Theatre" by Brenda Laurel. In live theatre (as opposed to movies), there is the reality of having to find ways to get people and props on and off the stage without distracting the audience. These ideas can apply to problems like this one. If you know that folks will dwell on the first screen for N seconds before they can even decide what to click on, then you've got N seconds to initialize stuff in a pseudo-thread. If you have Tabs that scroll, you can just initialize the first screenful of UI widgets, then you probably have another second or two to initialize stuff off-screen. Busy cursors, UI effects, progressive reveals are all techniques that can be used to create the illusion that the UI is ready to go, when in reality, your stage crew is hustling in the dark behind the sofa.

HTH,
-Alex

On 2/10/19, 4:57 AM, "Paul Stearns" wrote:

OK, I downloaded Scout & ScoutEnabler. I learned enough to be able to run it and I found the problem area.

The swf in question has 10 tabs with more than 300 objects spread among the tabs. The TabNavigator has creationPolicy="all" set so that once the swf is loaded the "as" code can start populating various comboBoxes and other components on the hidden tabs.

My working hypothesis is flash get's "hung" building all those components at once.

If this is the case, how can I get rid of creationPolicy="all" and once the screen becomes visible, force the creation of all the hidden tabs before I try to populate them? While this may take a little longer, it would provide a better user interface.

----------------------------------------
From: "Paul Stearns"
Sent: 2/10/19 6:55 AM
To: "[hidden email]"
Subject: Profiling
I have a routine that "disappears" for a few seconds. I would like to turn profiling on just before this begins and off when it comes back. Is this possible?

Since the app does many things, I want to isolate just this section where as far as I can tell it is not executing any code from my application.

I am currently using FlexBuilder 3, but will use whatever is available as long as the learning curve isn't too steep and it works with my 3.6 code.


Reply | Threaded
Open this post in threaded view
|

Re: Profiling

Alex Harui-2
I pasted it, but too far down so you may have missed it:

Try:
   
    var containerChild:Container = tn.getChildAt(i) as Container;
    containerChild.createComponentsFromDescriptors();

HTH,
-Alex

On 2/11/19, 7:38 PM, "Paul Stearns" <[hidden email]> wrote:

    Alex:
   
    Is there an analogous section of code for 3.5 I can go look at?
   
    If so where can I find it?
   
    ----------------------------------------
    From: Alex Harui <[hidden email]>
    Sent: 2/11/19 10:05 PM
    To: "[hidden email]" <[hidden email]>, "[hidden email]" <[hidden email]>
    Subject: Re: Profiling
    Re-adding users@ Please figure out why the ML keeps getting dropped.
   
    I forgot you are using 3.x
   
    From: Paul Stearns
    Reply-To: "[hidden email]"
    Date: Monday, February 11, 2019 at 6:56 PM
    To: Alex Harui
    Subject: Re: Profiling
   
    Alex:
   
    I had tried that, but INavigatorContent is not found. I tried to manually add;
   
    import mx.core.INavigatorContent;
   
    That didn't help either. Perhaps it is called something different in v3.6?
    Try:
   
    var containerChild:Container = tn.getChildAt(i) as Container;
    containerChild.createComponentsFromDescriptors();
   
    ________________________________
    From: Alex Harui
    Sent: 2/11/19 7:39 PM
    To: "[hidden email]" , "[hidden email]"
    Subject: Re: Profiling
    If you have a TabNavigator in a variable/id "tn",
   
    Then you should be able to write:
   
    var containerChild:INavigatorContent = tn.getChildAt(i) as INavigatorContent;
    containerChild.createDeferredContent();
   
    HTH,
    -Alex
   
    On 2/11/19, 4:37 PM, "Paul Stearns" wrote:
   
    Alex:
   
    I am not sure how I can use the link you referenced. I thought perhaps I could use "containerChild.createDeferredContent " but I am unable to find any components it is applicable to.
   
    ----------------------------------------
    From: Alex Harui
    Sent: 2/11/19 4:07 PM
    To: "[hidden email]" , "[hidden email]"
    Subject: Re: Profiling
    Re-adding users@
   
    IIRC, the key piece is a loop in ViewStack’s setActualCreationPolicies (around line 1058)
    https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fapache%2Fflex-sdk%2Fblob%2Fmaster%2Fframeworks%2Fprojects%2Fmx%2Fsrc%2Fmx%2Fcontainers%2FViewStack.as&amp;data=02%7C01%7Caharui%40adobe.com%7Ce880fe44cbad4a0807dd08d6909b9b73%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636855395337154782&amp;sdata=zlVEFW7Tavv0sBLiOCd4jGkijeyPTsFd88XD9Bg7L6o%3D&amp;reserved=0
   
    It calls each child’s createDeferredContent(). The trick is to figure out when to call it on each child. Apparently, calling it on all 9 other tabs at once causes so much code to run that it freezes the UI.
   
    Like the magicians I referred to upthread, it is important to know your audience. If the user is typing, it is hard to sneak in one second of computation. If the user is not typing and moving a mouse, you might be able to get away with a one second pause. But if a user makes a query, they might expect a pause and if the query is asynchronous, that’s a good time to sneak in some computation. And if 90% of the users go to tab 2, that may be the only one you need to initialize during the query. And then initialize the other 8 when the results come back and the user is pondering the results.
   
    Or maybe they will put up with 9 one-second pauses while they are typing and all you have to do is use callLater to “unravel” the loop. Put the iterator in a variable, call one createDeferredContent, (and maybe validateNow()) then increment the variable and callLater.
   
    HTH,
    -Alex
   
    From: Paul Stearns
    Reply-To: "[hidden email]"
    Date: Monday, February 11, 2019 at 4:37 AM
    To: Alex Harui
    Subject: Re: Profiling
   
    Alex:
   
    I would like to take a middle road...
   
    Upon startup there are a number of combo boxes which get populated. Then the user enters some query data, a query is performed and the rest get populated.
   
    I took the time to rewrite the initialization of the 22 combo boxes using bindable Array Collections so that the TabNavigator can load just the 1st page. I would like to have each of the hidden tabs populate while waiting for the user to enter the query data. I have been unable to find how to tell each hidden tab to render individually.
   
    You mention Initializing tabs, code wise, how is that accomplished? I've tried a few things with no luck.
   
    I found that I can define the TabNavigator's creationPolicy as "auto", wait until the 1st tab is rendered, and switch the TabNavigator's creation policy to "all" it will then populate the other 9 tabs. This does show the first tab much quicker but it doesn't allow the entry of data until all of the other tabs are rendered. I was hoping to be able to do the callLater trick to give a break in between each load. Somewhat similar to a .NET Application.doevents().
   
    I will look into the "magical" reference material you mentioned.
   
    ________________________________
    From: Alex Harui
    Sent: 2/11/19 12:12 AM
    To: "[hidden email]" , "[hidden email]"
    Subject: Re: Profiling
    There are several ways.
   
    The "theoretical" way is to rewrite your code. Populating ComboBoxes on hidden tabs is not a recommended practice. That is effectively having code in the app "pushing data down" into the controls. Instead, in any pattern that has MV in it, the recommended practice is that the components pull what they need from a model. If you do that rewrite, you may find that each Tab loads sufficiently fast when clicked on "on-demand". Maybe a busy cursor spins for a few seconds. Web pages often take a few seconds to load. But that may be a better experience than waiting 30 seconds for the first screen to show up.
   
    Related, any tab that takes a few seconds to load may have its own "push data down" code in it and is initializing controls that may be in a sub-tab or has even sucked in a module or two. Profile each slow Tab and see what is going on.
   
    The "hacky" way is to use Pseudo-Threads. There are fancy Pseudo-Thread patterns, but the cheapest one is just a chain of CallLater functions. Maybe each one initializes a Tab then callLater's the function to initialize the next Tab. Still to slow? Then initialize half a Tab and callLater to initialize the other half.
   
    Other ideas involve re-designing the UI to use more deferred-instantiation components.
   
    FWIW, many years ago I saw a great presentation on UI design by a magician. He talked about understanding human behavior to create illusions. There is also a classic book called "Computers As Theatre" by Brenda Laurel. In live theatre (as opposed to movies), there is the reality of having to find ways to get people and props on and off the stage without distracting the audience. These ideas can apply to problems like this one. If you know that folks will dwell on the first screen for N seconds before they can even decide what to click on, then you've got N seconds to initialize stuff in a pseudo-thread. If you have Tabs that scroll, you can just initialize the first screenful of UI widgets, then you probably have another second or two to initialize stuff off-screen. Busy cursors, UI effects, progressive reveals are all techniques that can be used to create the illusion that the UI is ready to go, when in reality, your stage crew is hustling in the dark behind the sofa.
   
    HTH,
    -Alex
   
    On 2/10/19, 4:57 AM, "Paul Stearns" wrote:
   
    OK, I downloaded Scout & ScoutEnabler. I learned enough to be able to run it and I found the problem area.
   
    The swf in question has 10 tabs with more than 300 objects spread among the tabs. The TabNavigator has creationPolicy="all" set so that once the swf is loaded the "as" code can start populating various comboBoxes and other components on the hidden tabs.
   
    My working hypothesis is flash get's "hung" building all those components at once.
   
    If this is the case, how can I get rid of creationPolicy="all" and once the screen becomes visible, force the creation of all the hidden tabs before I try to populate them? While this may take a little longer, it would provide a better user interface.
   
    ----------------------------------------
    From: "Paul Stearns"
    Sent: 2/10/19 6:55 AM
    To: "[hidden email]"
    Subject: Profiling
    I have a routine that "disappears" for a few seconds. I would like to turn profiling on just before this begins and off when it comes back. Is this possible?
   
    Since the app does many things, I want to isolate just this section where as far as I can tell it is not executing any code from my application.
   
    I am currently using FlexBuilder 3, but will use whatever is available as long as the learning curve isn't too steep and it works with my 3.6 code.