f2918139dccb50bd5cb0cd37f192e150f365b9f6
[profile/ivi/qtdeclarative.git] / src / quick / doc / src / appdevguide / performance.qdoc
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the documentation of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:FDL$
9 ** GNU Free Documentation License
10 ** Alternatively, this file may be used under the terms of the GNU Free
11 ** Documentation License version 1.3 as published by the Free Software
12 ** Foundation and appearing in the file included in the packaging of
13 ** this file.
14 **
15 ** Other Usage
16 ** Alternatively, this file may be used in accordance with the terms
17 ** and conditions contained in a signed written agreement between you
18 ** and Nokia.
19 **
20 **
21 **
22 **
23 **
24 ** $QT_END_LICENSE$
25 **
26 ****************************************************************************/
27
28 /*!
29 \page qtquick-performance.html
30 \title Performance Considerations And Suggestions
31 \brief Discussion of performance-related tradeoffs and best-practices
32
33 \section1 Timing Considerations
34
35 As an application developer, you must strive to allow the rendering engine
36 to achieve a consistent 60 frames-per-second refresh rate.  60 FPS means
37 that there is approximately 16 milliseconds between each frame in which
38 processing can be done, which includes the processing required to upload
39 the draw primitives to the graphics hardware.
40
41 In practice, this means that the application developer should use asynchronous,
42 event driven programming wherever possible, should use worker threads to do
43 significant processing, should never manually spin the event loop, and should
44 never spend more than a couple of milliseconds per frame within blocking functions.
45 Failure to do so will result in skipped frames, which has a drastic effect on the
46 user experience.
47
48 \note A pattern which is tempting, but should \e never be used, is creating your
49 own QEventLoop or calling QCoreApplication::processEvents() in order to avoid
50 blocking within a C++ code block invoked from QML. This is dangerous because
51 when an event loop is entered in a signal handler or binding, the QML engine
52 continues to run other bindings, animations, transitions, etc. Those bindings
53 can then cause side effects which, for example, destroy the hierarchy containing
54 your event loop.
55
56 \section1 Profiling
57
58 The most important tip is: use the QML profiler included with Qt Creator.  Knowing
59 where time is spent in an application will allow you to focus on problem areas which
60 actually exist, rather than problem areas which potentially exist.  See the Qt Creator
61 manual for more information on how to use the QML profiling tool.
62
63 Determining which bindings are being run the most often, or which functions your
64 application is spending the most time in, will allow you to decide whether you need
65 to optimize the problem areas, or redesign some implementation details of your
66 application so that the performance is improved.  Attempting to optimize code without
67 profiling is likely to result in very minor rather than significant performance
68 improvements.
69
70 \section1 JavaScript
71
72 Most QML applications will have a large amount of JavaScript code in them, in the
73 form of dynamic functions, signal handlers, and property binding expressions.
74 This is not generally a problem (in fact, due to some optimizations in the QML engine
75 (bindings compiler, etc) it can for some use-cases be faster than calling a C++ function)
76 however care must be taken to ensure that unnecessary processing isn't triggered
77 accidentally.
78
79 \section2 Bindings
80
81 There are two types of bindings in QML: optimized and non-optimized bindings.
82 It is a good idea to keep binding expressions as simple as possible, since the
83 QML engine makes use of an optimized binding expression evaluator which can
84 evaluate simple binding expressions without needing to switch into a full
85 JavaScript execution environment.  These optimized bindings are evaluated far
86 more efficiently than more complex (non-optimized) bindings.
87
88 Things to avoid in binding expressions to maximize optimizability:
89 \list
90   \li declaring intermediate JavaScript variables
91   \li calling JavaScript functions
92   \li constructing closures or defining functions within the binding expression
93   \li accessing properties outside of the immediate context (generally, this means outside the component)
94   \li writing to other properties as side effects
95 \endlist
96
97 The QML_COMPILER_STATS environment variable may be set when running a QML application
98 to print statistics about how many bindings were able to be optimized.
99
100 Bindings are quickest when they know the type of objects and properties they are working
101 with.  This means that non-final property lookup in a binding expression can be slower
102 in some cases, where it is possible that the type of the property being looked up has
103 been changed (for example, by a derived type).
104
105 Note that if a binding cannot be optimized by the QML engine's optimized binding
106 expression evaluator, and thus must be evaluated by the full JavaScript environment,
107 some of the tips listed above will no longer apply.  For example, it can sometimes be
108 beneficial to cache the result of property resolution in an intermediate JavaScript
109 variable, in a very complex binding.  Upcoming sections have more information on these
110 sorts of optimizations.
111
112 \section2 Type-Conversion
113
114 One major cost of using JavaScript is that in most cases when a property from a QML
115 element is accessed, a JavaScript object with an external resource containing the
116 underlying C++ data (or a reference to it) is created.  In most cases, this is fairly
117 inexpensive, but in others it can be quite expensive.  One example of where it is
118 expensive is assigning a C++ QVariantMap Q_PROPERTY to a QML "variant" property.
119 Lists can also be expensive, although sequences of specific types (QList of int,
120 qreal, bool, QString, and QUrl) should be inexpensive; other list types involve an
121 expensive conversion cost (creating a new JavaScript Array, and adding new elements
122 one by one, with per-element conversion from C++ type instance to JavaScript value).
123
124 Converting between some basic property types (such as "string" and "url" properties)
125 can also be expensive.  Using the closest matching property type will avoid unnecessary
126 conversion.
127
128 If you must expose a QVariantMap to QML, use a "var" property rather than a "variant"
129 property.  In general, "property var" should be considered to be superior to
130 "property variant" for every use-case in QtQuick 2.0 (note that "property variant"
131 is marked as obsolete in the QtQuick 2.0 documentation), as it allows a true JavaScript
132 reference to be stored (which can reduce the number of conversions required in certain
133 expressions).
134
135 \section2 Resolving Properties
136
137 Property resolution takes time.  While in some cases the result of a lookup can be
138 cached and reused, it is always best to avoid doing unnecessary work altogether, if
139 possible.
140
141 In the following example, we have a block of code which is run often (in this case, it
142 is the contents of an explicit loop; but it could be a commonly-evaluated binding expression,
143 for example) and in it, we resolve the element with the "rect" id and its "color" property
144 multiple times:
145
146 \qml
147 // bad.qml
148 import QtQuick 2.0
149
150 Item {
151     width: 400
152     height: 200
153     Rectangle {
154         id: rect
155         anchors.fill: parent
156         color: "blue"
157     }
158
159     function printValue(which, value) {
160         console.log(which + " = " + value);
161     }
162
163     Component.onCompleted: {
164         var t0 = new Date();
165         for (var i = 0; i < 1000; ++i) {
166             printValue("red", rect.color.r);
167             printValue("green", rect.color.g);
168             printValue("blue", rect.color.b);
169             printValue("alpha", rect.color.a);
170         }
171         var t1 = new Date();
172         console.log("Took: " + (t1.valueOf() - t0.valueOf()) + " milliseconds for 1000 iterations");
173     }
174 }
175 \endqml
176
177 We could instead resolve the common base just once in the block:
178
179 \qml
180 // good.qml
181 import QtQuick 2.0
182
183 Item {
184     width: 400
185     height: 200
186     Rectangle {
187         id: rect
188         anchors.fill: parent
189         color: "blue"
190     }
191
192     function printValue(which, value) {
193         console.log(which + " = " + value);
194     }
195
196     Component.onCompleted: {
197         var t0 = new Date();
198         for (var i = 0; i < 1000; ++i) {
199             var rectColor = rect.color; // resolve the common base.
200             printValue("red", rectColor.r);
201             printValue("green", rectColor.g);
202             printValue("blue", rectColor.b);
203             printValue("alpha", rectColor.a);
204         }
205         var t1 = new Date();
206         console.log("Took: " + (t1.valueOf() - t0.valueOf()) + " milliseconds for 1000 iterations");
207     }
208 }
209 \endqml
210
211 Just this simple change results in a significant performance improvement.
212 Note that the code above can be improved even further (since the property
213 being looked up never changes during the loop processing), by hoisting the
214 property resolution out of the loop, as follows:
215
216 \qml
217 // better.qml
218 import QtQuick 2.0
219
220 Item {
221     width: 400
222     height: 200
223     Rectangle {
224         id: rect
225         anchors.fill: parent
226         color: "blue"
227     }
228
229     function printValue(which, value) {
230         console.log(which + " = " + value);
231     }
232
233     Component.onCompleted: {
234         var t0 = new Date();
235         var rectColor = rect.color; // resolve the common base outside the tight loop.
236         for (var i = 0; i < 1000; ++i) {
237             printValue("red", rectColor.r);
238             printValue("green", rectColor.g);
239             printValue("blue", rectColor.b);
240             printValue("alpha", rectColor.a);
241         }
242         var t1 = new Date();
243         console.log("Took: " + (t1.valueOf() - t0.valueOf()) + " milliseconds for 1000 iterations");
244     }
245 }
246 \endqml
247
248 \section2 Property Bindings
249
250 A property binding expression will be re-evaluated if any of the properties
251 it references are changed.  As such, binding expressions should be kept as
252 simple as possible.
253
254 If you have a loop where you do some processing, but only the final result
255 of the processing is important, it is often better to update a temporary
256 accumulator which you afterwards assign to the property you need to update,
257 rather than incrementally updating the property itself, in order to avoid
258 triggering re-evaluation of binding expressions during the intermediate
259 stages of accumulation.
260
261 The following contrived example illustrates this point:
262
263 \qml
264 // bad.qml
265 import QtQuick 2.0
266
267 Item {
268     id: root
269     width: 200
270     height: 200
271     property int accumulatedValue: 0
272
273     Text {
274         anchors.fill: parent
275         text: root.accumulatedValue.toString()
276         onTextChanged: console.log("text binding re-evaluated")
277     }
278
279     Component.onCompleted: {
280         var someData = [ 1, 2, 3, 4, 5, 20 ];
281         for (var i = 0; i < someData.length; ++i) {
282             accumulatedValue = accumulatedValue + someData[i];
283         }
284     }
285 }
286 \endqml
287
288 The loop in the onCompleted handler causes the "text" property binding to
289 be re-evaluated six times (which then results in any other property bindings
290 which rely on the text value, as well as the onTextChanged signal handler,
291 to be re-evaluated each time, and lays out the text for display each time).
292 This is clearly unnecessary in this case, since we really only care about
293 the final value of the accumulation.
294
295 It could be rewritten as follows:
296
297 \qml
298 // good.qml
299 import QtQuick 2.0
300
301 Item {
302     id: root
303     width: 200
304     height: 200
305     property int accumulatedValue: 0
306
307     Text {
308         anchors.fill: parent
309         text: root.accumulatedValue.toString()
310         onTextChanged: console.log("text binding re-evaluated")
311     }
312
313     Component.onCompleted: {
314         var someData = [ 1, 2, 3, 4, 5, 20 ];
315         var temp = accumulatedValue;
316         for (var i = 0; i < someData.length; ++i) {
317             temp = temp + someData[i];
318         }
319         accumulatedValue = temp;
320     }
321 }
322 \endqml
323
324 \section2 Sequence tips
325
326 As mentioned earlier, some sequence types are fast (eg, QList<int>, QList<qreal>,
327 QList<bool>, QList<QString>, QStringList and QList<QUrl>) while others will be
328 much slower.  Aside from using these types wherever possible instead of slower types,
329 there are some other performance-related semantics you need to be aware of to achieve
330 the best performance.
331
332 Firstly, there are two different implementations for sequence types: one for where
333 the sequence is a Q_PROPERTY of a QObject (we'll call this a reference sequence),
334 and another for where the sequence is returned from a Q_INVOKABLE function of a
335 QObject (we'll call this a copy sequence).
336
337 A reference sequence is read and written via QMetaObject::property() and thus is read
338 and written as a QVariant.  This means that changing the value of any element in the
339 sequence from JavaScript will result in three steps occurring: the complete sequence
340 will be read from the QObject (as a QVariant, but then cast to a sequence of the correct
341 type); the element at the specified index will be changed in that sequence; and the
342 complete sequence will be written back to the QObject (as a QVariant).
343
344 A copy sequence is far simpler as the actual sequence is stored in the JavaScript
345 object's resource data, so no read/modify/write cycle occurs (instead, the resource
346 data is modified directly).
347
348 Therefore, writes to elements of a reference sequence will be much slower than writes
349 to elements of a copy sequence.  In fact, writing to a single element of an N-element
350 reference sequence is equivalent in cost to assigning a N-element copy sequence to that
351 reference sequence, so you're usually better off modifying a temporary copy sequence
352 and then assigning the result to a reference sequence, during computation.
353
354 Assume the existence (and prior registration into the "Qt.example 1.0" namespace) of the
355 following C++ type:
356
357 \code
358 class SequenceTypeExample : public QQuickItem
359 {
360     Q_OBJECT
361     Q_PROPERTY (QList<qreal> qrealListProperty READ qrealListProperty WRITE setQrealListProperty NOTIFY qrealListPropertyChanged)
362
363 public:
364     SequenceTypeExample() : QQuickItem() { m_list << 1.1 << 2.2 << 3.3; }
365     ~SequenceTypeExample() {}
366
367     QList<qreal> qrealListProperty() const { return m_list; }
368     void setQrealListProperty(const QList<qreal> &list) { m_list = list; emit qrealListPropertyChanged(); }
369
370 signals:
371     void qrealListPropertyChanged();
372
373 private:
374     QList<qreal> m_list;
375 };
376 \endcode
377
378 The following example writes to elements of a reference sequence in a
379 tight loop, resulting in bad performance:
380
381 \qml
382 // bad.qml
383 import QtQuick 2.0
384 import Qt.example 1.0
385
386 SequenceTypeExample {
387     id: root
388     width: 200
389     height: 200
390
391     Component.onCompleted: {
392         var t0 = new Date();
393         qrealListProperty.length = 100;
394         for (var i = 0; i < 500; ++i) {
395             for (var j = 0; j < 100; ++j) {
396                 qrealListProperty[j] = j;
397             }
398         }
399         var t1 = new Date();
400         console.log("elapsed: " + (t1.valueOf() - t0.valueOf()) + " milliseconds");
401     }
402 }
403 \endqml
404
405 The QObject property read and write in the inner loop caused by the
406 \c{"qrealListProperty[j] = j"} expression makes this code very suboptimal.  Instead,
407 something functionally equivalent but much faster would be:
408
409 \qml
410 // good.qml
411 import QtQuick 2.0
412 import Qt.example 1.0
413
414 SequenceTypeExample {
415     id: root
416     width: 200
417     height: 200
418
419     Component.onCompleted: {
420         var t0 = new Date();
421         var someData = [1.1, 2.2, 3.3]
422         someData.length = 100;
423         for (var i = 0; i < 500; ++i) {
424             for (var j = 0; j < 100; ++j) {
425                 someData[j] = j;
426             }
427             qrealListProperty = someData;
428         }
429         var t1 = new Date();
430         console.log("elapsed: " + (t1.valueOf() - t0.valueOf()) + " milliseconds");
431     }
432 }
433 \endqml
434
435 Secondly, a change signal for the property is emitted if any element in it changes.
436 If you have many bindings to a particular element in a sequence property, it is better
437 to create a dynamic property which is bound to that element, and use that dynamic
438 property as the symbol in the binding expressions instead of the sequence element,
439 as it will only cause re-evaluation of bindings if its value changes.
440
441 This is an unusual use-case which most clients should never hit, but is worth being
442 aware of, in case you find yourself doing something like this:
443
444 \qml
445 // bad.qml
446 import QtQuick 2.0
447 import Qt.example 1.0
448
449 SequenceTypeExample {
450     id: root
451
452     property int firstBinding: qrealListProperty[1] + 10;
453     property int secondBinding: qrealListProperty[1] + 20;
454     property int thirdBinding: qrealListProperty[1] + 30;
455
456     Component.onCompleted: {
457         var t0 = new Date();
458         for (var i = 0; i < 1000; ++i) {
459             qrealListProperty[2] = i;
460         }
461         var t1 = new Date();
462         console.log("elapsed: " + (t1.valueOf() - t0.valueOf()) + " milliseconds");
463     }
464 }
465 \endqml
466
467 Note that even though only the element at index 2 is modified in the loop, the three
468 bindings will all be re-evaluated since the granularity of the change signal is that
469 the entire property has changed.  As such, adding an intermediate binding can
470 sometimes be beneficial:
471
472 \qml
473 // good.qml
474 import QtQuick 2.0
475 import Qt.example 1.0
476
477 SequenceTypeExample {
478     id: root
479
480     property int intermediateBinding: qrealListProperty[1]
481     property int firstBinding: intermediateBinding + 10;
482     property int secondBinding: intermediateBinding + 20;
483     property int thirdBinding: intermediateBinding + 30;
484
485     Component.onCompleted: {
486         var t0 = new Date();
487         for (var i = 0; i < 1000; ++i) {
488             qrealListProperty[2] = i;
489         }
490         var t1 = new Date();
491         console.log("elapsed: " + (t1.valueOf() - t0.valueOf()) + " milliseconds");
492     }
493 }
494 \endqml
495
496 In the above example, only the intermediate binding will be re-evaluated each time,
497 resulting in a significant performance increase.
498
499 \section2 Value-Type tips
500
501 Value-type properties (font, color, vector3d, etc) have similar QObject property
502 and change notification semantics to sequence type properties.  As such, the tips
503 given above for sequences are also applicable for value-type properties.  While
504 they are usually less of a problem with value-types (since the number of
505 sub-properties of a value-type is usually far less than the number of elements
506 in a sequence), any increase in the number of bindings being re-evaluated needlessly
507 will have a negative impact on performance.
508
509 \section2 Other JavaScript Objects
510
511 Different JavaScript engines provide different optimizations.  The JavaScript engine
512 which QtQuick 2 uses is optimized for object instantiation and property lookup, but
513 the optimizations which it provides relies on certain criteria.  If your application
514 does not meet the criteria, the JavaScript engine falls back to a "slow-path" mode
515 with much worse performance.  As such, always try to ensure you meet the following
516 criteria:
517
518 \list
519 \li Avoid using eval() if at all possible
520 \li Do not delete properties of objects
521 \endlist
522
523 \section1 Common Interface Elements
524
525 \section2 Text Elements
526
527 Calculating text layouts can be a slow operation.  Consider using the \c PlainText
528 format instead of \c StyledText wherever possible, as this reduces the amount of work
529 required of the layout engine.  If you cannot use \c PlainText (as you need to embed
530 images, or use tags to specify ranges of characters to have certain formatting (bold,
531 italic, etc) as opposed to the entire text) then you should use \c StyledText.
532
533 You should only use \c AutoText if the text might be (but probably isn't)
534 \c StyledText as this mode will incur a parsing cost.  The \c RichText mode should
535 not be used, as \c StyledText provides almost all of its features at a fraction of
536 its cost.
537
538 \section2 Images
539
540 Images are a vital part of any user interface.  Unfortunately, they are also a big
541 source of problems due to the time it takes to load them, the amount of memory they
542 consume, and the way in which they are used.
543
544 \section3 Asynchronous Loading
545
546 Images are often quite large, and so it is wise to ensure that loading an image doesn't
547 block the UI thread.  Set the "asynchronous" property of the QML Image element to
548 \c true to enable asynchronous loading of images from the local file system (remote
549 images are always loaded asynchronously) where this would not result in a negative impact
550 upon the aesthetics of the user interface.
551
552 Image elements with the "asynchronous" property set to \c true will load images in
553 a low-priority worker thread.
554
555 \section3 Explicit Source Size
556
557 If your application loads a large image but displays it in a small-sized element, set
558 the "sourceSize" property to the size of the element being rendered to ensure that the
559 smaller-scaled version of the image is kept in memory, rather than the large one.
560
561 Beware that changing the sourceSize will cause the image to be reloaded.
562
563 \section3 Avoid Run-time Composition
564
565 Also remember that you can avoid doing composition work at run-time by providing the
566 pre-composed image resource with your application (e.g., providing elements with shadow
567 effects).
568
569 \section2 Position Elements With Anchors
570
571 It is more efficient to use anchors rather than bindings to position items
572 relative to each other.  Consider this use of bindings to position rect2
573 relative to rect1:
574
575 \code
576 Rectangle {
577     id: rect1
578     x: 20
579     width: 200; height: 200
580 }
581 Rectangle {
582     id: rect2
583     x: rect1.x
584     y: rect1.y + rect1.height
585     width: rect1.width - 20
586     height: 200
587 }
588 \endcode
589
590 This is achieved more efficiently using anchors:
591
592 \code
593 Rectangle {
594     id: rect1
595     x: 20
596     width: 200; height: 200
597 }
598 Rectangle {
599     id: rect2
600     height: 200
601     anchors.left: rect1.left
602     anchors.top: rect1.bottom
603     anchors.right: rect1.right
604     anchors.rightMargin: 20
605 }
606 \endcode
607
608 Note that this is still not as efficient as specifying a static size, so you should still specify static sizes via
609 the x, y, width and height properties.
610
611 Item coordinates are always relative to their parent, so if you wanted to be a fixed offset from your parent's
612 0,0 coordinate you should not use anchors. For example the following items are in the same place, but the anchors
613 code is not as resource efficient as fixed positioning.
614
615 \code
616 Rectangle {
617     width: 60
618     height: 60
619     Rectangle {
620         x: 20
621         y: 20
622         width: 20
623         height: 20
624     }
625     Rectangle {
626         anchors.fill: parent
627         anchors.margins: 20
628     }
629 }
630 \endcode
631
632 \section1 Models and Views
633
634 Most applications will have at least one model feeding data to a view.  There are
635 some semantics which application developers need to be aware of, in order to achieve
636 maximal performance.
637
638 \section2 Custom C++ Models
639
640 It is often desirable to write your own custom model in C++ for use with a view in
641 QML.  While the optimal implementation of any such model will depend heavily on the
642 use-case it must fulfil, some general guidelines are as follows:
643
644 \list
645 \li Be as asynchronous as possible
646 \li Do all processing in a (low priority) worker thread
647 \li Batch up backend operations so that (potentially slow) I/O and IPC is minimized
648 \li Use a sliding slice window to cache results, whose parameters are determined with the help of profiling
649 \endlist
650
651 It is important to note that using a low-priority worker thread is recommended to
652 minimise the risk of starving the GUI thread (which could result in worse perceived
653 performance).  Also, remember that synchronization and locking mechanisms can be a
654 significant cause of slow performance, and so care should be taken to avoid
655 unnecessary locking.
656
657 \section2 ListModel
658
659 QML provides a ListModel element which can be used to feed data to a ListView.
660 It should suffice for most use-cases and be relatively performant so long as
661 it is used correctly.
662
663 \section3 Populate Within A Worker Thread
664
665 ListModel elements can be populated in a (low priority) worker thread in JavaScript.  The
666 developer must explicitly call "sync()" on the ListModel from within the WorkerScript to
667 have the changes synchronized to the main thread.  See the WorkerScript documentation
668 for more information.
669
670 Please note that using a WorkerScript element will result in a separate JavaScript engine
671 being created (as the JavaScript engine is per-thread).  This will result in increased
672 memory usage.  Multiple WorkerScript elements will all use the same worker thread, however,
673 so the memory impact of using a second or third WorkerScript element is negligible once
674 an application already uses one.
675
676 \section3 Don't Use Dynamic Roles
677
678 The ListModel element in QtQuick 2.0 is much more performant than in QtQuick 1.0.  The
679 performance improvements mainly come from assumptions about the type of roles within each
680 element in a given model - if the type doesn't change, the caching performance improves
681 dramatically.  If the type can change dynamically from element to element, this optimization
682 becomes impossible, and the performance of the model will be an order of magnitude worse.
683
684 Therefore, dynamic typing is disabled by default; the developer must specifically set
685 the boolean "dynamicRoles" property of the model to enable dynamic typing (and suffer
686 the attendant performance degradation).  We recommend that you do not use dynamic typing
687 if it is possible to redesign your application to avoid it.
688
689 \section2 Views
690
691 View delegates should be kept as simple as possible.  Have just enough QML in the delegate
692 to display the necessary information.  Any additional functionality which is not immediately
693 required (e.g., if it displays more information when clicked) should not be created until
694 needed (see the upcoming section on lazy initialization).
695
696 The following list is a good summary of things to keep in mind when designing a delegate:
697 \list
698 \li The fewer elements that are in a delegate, the faster they can be created, and thus
699    the faster the view can be scrolled.
700 \li Keep the number of bindings in a delegate to a minimum; in particular, use anchors
701    rather than bindings for relative positioning within a delegate.
702 \li Avoid using ShaderEffect elements within delegates.
703 \li Never enable clipping on a delegate.
704 \endlist
705
706 You may set the \c cacheBuffer property of a view to allow asynchronous creation and
707 buffering of delegates outside of the visible area.  Utilizing a \c cacheBuffer is
708 recommended for view delegates that are non-trivial and unlikely to be created within a
709 single frame.
710
711 Be mindful that a \c cacheBuffer keeps additional delegates in-memory and therefore the
712 value derived from utilizing the \c cacheBuffer must be balanced against additional memory
713 usage.  Developers should use benchmarking to find the best value for their use-case, since
714 the increased memory pressure caused by utilizing a \c cacheBuffer can, in some rare cases,
715 cause reduced frame rate when scrolling.
716
717 \section1 Visual Effects
718
719 QtQuick 2 includes several features which allow developers and designers to create
720 exceptionally appealing user interfaces.  Fluidity and dynamic transitions as well
721 as visual effects can be used to great effect in an application, but some care must
722 be taken when using some of the features in QML as they can have performance implications.
723
724 \section2 Animations
725
726 In general, animating a property will cause any bindings which reference that property
727 to be re-evaluated.  Usually, this is what is desired but in other cases it may be better
728 to disable the binding prior to performing the animation, and then reassign the binding
729 once the animation has completed.
730
731 Avoid running JavaScript during animation.  For example, running a complex JavaScript
732 expression for each frame of an x property animation should be avoided.
733
734 Developers should be especially careful using script animations, as these are run in the main
735 thread (and therefore can cause frames to be skipped if they take too long to complete).
736
737 \section2 Particles
738
739 The QtQuick 2.0 Particles module allows beautiful particle effects to be integrated
740 seamlessly into user interfaces.  However every platform has different graphics hardware
741 capabilities, and the Particles module is unable to limit parameters to what your hardware
742 can gracefully support.  The more particles you attempt to render (and the larger they are),
743 the faster your graphics hardware will need to be in order to render at 60 FPS.  Affecting
744 more particles requires a faster CPU.  It is therefore important to test all
745 particle effects on your target platform carefully, to calibrate the number and size of
746 particles you can render at 60 FPS.
747
748 It should be noted that a particle system can be disabled when not in use
749 (e.g., on a non-visible element) to avoid doing unnecessary simulation.
750
751 See the \l{Particle System Performance Guide} for more in-depth information.
752
753 \section2 Shaders
754
755 Shaders written in GLSL allow for complex transformations and visual effects to be written,
756 however they should be used with care.  Using a ShaderEffectSource causes a scene to
757 prerendered into an FBO before it can be drawn.  This extra overhead is quite expensive.
758
759 A ShaderEffect element can imply a ShaderEffectSource (and the indirect rendering costs
760 associated with that) and also involves uploading a vertex and fragment shader program
761 (which is then compiled into a GLSL shader).  Each fragment shader runs once for every
762 pixel of the scene, and so these should be kept as simple as possible.
763
764 \section1 Controlling Element Lifetime
765
766 By partitioning an application into simple, modular components, each contained in a single
767 QML file, you can achieve faster application startup time and better control over memory
768 usage, and reduce the number of active-but-invisible elements in your application.
769
770 \section2 Lazy Initialization
771
772 The QML engine does some tricky things to try to ensure that loading and initialization of
773 components doesn't cause frames to be skipped, however there is no better way to reduce
774 startup time than to avoid doing work you don't need to do, and delaying the work until
775 it is necessary.  This may be achieved by using either \l Loader or creating components
776 \l {qtqml-javascript-dynamicobjects.html}{dynamically}.
777
778 \section3 Using Loader
779
780 The Loader is an element which allows dynamic loading and unloading of components.
781
782 \list
783 \li Using the "active" property of a Loader, initialization can be delayed until required.
784 \li Using the overloaded version of the "setSource()" function, initial property values can
785    be supplied.
786 \li Setting the Loader \l {Loader::asynchronous}{asynchronous} property to true may also
787    improve fluidity while a component is instantiated.
788 \endlist
789
790 \section3 Using Dynamic Creation
791
792 Developers can use the Qt.createComponent() function to create a component dynamically at
793 runtime from within JavaScript, and then call createObject() to instantiate it.  Depending
794 on the ownership semantics specified in the call, the developer may have to delete the
795 created object manually.  See \l{qtqml-javascript-dynamicobjects.html}
796 {Dynamic Object Management in QML} for more information.
797
798 \section2 Destroy Unused Elements
799
800 Elements which are invisible because they are a child of a non-visible element (e.g., the
801 second tab in a tab-widget, while the first tab is shown) should be initialized lazily in
802 most cases, and deleted when no longer in use, to avoid the ongoing cost of leaving them
803 active (e.g., rendering, animations, property binding evaluation, etc).
804
805 An item loaded with a Loader element may be released by resetting the "source" or
806 "sourceComponent" property of the Loader, while other items may be explicitly
807 released by calling destroy() on them.  In some cases, it may be necessary to
808 leave the item active, in which case it should be made invisible at the very least.
809
810 See the upcoming section on Rendering for more information on active but invisible elements.
811
812 \section1 Rendering
813
814 The scene graph used for rendering in QtQuick 2.0 allows highly dynamic, animated user
815 interfaces to be rendered fluidly at 60 FPS.  There are some things which can
816 dramatically decrease rendering performance, however, and developers should be careful
817 to avoid these pitfalls wherever possible.
818
819 \section2 Clipping
820
821 Clipping is disabled by default, and should only be enabled when required.
822
823 Clipping is a visual effect, NOT an optimization.  It increases (rather than reduces)
824 complexity for the renderer.  If clipping is enabled, an item will clip its own painting,
825 as well as the painting of its children, to its bounding rectangle.  This stops the renderer
826 from being able to reorder the drawing order of elements freely, resulting in a sub-optimal
827 best-case scene graph traversal.
828
829 Clipping inside a delegate is especially bad and should be avoided at all costs.
830
831 \section2 Over-drawing and Invisible Elements
832
833 If you have elements which are totally covered by other (opaque) elements, it is best to
834 set their "visible" property to \c false or they will be needlessly drawn.
835
836 Similarly, elements which are invisible (e.g., the second tab in a tab widget, while the
837 first tab is shown) but need to be initialized at startup time (e.g., if the cost of
838 instantiating the second tab takes too long to be able to do it only when the tab is
839 activated), should have their "visible" property set to \c false, in order to avoid the
840 cost of drawing them (although as previously explained, they will still incur the cost of
841 any animations or bindings evaluation since they are still active).
842
843 \section2 Manual Layouts
844
845 The scene graph renderer is able to batch up certain operations to minimise the number of
846 OpenGL state changes required.  However, this optimization is only possible for the
847 built-in layout elements provided by QtQuick 2.0, and cannot be applied to manual layouts.
848
849 Therefore, application developers should use the Row, Column, Grid, GridView and ListView
850 elements instead of manual layouts wherever possible.
851
852 \section1 Memory Allocation And Collection
853
854 The amount of memory which will be allocated by an application and the way in which that
855 memory will be allocated are very important considerations.  Aside from the obvious
856 concerns about out-of-memory conditions on memory-constrained devices, allocating memory
857 on the heap is a fairly computationally expensive operation, and certain allocation
858 strategies can result in increased fragmentation of data across pages.  JavaScript uses
859 a managed memory heap which is automatically garbage collected, and this provides some
860 advantages but also has some important implications.
861
862 An application written in QML uses memory from both the C++ heap and an automatically
863 managed JavaScript heap.  The application developer needs to be aware of the subtleties
864 of each in order to maximise performance.
865
866 \section2 Tips For QML Application Developers
867
868 The tips and suggestions contained in this section are guidelines only, and may not be
869 applicable in all circumstances.  Be sure to benchmark and analyse your application
870 carefully using empirical metrics, in order to make the best decisions possible.
871
872 \section3 Instantiate and initialize components lazily
873
874 If your application consists of multiple views (for example, multiple tabs) but only
875 one is required at any one time, you can use lazy instantiation to minimize the
876 amount of memory you need to have allocated at any given time.  See the prior section
877 on \l{Lazy Initialization} for more information.
878
879 \section3 Destroy unused objects
880
881 If you lazily instantiate components, or dynamically create objects during a JavaScript
882 expression, it is often better to manually \c{destroy()} them rather than waiting for
883 automatic garbage collection to do so.  See the prior section on
884 \l{Controlling Element Lifetime} for more information.
885
886 \section3 Don't manually invoke the garbage collector
887
888 In most cases, it is not wise to manually invoke the garbage collector, as it will block
889 the GUI thread for a substantial period of time.  This can result in skipped frames and
890 jerky animations, which should be avoided at all costs.
891
892 There are some cases where manually invoking the garbage collector is acceptable (and
893 this is explained in greater detail in an upcoming section), but in most cases, invoking
894 the garbage collector is unnecessary and counter-productive.
895
896 \section3 Avoid complex bindings
897
898 Aside from the reduced performance of complex bindings (for example, due to having to
899 enter the JavaScript execution context to perform evaluation), they also take up more
900 memory both on the C++ heap and the JavaScript heap than bindings which can be
901 evaluated by QML's optimized binding expression evaluator.
902
903 \section3 Avoid defining multiple identical implicit types
904
905 If a QML element has a custom property defined in QML, it becomes its own implicit type.
906 This is explained in greater detail in an upcoming section.  If multiple identical
907 implicit types are defined inline in a component, some memory will be wasted.  In that
908 situation it is usually better to explicitly define a new component which can then be
909 reused.
910
911 Defining a custom property can often be a beneficial performance optimization (for
912 example, to reduce the number of bindings which are required or re-evaluated), or it
913 can improve the modularity and maintainability of a component.  In those cases, using
914 custom properties is encouraged; however, the new type should, if it is used more than
915 once, be split into its own component (.qml file) in order to conserve memory.
916
917 \section3 Re-use existing components
918
919 If you are considering defining a new component, it's worth double checking that such a
920 component doesn't already exist in the component set for your platform.  Otherwise, you
921 will be forcing the QML engine to generate and store type-data for a type which is
922 essentially a duplicate of another pre-existing and potentially already loaded component.
923
924 \section3 Use module APIs instead of pragma library scripts
925
926 If you are using a pragma library script to store application-wide instance data,
927 consider using a QObject module API instead.  This should result in better performance,
928 and will result in less JavaScript heap memory being used.
929
930 \section2 Memory Allocation in a QML Application
931
932 The memory usage of a QML application may be split into two parts: its C++ heap usage,
933 and its JavaScript heap usage.  Some of the memory allocated in each will be unavoidable,
934 as it is allocated by the QML engine or the JavaScript engine, while the rest is
935 dependent upon decisions made by the application developer.
936
937 The C++ heap will contain:
938 \list
939   \li the fixed and unavoidable overhead of the QML engine (implementation data
940   structures, context information, and so on)
941   \li per-component compiled data and type information, including per-type property
942   metadata, which is generated by the QML engine depending on which modules are
943   imported by the application and which components the application loads
944   \li per-object C++ data (including property values) plus a per-element metaobject
945   hierarchy, depending on which components the application instantiates
946   \li any data which is allocated specifically by QML imports (libraries)
947 \endlist
948
949 The JavaScript heap will contain:
950 \list
951   \li the fixed and unavoidable overhead of the JavaScript engine itself (including
952   built-in JavaScript types)
953   \li the fixed and unavoidable overhead of our JavaScript integration (constructor
954   functions for loaded types, function templates, and so on)
955   \li per-type layout information and other internal type-data generated by the JavaScript
956   engine at runtime, for each type (see note below, regarding types)
957   \li per-object JavaScript data ("var" properties, JavaScript functions and signal
958   handlers, and non-optimized binding expressions)
959   \li variables allocated during expression evaluation
960 \endlist
961
962 Furthermore, there will be one JavaScript heap allocated for use in the main thread, and
963 optionally one other JavaScript heap allocated for use in the WorkerScript thread.  If an
964 application does not use a WorkerScript element, that overhead will not be incurred.  The
965 JavaScript heap can be several megabytes in size, and so applications written for
966 memory-constrained devices may be best served to avoid using the WorkerScript element
967 despite its usefulness in populating list models asynchronously.
968
969 Note that both the QML engine and the JavaScript engine will automatically generate their
970 own caches of type-data about observed types.  Every component loaded by an application
971 is a distinct (explicit) type, and every element (component instance) which defines its
972 own custom properties in QML is an implicit type.  Any element (instance of a component)
973 which does not define any custom properties is considered by the JavaScript and QML engines
974 to be of the type explicitly defined by the component, rather than its own implicit type.
975
976 Consider the following example:
977 \qml
978 import QtQuick 2.0
979
980 Item {
981     id: root
982
983     Rectangle {
984         id: r0
985         color: "red"
986     }
987
988     Rectangle {
989         id: r1
990         color: "blue"
991         width: 50
992     }
993
994     Rectangle {
995         id: r2
996         property int customProperty: 5
997     }
998
999     Rectangle {
1000         id: r3
1001         property string customProperty: "hello"
1002     }
1003
1004     Rectangle {
1005         id: r4
1006         property string customProperty: "hello"
1007     }
1008 }
1009 \endqml
1010
1011 In the previous example, the rectangles \c r0 and \c r1 do not have any custom properties,
1012 and thus the JavaScript and QML engines consider them both to be of the same type.  That
1013 is, \c r0 and \c r1 are both considered to be of the explicitly defined \c Rectangle type.
1014 The rectangles \c r2, \c r3 and \c r4 each have custom properties and are each considered
1015 to be different (implicit) types.  Note that \c r3 and \c r4 are each considered to be of
1016 different types, even though they have identical property information, simply because the
1017 custom property was not declared in the component which they are instances of.
1018
1019 If \c r3 and \c r4 were both instances of a \c RectangleWithString component, and that
1020 component definition included the declaration of a string property named \c customProperty,
1021 then \c r3 and \c r4 would be considered to be the same type (that is, they would be
1022 instances of the \c RectangleWithString type, rather than defining their own implicit type).
1023
1024 \section2 In-Depth Memory Allocation Considerations
1025
1026 Whenever making decisions regarding memory allocation or performance trade-offs, it is
1027 important to keep in mind the impact of CPU-cache performance, operating system paging,
1028 and JavaScript engine garbage collection.  Potential solutions should be benchmarked
1029 carefully in order to ensure that the best one is selected.
1030
1031 No set of general guidelines can replace a solid understanding of the underlying
1032 principles of computer science combined with a practical knowledge of the implementation
1033 details of the platform for which the application developer is developing.  Furthermore,
1034 no amount of theoretical calculation can replace a good set of benchmarks and analysis
1035 tools when making trade-off decisions.
1036
1037 \section3 Fragmentation
1038
1039 Fragmentation is a C++ development issue.  If the application developer is not defining
1040 any C++ types or plugins, they may safely ignore this section.
1041
1042 Over time, an application will allocate large portions of memory, write data to that
1043 memory, and subsequently free some portions of that memory once it has finished using
1044 some of the data.  This can result in "free" memory being located in non-contiguous
1045 chunks, which cannot be returned to the operating system for other applications to use.
1046 It also has an impact on the caching and access characteristics of the application, as
1047 the "living" data may be spread across many different pages of physical memory.  This
1048 in turn could force the operating system to swap which can cause filesystem I/O - which
1049 is, comparatively speaking, an extremely slow operation.
1050
1051 Fragmentation can be avoided by utilizing pool allocators (and other contiguous memory
1052 allocators), by reducing the amount of memory which is allocated at any one time by
1053 carefully managing object lifetimes, by periodically cleansing and rebuilding caches,
1054 or by utilizing a memory-managed runtime with garbage collection (such as JavaScript).
1055
1056 \section3 Garbage Collection
1057
1058 JavaScript provides garbage collection.  Memory which is allocated on the JavaScript
1059 heap (as opposed to the C++ heap) is owned by the JavaScript engine.  The engine will
1060 periodically collect all unreferenced data on the JavaScript heap, and if fragmentation
1061 becomes an issue, it will compact its heap by moving all "living" data into a contiguous
1062 region of memory (allowing the freed memory to be returned to the operating system).
1063
1064 \section4 Implications of Garbage Collection
1065
1066 Garbage collection has advantages and disadvantages.  It ensures that fragmentation is
1067 less of an issue, and it means that manually managing object lifetime is less important.
1068 However, it also means that a potentially long-lasting operation may be initiated by the
1069 JavaScript engine at a time which is out of the application developer's control.  Unless
1070 JavaScript heap usage is considered carefully by the application developer, the frequency
1071 and duration of garbage collection may have a negative impact upon the application
1072 experience.
1073
1074 \section4 Manually Invoking the Garbage Collector
1075
1076 An application written in QML will (most likely) require garbage collection to be
1077 performed at some stage.  While garbage collection will be automatically triggered by
1078 the JavaScript engine when the amount of available free memory is low, it is occasionally
1079 better if the application developer makes decisions about when to invoke the garbage
1080 collector manually (although usually this is not the case).
1081
1082 The application developer is likely to have the best understanding of when an application
1083 is going to be idle for substantial periods of time.  If a QML application uses a lot
1084 of JavaScript heap memory, causing regular and disruptive garbage collection cycles
1085 during particularly performance-sensitive tasks (for example, list scrolling, animations,
1086 and so forth), the application developer may be well served to manually invoke the
1087 garbage collector during periods of zero activity.  Idle periods are ideal for performing
1088 garbage collection since the user will not notice any degradation of user experience
1089 (skipped frames, jerky animations, and so on) which would result from invoking the garbage
1090 collector while activity is occurring.
1091
1092 The garbage collector may be invoked manually by calling \c{gc()} within JavaScript.
1093 This will cause a comprehensive collection and compaction cycle to be performed, which
1094 may take from between a few hundred to more than a thousand milliseconds to complete, and
1095 so should be avoided if at all possible.
1096
1097 \section3 Memory vs Performance Trade-offs
1098
1099 In some situations, it is possible to trade-off increased memory usage for decreased
1100 processing time.  For example, caching the result of a symbol lookup used in a tight loop
1101 to a temporary variable in a JavaScript expression will result in a significant performance
1102 improvement when evaluating that expression, but it involves allocating a temporary variable.
1103 In some cases, these trade-offs are sensible (such as the case above, which is almost always
1104 sensible), but in other cases it may be better to allow processing to take slightly longer
1105 in order to avoid increasing the memory pressure on the system.
1106
1107 In some cases, the impact of increased memory pressure can be extreme.  In some situations,
1108 trading off memory usage for an assumed performance gain can result in increased page-thrash
1109 or cache-thrash, causing a huge reduction in performance. It is always necessary to benchmark
1110 the impact of trade-offs carefully in order to determine which solution is best in a given
1111 situation.
1112
1113 For in-depth information on cache performance and memory-time trade-offs, please see
1114 Ulrich Drepper's excellent article "What Every Programmer Should Know About Memory"
1115 (available at http://ftp.linux.org.ua/pub/docs/developer/general/cpumemory.pdf as at 18th
1116 April 2012), and for information on C++-specific optimizations, please see Agner Fog's
1117 excellent manuals on optimizing C++ applications (available at
1118 http://www.agner.org/optimize/ as at 18th April 2012).
1119
1120 */