Noticeable Flex 3 performance increase using Canvas vs VBox/HBox? - apache-flex

I was told that there is an increase in performance when using Canvas versus HBox or VBox when laying out out the position of children. As a result, a number of our components have been converted over to using Canvas. However, now there is code being added to calculate the x and y positioning of some of the child elements based off of the width and height of other children. Is it worth using a Canvas to increase performance if code needs to be added to determine the coordinates/positions of the children? Is there a better method or technique available that should be practiced other than just minimizing the number of ui components added and specifying positioning absolutely?

There are a number of middle-of-the-road techniques, one of which is to use rendering-type components, such as TileGrid or ItemRenderers, if your layout fits a certain formula. If you're using forms, try using the Form layout component instead of using a custom layout.
If you do need to use the layout engine in Flex, the way to optimize your usage is to remember that certain techniques are used by the framework in increasing performance load, loosely following the below list, the last being the most performance intensive:
absolute positioning (<Canvas>)
relative positioning (<VBox>)
constraint-based positioning (right=0)
advanced constraint-based positioning (<constraintColumns>)
Using relative positioning is usually not that performance intensive. If you are finding that it is, it could be that you're using too many nested containers. Look at your layout architecture and try to find out ways in which your objects may be "over-laid out", and simplify them. A good tool for this is FlexSpy, which lets you introspect object layout at runtime.
Another common performance bottleneck is that your application is attempting to do some number-crunching at the exact same time that your GUI is attempting to respond to user interaction. Although no green threading frameworks exist at the moment which enable you to run UI and logic in separate 'threads', you can use a good architectural framework such as Cairngorm or Mate (there are many) which uses Commands instead of straight up methods, so that functionality execution which may take up processing cycles waits until the UI has finished responding to the user.

A couple things you want to keep in mind while optimizing a Flex UI:
Avoiding excessive nesting of containers. Consider using a Canvas with absolute or constraint-based positioning over nesting lots of HBox / VBox elements. However this doesn't mean you should NEVER use VBox/HBox. You can mix and match, such as using a Canvas as the main container and positioning child Boxes inside them as needed, just try to avoid too much nesting.
Using the UIComponent model properly in custom components. In particular, using invalidateProperties(), invalidateSize() and invalidateDisplayList() so that their companion functions (commitProperties(), measure() and updateDisplayList()) are invoked at an optimal time for the Flash Player. Deepa gives a great talk about this here:
http://tv.adobe.com/#vi+f15384v1002
She explains how making heavy use of the invalidation scheme allows the Flash Player to execute your code at an ideal time, i.e. not in the middle of a screen update. These principles are used by all Flex components and can/should be leveraged regardless of the framework being used.

To make sure I understand:
You heard that Canvas can position children faster than [VH]Box
Canvas only does absolute positioning
Some (many?) of your components have an absolute position, so you switched to using Canvas
But some of your components have a relative position, so you need to write code to position them
Is that correct?
Anyway, assuming I'm correct (which may not be the case), the first thing you want to do is pick the functioning interface which requires the fewest lines of code, then decide if it's "good enough". You want the one with the fewest lines of code because studies have shown that there is a correlation between lines of code and number of bugs (and you don't want bugs). You want to see if it's "good enough" because, if it IS "good enough", you don't need to do anything (if you do try and make it faster, you're committing Premature Optimization).
But that's probably not what you wanted to hear :)
So I'll also suggest that, if you want to stick with Canvas-based layout, you try sticking all the relatively positioned content inside [VH]Boxes, which are then absolutely positioned inside the Canvas. There's a good chance the code Adobe has written is faster than code, so you should try to take advantage of it.
But the only way to know for sure is to try it and profile it.

Related

Practical differences between SVG and Canvas within a ggvis & Shiny Context

