Improve performance guide
authorChris Adams <christopher.adams@nokia.com>
Fri, 29 Jun 2012 02:59:47 +0000 (12:59 +1000)
committerQt by Nokia <qt-info@nokia.com>
Wed, 4 Jul 2012 05:29:31 +0000 (07:29 +0200)
This commit improves documentation about binding optimisation and
positioning.

Task-number: QTBUG-21720
Task-number: QTBUG-25844
Change-Id: Ib2c23583adee9207dfdee9f9d4ec5473fe2a7ec6
Reviewed-by: Michael Brasser <michael.brasser@nokia.com>
src/quick/doc/src/appdevguide/performance.qdoc

index f291813..5250f91 100644 (file)
@@ -83,14 +83,17 @@ It is a good idea to keep binding expressions as simple as possible, since the
 QML engine makes use of an optimized binding expression evaluator which can
 evaluate simple binding expressions without needing to switch into a full
 JavaScript execution environment.  These optimized bindings are evaluated far
-more efficiently than more complex (non-optimized) bindings.
+more efficiently than more complex (non-optimized) bindings.  The basic
+requirement for optimization of bindings is that the type information of every
+symbol accessed must be known at compile time.
 
 Things to avoid in binding expressions to maximize optimizability:
 \list
   \li declaring intermediate JavaScript variables
+  \li accessing "var" properties
   \li calling JavaScript functions
   \li constructing closures or defining functions within the binding expression
-  \li accessing properties outside of the immediate context (generally, this means outside the component)
+  \li accessing properties outside of the immediate evaluation scope
   \li writing to other properties as side effects
 \endlist
 
@@ -102,6 +105,19 @@ with.  This means that non-final property lookup in a binding expression can be
 in some cases, where it is possible that the type of the property being looked up has
 been changed (for example, by a derived type).
 
+The immediate evaluation scope can be summarized by saying that it contains:
+\list
+  \li the properties of the expression scope object (for binding expressions, this is
+      the object to which the property binding belongs)
+  \li ids of any objects in the component
+  \li the properties of the root item in the component
+\endlist
+
+Ids of objects from other components and properties of any such objects, as
+well as symbols defined in or included from a JavaScript import, are not in the
+immediate evaluation scope, and thus bindings which access any of those things
+will not be optimized.
+
 Note that if a binding cannot be optimized by the QML engine's optimized binding
 expression evaluator, and thus must be evaluated by the full JavaScript environment,
 some of the tips listed above will no longer apply.  For example, it can sometimes be
@@ -605,24 +621,31 @@ Rectangle {
 }
 \endcode
 
-Note that this is still not as efficient as specifying a static size, so you should still specify static sizes via
-the x, y, width and height properties.
+Positioning with bindings (by assigning binding expressions to the x, y, width
+and height properties of visual objects, rather than using anchors) is
+relatively slow, although it allows maximum flexibility.
 
-Item coordinates are always relative to their parent, so if you wanted to be a fixed offset from your parent's
-0,0 coordinate you should not use anchors. For example the following items are in the same place, but the anchors
-code is not as resource efficient as fixed positioning.
+If the layout is not dynamic, the most performant way to specify the layout is
+via static initialization of the x, y, width and height properties.  Item
+coordinates are always relative to their parent, so if you wanted to be a fixed
+offset from your parent's 0,0 coordinate you should not use anchors.  In the
+following example the child Rectangle objects are in the same place, but the
+anchors code shown is not as resource efficient as the code which
+uses fixed positioning via static initialization:
 
 \code
 Rectangle {
     width: 60
     height: 60
     Rectangle {
+        id: fixedPositioning
         x: 20
         y: 20
         width: 20
         height: 20
     }
     Rectangle {
+        id: anchorPositioning
         anchors.fill: parent
         anchors.margins: 20
     }