1 person found this helpful
Between “complete” and “preinitialize”, the player has to interpret all the bytes it downloaded, then start running code that sets up styles, databindings, embedded fonts, resources, and probably a few things I’m forgetting. If you are using some sort of application framework like Parsley, there might be additional work done as well. Usually, the heavy lifting in an app happens after preinitialize when all of the child components get created and initialized.
Breaking a single SWF into modules reduces the number of bytes the player has to interpret (although that shouldn’t really take very long) and reduces the number of styles and databindings that have to be setup, assuming the module isn’t needed until after the first screen appears. But primarily, it reduces the number of child components that get instantiated if you weren’t already deferring the creation through some other technique.
I don’t know how many a “few seconds” is, but getting the first screen up in less than two seconds can be challenging. Try a hello world app so you know the baseline. Fancier preloaders, and using fewer components and containers can help.
I was reffering not about breaking a swf into modules, but using Module instead of Application. Would it bring any benefits?
And the swfs that are loading are not at the first screen. There is menu from which you select which pages to load and those pages are loading in few seconds (and I say few because for me is about 2 but clients are complaining that is more then five). It is any way influence by the operating system, browser? So, if you have any suggestion to this approach, please, let me know.
Meanwhile I'll run somer tests, thank you
Modules should load faster than sub-applications. Sub-applications can be built with different SDK versions than the main App which is extremely important in some scenarios like a forms manager with 1000’s of forms where each form is a SWF. Sub-applications can also run inside their own security sandboxes which is extremely important if someone you don’t trust is allowed to create SWFs. Sometimes, these forms managers allow 3rd party development of forms.
Modules will load faster because they don’t have to run all of that startup code for the application and because they should be smaller SWFs if you exclude all common classes.
OS and browser does make a small difference in performance numbers, but it should affect modules and sub-apps in a similar fashion. What matters most is how much code you need to run and how fast the user’s computer is and how many other apps that computer is running and how much memory it has to run it.
I have added some traces in code to see what happens in other's client machines and the only segnificant difference is the amount of time needed to load the sub-application inside the application. And I suppose this is due to the Internet connection.
Lots of thanks for your answers
If the interval you are concerned about is the time between “complete” and “preinitialize” then it isn’t download time that is an issue, it is the amount of SWF bytes that need interpreting, but primarily, the amount of code that needs to run to get to the preinitialize event. Unless there are significant configuration differences between computers, a performance profile of the app on your machine should show the same hotspots as the slower machines, and point out places where optimization would be useful.
no, it's the interval of time between the user clicks a butoon to load a swf and the loaded complet event is dispatched. It is considerable larger on the client the for me. The rest are similar (not exactly, but also there is not a big difference). It could be other reason then the Internet connection? The swf that loads it around 110KB, I suppose it's not that big. It takes about 0.45 second for me to load and for client is arround 2 seconds. I'm curious if converting it into module will help
1 person found this helpful
Load requests are actually serviced at the frame boundary (when code has finished running and the screen has been updated). That means there is a small chance that there is something else your app is doing in response to the click that delays when the request actually goes out and the compute time for that is significant on the user’s computer because of CPU and/or memory. But you’re probably right, it is the internet connection.
At home, on DSL, wireless and VPN, I get about 80Kb/sec, meaning that a simple helloworld app that is about 80Kb can show up in about 1 second. At work on the corporate network, download is almost insignificant for 110Kb.
110Kb for a Flex app implies you are using the Flex RSLs so shared code is already extracted from the SWF. Switching to a module might not make that much of a difference, but is probably worth a try. Other options you have are to see if you can figure out how to load the SWF before the user clicks the button, or by using a custom preloader or custom view/effect to show something interesting while the SWF is loading.
yes, indeed I'm using RSLs.
I have converted the web application in a desktop one. And now my question is: why the load of the sub-application takes about 0.5 seconds? What happens during that time, because this time we are not dealing anymore with downloading from the Internet. And if I could improve here, I could also improve the web version. Doesn't it have anything to do with the RSL? Because when I test from Flex Builder I have some trace in the consoler saying somethig about bytes resulted from decompressing the RSL.
I have tried with custom preloader, clients are still unsatisfied, to load the swf before is not an option because we have over 40 files, custom view/effect remains the only option but I'm sure it will be rejected from the beginning...But I'll have to think about it in order to make it as attractive as possible (my point of view 3 seconds to wait is ok, but clients don't accept more then 1.5)
The RSLs might be a factor in getting the app to show up, but it shouldn’t delay the “complete” event from the loader. That’s because the RSL loading code should be holding the SWF at frame 1 while the RSLs download, but the rest of the SWF should be finishing its download since its request has already started in order to just get frame 1 in and running. Are you really measuring the time to the “complete” event or the “applicationComplete” event instead, which is when a sub-app would become visible.
No, not the applicationComplete event, the complete event of SwfLoader which loads the sub-application. I have also measured the time to preiinitialize of the subapplication (about 0.5), initialize (0.2), creationComplete (0.07) and the rest of the operations (including db access: 0.7), which I would say are reasonable. So the only place I think I could optimize is loading the swf. I will try to decrease the swf size, but really, from 110 KB, I don't know how much smaller could I make it. The downloading speed, there is nothing I can do about unless trying to reduce the size, but then again, why does it take for the desktop application 0.5 seconds? Because we are not dealing with Internet downloading.
Thanks for your help, I'm a little bit under preasure because my clients are fighting to proove my inefficiency or flex inefficiency or both and I do my best to proove none.
So, did you try using modules? Less code gets run and the SWF might be slightly smaller. I would be careful about using the Desktop app as a comparison. I believe that SWFs are loaded in one big lump on desktop and are streamed in when run over HTTP. Also, I assume you are testing using http:// instead of file://
Are these times you listed deltas from each other? Or from the button click?
deltas are from one step to another, so from each other.
I haven't managed to implement with modules, at least not yet, because the base class of all sub-application is contained in a RSL and when trying to access the parameters of the module, the
loaderInfo.urlreturns the url of the RSL and not the module.
Try using the performance profiler. Turn on all checkboxes in the profiler dialog box, startup the app and take a sample and analyze.
for what exactly should I look on profiling? I have created a performance profile from right before clicking the button to load a sub-application.
What are the top 10 functions in terms of cumulative time? How many times are they called and how much time do they take? You can also save the profiling data and make it available for download and I will try to find time to look at it.
Here is the list of the last functions ordered by Cumulative time (so the bottom are with highest). I kept searching for enterFrameEvent and abc-decode, I couldn't really associate it with anything precisely. Does the profiler captures also events related to loading a swf? What does in fact happen when loading a swf? I mean 'in the progress of loading', before the complete event is dispatched?
I have also tried with modules. Even though the size of the module is half the size of the application, it dispatches a ready event in 2 more seconds comparing with the time the application complete was dispatched.
Let me know if the image is not clear enough
2 more seconds for modules? It would be interesting to see that profiler as well.
It is hard to tell without the full dumps and the source code, but I’m going to guess from the image that you are loading a sub-app called Invoices and it uses a SuperTabNavigator. I see a bunch of suspicious things in the data.
1. A mouseEvent or events are consuming 9% of the time. That is highly unusual. If the mouseEvent that requests the load is also causing lots of other processing, the load will not start until the mouseEvent processing has finished
2. There is a lot of time being spent on garbage collection. That is “ok” given a new SWF is loading and has to do a lot of allocations, but it might be worth looking into whether any of those allocations can be deferred or are simply unnecessary or fewer objects can be created via object pooling.
3. There are 20 calls to SuperTabNavigator.styleChanged. Changing styles is expensive. Why are styles being changed? Using a Type Selector might be better,
4. There are 6 calls to SuperTabNavigator.updateDisplayList. In theory, a component should get updated only once, or twice if it gets updated with asynchronous data.
5. Invoice.creationComplete is taking a long time, but it will if some code is calling styleChanged in SuperTabNavigator.
Abc-decode should be a big number when loading a SWF since that is where it decodes the SWF and starts running some code.
The timeline should roughly be:
Enough bytes get downloaded to complete frame 1 -> abc-decode starts parsing the SWF -> shows preloader.
Enough bytes get downloaded to complete frame 2 -> abc-decode start parsing frame 2 -> Application is constructed -> preinitialize -> children are created -> initialize -> EnterFrame -> components get commitProperties called -> -> components get measured -> EnterFrame -> components get layed out and sized in updateDisplayList -> creationComplete -> applicationComplete.
Server data arrives -> deserialized if required -> result event -> update components -> componens get commitProperties, measure, updateDisplayList.
Here is the profiler for modules. To me, it seems improved comparing to sub-application, the size of the swf is almost half smaller, yet, it takes much more time. Maybe it is related to the fact that the time measurements are taken with the relese version of the subaplications and modules (modules is also otimized for the application that loads it) so profiler wouldn't be 100% relevant.
I'll remain with the sub-application version and try to improve it according with your remarks.
The garbage collection is probably also due to the fact the the old subapplication is being unloaded
SuperTabNavigator changes style in order to determine the number of tab headers that can be displayed (depending on the stage size). Probably this and updateDisplayList are called when setting a tab close policy, when seeting the selected tab, I'll look
If you have any other suggestions, linksthat I could study and might help, let me know
Thank you for your help
The profiler should still be relevant. I don’t see any significant differences between this and the other profile image. Is it possible that your module is set to use RSLs? It should be configured for merged-into-code when optimized against the app.
yes, indeed, the module is configured to use RSL. The sub-applications should be configured to use RSL or to merge into code? I have always configured to use RSL, but I don't know if it's the best if the size of my library is big enough and only small part of the classes are used for a specific subapplication.
The main app should use RSLs. All modules should use merged-into-code and the RSL SWCs should be external.