I have already read
What is the difference between SVG and HTML5 Canvas?
&&
https://en.wikipedia.org/wiki/Canvas_element#Canvas_versus_Scalable_Vector_Graphics_.28SVG.29
So i am aware of the basic differences, but i was wondering if anyone had encountered any practical difference between the two within the context of ggvis and shiny apart from SVG inability to deal with NA's in the data
The short answer:
SVG would be easier for you, since selection and moving it around is already built in. SVG objects are DOM objects, so they have "click" handlers, etc.
DIVs are okay but clunky and have awful performance loading at large numbers.
Canvas has the best performance hands-down, but you have to implement all concepts of managed state (object selection, etc) yourself, or use a library.
The long answer:
HTML5 Canvas is simply a drawing surface for a bit-map. You set up to draw (Say with a color and line thickness), draw that thing, and then the Canvas has no knowledge of that thing: It doesn't know where it is or what it is that you've just drawn, it's just pixels. If you want to draw rectangles and have them move around or be selectable then you have to code all of that from scratch, including the code to remember that you drew them.
SVG on the other hand must maintain references to each object that it renders. Every SVG/VML element you create is a real element in the DOM. By default this allows you to keep much better track of the elements you create and makes dealing with things like mouse events easier by default, but it slows down significantly when there are a large number of objects
Those SVG DOM references mean that some of the footwork of dealing with the things you draw is done for you. And SVG is faster when rendering really large objects, but slower when rendering many objects.
A game would probably be faster in Canvas. A huge map program would probably be faster in SVG. If you do want to use Canvas, I have some tutorials on getting movable objects up and running here.
Canvas would be better for faster things and heavy bitmap manipulation (like animation), but will take more code if you want lots of interactivity.
I've run a bunch of numbers on HTML DIV-made drawing versus Canvas-made drawing. I could make a huge post about the benefits of each, but I will give some of the relevant results of my tests to consider for your specific application:
I made Canvas and HTML DIV test pages, both had movable "nodes." Canvas nodes were objects I created and kept track of in Javascript. HTML nodes were movable Divs.
I added 100,000 nodes to each of my two tests. They performed quite differently:
The HTML test tab took forever to load (timed at slightly under 5 minutes, chrome asked to kill the page the first time). Chrome's task manager says that tab is taking up 168MB. It takes up 12-13% CPU time when I am looking at it, 0% when I am not looking.
The Canvas tab loaded in one second and takes up 30MB. It also takes up 13% of CPU time all of the time, regardless of whether or not one is looking at it. (2013 edit: They've mostly fixed that)
Dragging on the HTML page is smoother, which is expected by the design, since the current setup is to redraw EVERYTHING every 30 milliseconds in the Canvas test. There are plenty of optimizations to be had for Canvas for this. (canvas invalidation being the easiest, also clipping regions, selective redrawing, etc.. just depends on how much you feel like implementing)
There is no doubt you could get Canvas to be faster at object manipulation as the divs in that simple test, and of course far faster in the load time. Drawing/loading is faster in Canvas and has far more room for optimizations, too (ie, excluding things that are off-screen is very easy).
Conclusion:
SVG is probably better for applications and apps with few items (less than 1000? Depends really)
Canvas is better for thousands of objects and careful manipulation, but a lot more code (or a library) is needed to get it off the ground.
HTML Divs are clunky and do not scale, making a circle is only possible with rounded corners, making complex shapes is possible but involves hundreds of tiny tiny pixel-wide divs. Madness ensues.
I have past content from the following link.
Please see this link for more details
HTML5 Canvas vs. SVG vs. div

Famo.us css 3d transforms

Famo.us claims that it "talks directly to the GPU" to compute themselfs the css transforms. I assume they are talking about the 4x4 transform matrix.
When they say the "talk to the GPU" it means they are doing their maths in WebGL?
When they show 3D elements are they using WebGL in a canvas element?
Is their technology real THAT special or their claims are the result of an excellent marketing campaign?
Disclaimer: I do not work for Famo.us, I just share their vision in way software should be built.
The answer to all three questions is no. When they say talks to the GPU, they are not referring to the matrix calculations, they are referring to the matrix3d property of CSS that is GPU accelerated by the browser. By throwing out the box model of normal HTML and CSS, we can create a new model that follows the likes of traditional graphics development, which is based on a Cartesian coordinate system and all elements are absolutely positioned with 3d transforms.
There is no WebGL and no write to canvas. Every one of the (surface) elements on screen is just a div that is transformed. Every bit of text will still be highlightable and every button will still be clickable. It's all live. The rendering starts at the Context, which in most cases is the top level of the render tree. Nodes for other subviews are added as children. On each render cycle the context's render function is called, which in return looks down the tree and calls the render function of each subview recursively. Since the render engine is tightly integrated with requestAnimationFrame, all calculations can be determined then rendered at the time of screen refresh.
The technology can be considered special, because it throws away so many traditional paradigms in favor of a more modern approach to building web applications. That being said, it's really only Javascript. HTML was not built for web applications. HTML and CSS were built for static content pages and work as a crutch in trying to achieve applications similar to the ones we love and adore on mobile. Famo.us makes it possible to build applications with only JS, or a compile-to-JS language like CoffeeScript. You define Surfaces which correspond to divs on screen, and you apply properties for HTML attributes and CSS. You still have the option to apply CSS classes or inject HTML into surfaces.
In the end the choice is up to you. If you do not see the value, or are comfortable with the way you build web applications, then stick with it. Over the next few months you will see many more demos popping up as real users like myself create them. I can tell you already, it's amazingly promising.
Cheers
I want to add a slightly updated answer:
(I, too, don't work for Famo.us, but I did spend three weeks there working on projects)
While #johntraver has summed up pretty nicely what Famo.us does at the moment, it is important to understand that famo.us WILL support canvas and webGL.
Going deeper into the philosophy of famo.us, it throws away all the tools that HTML and CSS provide for layout and animation. ALL surfaces in famo.us are absolutely positioned at top:0, left:0 and EVERYTHING else is done purely with transforms, that are calculated by famous.
Animations are also done in javascript and don't use CSS transitions or Animations.
The more you think about it, Famo.us has almost no dependency on HTML or CSS, and that is exactly the plan. Famo.us treats HTML as just one of many possible renderers.
They are now working on adding WebGL rendering to famo.us. Essentially, what this will enable is a common API for layout and animation that will be able to render to WebGL AND HTML for the best of both worlds.
So, calculations will still be done in Javascript entirely, but the output may either be surfaces with transforms OR WebGL.
Hope that helps.

SkinnableContainer+Layout vs Group+Rect+Hgroup

I'm trying to add a custom background to my horizontally laid out container. There are two ways mentioned to accomplish this:
Use a SkinnableContainer with a HorizontalLayout
Use a Group with a Rect and another HGroup inside it.
Which is a better option according to memory? Also, is placing multiple groups, hgroups and vgroups in a nested fashion a major flaw in design?
Thanks in advance!
Which is a better option according to memory?
You'll have to test and see, but from a theoretical approach; a SkinnableContainer will perform a lot more processing than a group. My first approach would be to use a group with a Rect inside it. Or, if you're doing mobile development, use a group and draw a Rect on top of it using the graphics API.
Also, is placing multiple groups, hgroups and vgroups in a nested
fashion a major flaw in design?
Not a major design flaw, but it could very well contribute to the lack of performance in an application. It it becomes an issue, you should evaluate your use of containers and see if you can minimize. Sometimes using a basicLayout and writing a layout algorithm will give you a lot more performance, and flexibility. It may very well take longer to write, depending on the complexity, though.

flex: relative sizing and performance

We are building a flex project and would like it to render faster. We do have situations where we reference parent module size properties to size current module containers, as well as current module size properties for a bunch of attributes including font size and element positions and sizes.
Would it help to create temporary variables for
a) pcw=parentcontainer.width, pch= parentcontainer.height
b) ccw=currentcontainer.width, cch=currentcontainer.height
and reference to pcw,pch,ccw and cch while doing positioning. Will that help?
Also given the bulk of the positioning will be done in mxml, will setting these interim variables in initialization function, allow them to be used in mxml such that they will resize as browser size is changed. Thanks for pointers
I'm not sure if you're using the term "Module" a a generic term to refer to a component, or if you are explicitly referring to classes of the Module class.
It breaks encapsulation if a container is aware of it's parents. In Flex, a parent is always responsible for sizing it's children; and a child should never size itself.
You had code like this to access the parent's height and width:
pcw=parentcontainer.width
parentcontainer.height
I can't imagine how saving the parent's height and width values would speed anything up.
I also find it hard to envision a situation where knowing the parent container's width and height is helpful. Often a container has more than one children. It is important to know how much size a component has for laying out it's own children, not how much space the parent has.
The appropriate way to size and position a component's children is to override updateDisplayList(). updateDisplayList() has two parameters: unscaledWidth and unscaledHeight; that is, in essence, the height and width of the component. You should size and position the component's children based on those two values.
Of course, doing so often relies on ActionScript; not MXML.
Your primary question seemed to want to improve performance. There are many factors involved in the performance of an app. Using ActionScript for layout instead of MXML could be one factor that may help improve performance. Minimize your use on binding is another thing that can sometimes help performance.
Have you used the Flex Profiler? Have you stepped through code? Does doing these things help you determine what exactly the performance issue is?
Unless your application changes it's shape a lot, there shouldn't be any problems laying out with Flex if you use proper skinning/component/layout standards.
Most of the problem isn't from Flex, but the code most people add onto their own application that renders the whole system slow. Make sure you brush up on Flash performance improvements (like data structures, limiting binding, proper architecture, object lifecycle, etc).

