Explanation of Stateless and Stateful skins
There are several approaches to style and skin Flex applications. Adobe has also been nice enough to provide some special skinning extensions and kits to work in conjunction with the CS3-CS4 tools such as Flash, Fireworks, Photoshop and Illustrator.
These extensions provide templates and some export commands to assist the workflow of creating graphical skin and exporting them out to bring into your Flex application. Most of these workflows consist of using a “stateless” approach. This means there is an individual asset for each state of a component, such as an image for the up, over, down, and disabled states of a basic Button. The stateless approach can be used with AI, PS, FW and Flash. The nice thing about using it with AI and Flash, is that you can keep the graphics vector within a SWF, if that is your preference. In FW and PS, they will export as bitmaps.
As for the stateful approach, this had been my preferred choice for the past year or so. This requires the Flex skinning extension kit for Flash where it provides a Make Flex Component Command and provides the FlexComponentBase to your file which allows Flex to communicate and translate with the state and transition frame labels without having to write any additional script within Flash or Flex. This approach also utilizes the Embed Skin Class approach within the CSS v. the Embed Source as with stateless.
Example CSS for a Button
Stateful CSS:
Button.
{
skin: Embed(skinClass=”Button_skin”);
}
Stateless CSS:
Button
{
disabledSkin: Embed(source=”flex_skins.swf”,symbol=”Button_disabledSkin”);
downSkin: Embed(source=”flex_skins.swf”,symbol=”Button_downSkin”);
overSkin: Embed(source=”flex_skins.swf”, symbol=”Button_overSkin”);
upSkin: Embed(source=”flex_skins.swf”, symbol=”Button_upSkin”);
}
As you can see, in the stateful skin, you only need one symbol for all of your states of that particular component. The states are designed within the timeline of the individual symbol within Flash. Inside that symbol, there are two informative layers for Flex to communicate with and to be able to assign the appropriate state/transition to that particular component.
Those layers are states and transitions. A typical button would have frame labels of: up, over, down, disabled, selectedUp, selectedOver, selectedDown, selectedDisabled.
The stateless approach would require creating a separate symbol for each state of that particular component.
Now, for the main point of this post…
Issues with Stateful skins
The stateful skin approach was a channel later introduced by Adobe as one of their recommended workflows, and had seemed to be the most optimal in regards to efficiency and workflow in my opinion. Unfortunately, we (Project Team @ EffectiveUI) have discovered a major flaw with performance using stateful skins within a large Flex application where there are many instances of a component using a graphical skin. In smaller applications with minimal instances of a graphical skin, the performance hit is minimal and may not be noticeable, so it is proportional to the amount of objects using a graphical skin.
On a recent project, we saw a rather large percentage increase in CPU usage when using a stateful skin on a CheckBox and other components. There appears to be an OnEnterFrame recursion on UIMovieClip, which is the Base Class for a stateful skin. We weren’t sure if it was part of the swc, or how Flex was pulling it in and reading it, so we decided to run a quick test. We swapped out the stateful skin with a stateless version using the same exact graphical information in the fla, but just designed as stateless and compiled to a swf. Once the developer threw that into the app, the CPU usage dropped dramatically! It dropped to the expected percentage which should be almost identical to not using any CSS or external styling in your Flex application, since skins should not hit the CPU usage. So, it seems like we have narrowed down the issue to the use of stateful skins.
(note: There were issues on more than just the CheckBox, but this was one of the components we used to try to narrow down the issue)
The Test
A fellow coworker, Greg Owen – Lead Developer @ EffectiveUI, help me create a test environment Flex application (wrapped in AIR), which will instantiate several hundred CheckBoxes, this should provide enough performance in the app to see a hit on the CPU usage while using the stateful skin swc.
In the test app, we did some variations with stateful skins and here are the results:
Running 100 CheckBoxes + stateful skins – CPU usage = 19%
Running 250 CheckBoxes + stateful skins – CPU usage = 30%
Running 500 CheckBoxes + stateful skins – CPU usage = 50%
Running any # of CheckBoxes*—————- CPU usage = 10%
(*no added styles/skins)
You can download the source if you would like to try the test it yourself. You can go into the MXML and alter the amount of instances of the CheckBox, and you can swap the style sheets used between the stateful and stateless skins.
I have created two sets of skins for this CheckBox to swap out and review the difference in performance. One skin is a stateful symbol within a swc, and the other stateless skin is comprised of eight symbols, one for every state of a CheckBox, within the swf.
Download the source files here:
http://www.patrickhansen.com/demos/flex/SkinningTest.zip
Click below to view Greg Owen’s post about this issue:
http://behindtheui.blogspot.com/2009/03/flex-component-kit-cpu-black-hole.html
As a result, I plan on working with stateless skins from here on out until there is a resolution to this issue.I’m also planning on working with Degrafa and FX-G in FB4 more for skinning as well.
updated: March 2009
Here is the post for: Stateless vs. Stateful vs. Degrafa
*On a Mac, you can open the Activity Monitor under Applications/Utilities and you can check the CPU usage.