Try using the profiler to see where the time is going. Modules are primarily meant to defer SWF loading. If you need a whole bunch of them up front, it can cost more than one monolithic swf. But there is a chance that has each module comes in it causes lots of other code to re-layout or something like that.
None of the components from any of the modules are added to the stage until after the user clicks a button that is in the main swf. So in theory I would think there should be no time spent rendering just to load the module SWFs' classes.
The reason I'm not using one monolithic swf is so that I can load the same app in multiple ways and presumably cut down on the load time if I don't need all the modules. Also, I need to be able to add a new features without having to update the main SWF. But, I do need to have all the SWFs loaded before the user can do anything, so I can't defer the loading of them. And even if I did defer them, the user would probably click to get to that part pretty quickly which would just make the UI seem slow. As a rule all user actions once the app is loaded should take less than 250 milliseconds, it appears that loading a module when the user clicks on something is pretty much guaranteed to take longer than that.
I'm actually compiling with "-verify-digests=false" as that cut a bit of time off of the load time.
The top three on the performance profile list are...
Is there a way to debug into what specifically is taking the time? It looks like it's all in the player and not my code. Are there things in SWFs that generally would make it load slower?
Is it unrealistic to expect 10 SWFs to be able to load in less than one second?
Those three numbers from the Performance Profiler are actually the to three cumulative time.
I'm guessing the Self Time numbers are more important, but they aren't much different...
At home, over DSL and VPN, I only get about 80K per second. So yeah, I don’t think 10 modules would load in one second. If they require new RSLs then that’s more loading it needs to do, regardless if they are on the stage or not.
Make sure you’ve turned off filters otherwise your listings will be skewed.
If it were me, I would look into the order modules are loaded so ones you absolutely need for the main screen get loaded first, then load the rest in the order you’d guess they will be needed.
My times are all loading from the browser cache, so there is no network delay in there.
The issue is that I absolutely have to load all the SWFs at some point. At first I had my "Login Page" open first and then load the modules in the background, but the problem with that is that the user can't do anything when the actual module loading is happening, the app basically freezes while the SWFs are loading (it would have been fine if it were just a slow network, because the UI continues to be responsive while the request is outstanding). The only way for the user to not have any hicups is to load them all up front. I just want to understand why it is so slow to load the modules. What is actually happening and is there something I can change with the way the modules are compiled or constructed so that it doesn't take that long to do the module load?
Currently each SWF is in fact loaded serialy. I don't call loadModule on the second module until after the first module has completed, etc. I have to do them serially because there are dependencies between modules.
Clearing the filters did change the output a little, but still no layout or anything shows up in the results, it's just internal player stuff. Is there a way to see more details about what is taking the time in a [pre-render] or [abc-decode]?
Everything is over https:// but from the browser cache. I'm curious how the load behavior is different though?
The main SWF depends on all the RSLs and my understanding is that the modules should reuse those RSLs. Do the RSL dependencies on the modules make it take longer to load?
The biggest module is 1202999 bytes (473404 bytes compressed)
The others are all around 400000 bytes (164000 bytes compressed)
From file:// the SWF is read off the disk in one gulp. From http:// it is streamed in. It could be that when in the browser cache it also gets read in one gulp, though.
If the modules are using RSLs not loaded by the main app, then they might be causing them to load. The debug console should show you if that’s happening.
Each SWF has to get decompressed, then the bytes in the first frame are parsed and the byte-code is decoded to create the structures for the AS VM. That shows up in the profiler as . The main class (FlexModuleFactory) is constructed within abc-decode. Then a READY event should fire to indicate the module is ready to be used. Usually, modules create a bunch of visual components that have to get validated which happens in , then they are finally drawn on the screen.
If you think of the total number of bytes to be decompressed and decoded, that might be a gating factor. When you statically link the modules, is the SWF size about the same numbers as all the modules added up? If the statically linked version is much smaller that implies there is more code sharing you could do to shrink down the modules some more.
There really isn't duplication in the module SWFs, I've spent a good amount of time going over the link reports to get them all down to size. The size of one SWF vs many SWFs is reasonably close. The only thing I can think of at this point to get them any smaller is stop using mxml bindings as that seems to create a bunch of extra classes.
Based on the debug console all the RSLs do in fact load before the module loads start, and then there isn't additional RSL loading. Since the [pre-render] takes the bulk of the time in my performance profiles does that mean it is in fact trying to create visual components? How can I tell what these components are? Since I don't immediately add anything to the stage from the modules I'm not clear what visual components could be created. Could [pre-render] include loading Embed images?
I really appreciate you taking the time to humor me. I feel like it should be obvious to me where the time goes, but somehow it seems like the tools don't actually tell you, it just seems like guesswork.
Post a screenshot of the top 20 by cumulative time.
That's a good idea, I'll try moving the module load and report my findings.
I had a simple progress indicator that redrew during the preloader on each tick of a timer and removed it and the [render] came down a little, but not much.
Also cut down on the number of modules and see how that changes the numbers. Maybe one of the modules is worse than the others. I’m signing off for a while as it is the end of my day.
Well that was extremely enlightening. The module load is almost instantaneous if i have it in response to a button click. It only takes 182ms to load 9 modules (a total of around 1.5 megabytes). An order of magnitude better. It must be something to do with updating my progress indicator.
You have been very helpful. Thanks a lot. I'll try to post details on the specifics of what I did wrong.
So my code draws a simple circle to indicate progress using a bunch of graphics.lineTo calls. Apparently I was redrawing my circle on every "progress" event from the module loader. By moving the redraw to only happen on a timer (called every 50ms) instead of as a direct result of the progress event the performance problem goes away.
So the lesson learned is: Don't do rendering in response to loader progress events, it slows the load itself down.
Interestingly, the actual http response seems to be read slower by the browser when doing the rendering in the event. I'm guessing this means that the actually reading of the http stream is on the same thread as the event handler.
Glad you figured it out. There aren’t too many threads in the player so depending on your resultFormat, the response might still get parsed in the AS thread.