Flex: six seconds between initialize and creationComplete

I'm working with a large flex applications and I have noticed that one of our largest components (with lots of child canvases) takes about 6 seconds between the initialize and creationComplete events. I've been doing some reading and have found that having lots of nested canvases can cause slowdowns, but i'm not sure if this is where the slowdowns would be? Anyone have any suggestions on speeding this up, or even diagnosing exactly where the slowdowns are coming from?
It's been my experience that nested containers with dynamic sizing are the most common cause of these types of lags. Some things to try:
Set explicit sizes/positions for your containers/components whenever possible. This reduces the incredible amount of measuring that goes on within the framework during the creation process.
Reduce the number of nested containers. Sounds obvious, but it's amazing how much you can cut away when you start looking critically at how your UI is set up. Specifically, are there HBox and VBox containers you can get rid of by simply setting explicit positions/sizes for the child components? Do you really need to use a Form container?
Switch your containers to the much lighter weight Spark Groups instead of using the heavier weight Canvas where possible.
Hope that helps. If not, post some code so we can dig in to your particular issue.
The biggest thing to consider is to use VBox's and/or HBox's in place of some dynamically generated x's and y's. VBox and HBox are much more efficient. Look into it!
Adding many display objects to the display list all at once can take a long time, especially if we're talking about Flex containers that have layout and scrolling logic in the mix. Since you say you're using many Canvas containers, that could certainly be the issue you're running into.
I know that a lot of developers abuse the creationPolicy property. Normally, it is set to "auto" which allows Flex to defer instantiation of a container's children until a very short time "later". Often, before the next frame, so you don't even see the difference. Do you happen to set creationPolicy to "all" anywhere in that hierarchy? This could be forcing the Canvases and their children to be created immediately.

Resources