443In the above example, only the intermediate binding will be re-evaluated each time,
444resulting in a significant performance increase.
445
446\section2 Value-Type tips
447
448Value-type properties (font, color, vector3d, etc) have similar QObject property
449and change notification semantics to sequence type properties. As such, the tips
450given above for sequences are also applicable for value-type properties. While
451they are usually less of a problem with value-types (since the number of
452sub-properties of a value-type is usually far less than the number of elements
453in a sequence), any increase in the number of bindings being re-evaluated needlessly
454will have a negative impact on performance.
455
456\section2 General Performance Tips
457
458General JavaScript performance considerations resulting from the language design are applicable also to QML. Most prominently:
459
460\list
461\li Avoid using eval() if at all possible
462\li Do not delete properties of objects
463\endlist
464
465\section1 Common Interface Elements
466
467\section2 Text Elements
468
469Calculating text layouts can be a slow operation. Consider using the \c PlainText
470format instead of \c StyledText wherever possible, as this reduces the amount of work
471required of the layout engine. If you cannot use \c PlainText (as you need to embed
472images, or use tags to specify ranges of characters to have certain formatting (bold,
473italic, etc) as opposed to the entire text) then you should use \c StyledText.
474
475You should only use \c AutoText if the text might be (but probably isn't)
476\c StyledText as this mode will incur a parsing cost. The \c RichText mode should
477not be used, as \c StyledText provides almost all of its features at a fraction of
478its cost.
479
480\section2 Images
481
482Images are a vital part of any user interface. Unfortunately, they are also a big
483source of problems due to the time it takes to load them, the amount of memory they
484consume, and the way in which they are used.
485
486\section3 Asynchronous Loading
487
488Images are often quite large, and so it is wise to ensure that loading an image doesn't
489block the UI thread. Set the "asynchronous" property of the QML Image element to
490\c true to enable asynchronous loading of images from the local file system (remote
491images are always loaded asynchronously) where this would not result in a negative impact
492upon the aesthetics of the user interface.
493
494Image elements with the "asynchronous" property set to \c true will load images in
495a low-priority worker thread.
496
497\section3 Explicit Source Size
498
499If your application loads a large image but displays it in a small-sized element, set
500the "sourceSize" property to the size of the element being rendered to ensure that the
501smaller-scaled version of the image is kept in memory, rather than the large one.
502
503Beware that changing the sourceSize will cause the image to be reloaded.
504
505\section3 Avoid Run-time Composition
506
507Also remember that you can avoid doing composition work at run-time by providing the
508pre-composed image resource with your application (for example, providing elements with shadow
509effects).
510
511\section3 Avoid Smoothing Images
512
513Enable \c{image.smooth} only if required. It is slower on some hardware, and it has no visual
514effect if the image is displayed in its natural size.
515
516\section3 Painting
517
518Avoid painting the same area several times. Use Item as root element rather than Rectangle
519to avoid painting the background several times.
520
521\section2 Position Elements With Anchors
522
523It is more efficient to use anchors rather than bindings to position items
524relative to each other. Consider this use of bindings to position rect2
525relative to rect1:
526
527\code
528Rectangle {
529 id: rect1
530 x: 20
531 width: 200; height: 200
532}
533Rectangle {
534 id: rect2
535 x: rect1.x
536 y: rect1.y + rect1.height
537 width: rect1.width - 20
538 height: 200
539}
540\endcode
541
542This is achieved more efficiently using anchors:
543
544\code
545Rectangle {
546 id: rect1
547 x: 20
548 width: 200; height: 200
549}
550Rectangle {
551 id: rect2
552 height: 200
553 anchors.left: rect1.left
554 anchors.top: rect1.bottom
555 anchors.right: rect1.right
556 anchors.rightMargin: 20
557}
558\endcode
559
560Positioning with bindings (by assigning binding expressions to the x, y, width
561and height properties of visual objects, rather than using anchors) is
562relatively slow, although it allows maximum flexibility.
563
564If the layout is not dynamic, the most performant way to specify the layout is
565via static initialization of the x, y, width and height properties. Item
566coordinates are always relative to their parent, so if you wanted to be a fixed
567offset from your parent's 0,0 coordinate you should not use anchors. In the
568following example the child Rectangle objects are in the same place, but the
569anchors code shown is not as resource efficient as the code which
570uses fixed positioning via static initialization:
571
572\code
573Rectangle {
574 width: 60
575 height: 60
576 Rectangle {
577 id: fixedPositioning
578 x: 20
579 y: 20
580 width: 20
581 height: 20
582 }
583 Rectangle {
584 id: anchorPositioning
585 anchors.fill: parent
586 anchors.margins: 20
587 }
588}
589\endcode
590
591\section1 Models and Views
592
593Most applications will have at least one model feeding data to a view. There are
594some semantics which application developers need to be aware of, in order to achieve
595maximal performance.
596
597\section2 Custom C++ Models
598
599It is often desirable to write your own custom model in C++ for use with a view in
600QML. While the optimal implementation of any such model will depend heavily on the
601use-case it must fulfil, some general guidelines are as follows:
602
603\list
604\li Be as asynchronous as possible
605\li Do all processing in a (low priority) worker thread
606\li Batch up backend operations so that (potentially slow) I/O and IPC is minimized
607\endlist
608
609It is important to note that using a low-priority worker thread is recommended to
610minimize the risk of starving the GUI thread (which could result in worse perceived
611performance). Also, remember that synchronization and locking mechanisms can be a
612significant cause of slow performance, and so care should be taken to avoid
613unnecessary locking.
614
615\section2 ListModel QML Type
616
617QML provides a ListModel type which can be used to feed data to a ListView.
618It should suffice for most use-cases and be relatively performant so long as
619it is used correctly.
620
621\section3 Populate Within A Worker Thread
622
623ListModel elements can be populated in a (low priority) worker thread in JavaScript. The
624developer must explicitly call "sync()" on the ListModel from within the WorkerScript to
625have the changes synchronized to the main thread. See the WorkerScript documentation
626for more information.
627
628Please note that using a WorkerScript element will result in a separate JavaScript engine
629being created (as the JavaScript engine is per-thread). This will result in increased
630memory usage. Multiple WorkerScript elements will all use the same worker thread, however,
631so the memory impact of using a second or third WorkerScript element is negligible once
632an application already uses one.
633
634\section3 Don't Use Dynamic Roles
635
636The ListModel element in QtQuick 2 is much more performant than in QtQuick 1. The
637performance improvements mainly come from assumptions about the type of roles within each
638element in a given model - if the type doesn't change, the caching performance improves
639dramatically. If the type can change dynamically from element to element, this optimization
640becomes impossible, and the performance of the model will be an order of magnitude worse.
641
642Therefore, dynamic typing is disabled by default; the developer must specifically set
643the boolean "dynamicRoles" property of the model to enable dynamic typing (and suffer
644the attendant performance degradation). We recommend that you do not use dynamic typing
645if it is possible to redesign your application to avoid it.
646
647\section2 Views
648
649View delegates should be kept as simple as possible. Have just enough QML in the delegate
650to display the necessary information. Any additional functionality which is not immediately
651required (for example, if it displays more information when clicked) should not be created until
652needed (see the upcoming section on lazy initialization).
653
654The following list is a good summary of things to keep in mind when designing a delegate:
655\list
656\li The fewer elements that are in a delegate, the faster they can be created, and thus
657 the faster the view can be scrolled.
658\li Keep the number of bindings in a delegate to a minimum; in particular, use anchors
659 rather than bindings for relative positioning within a delegate.
660\li Avoid using ShaderEffect elements within delegates.
661\li Never enable clipping on a delegate.
662\endlist
663
664You may set the \c cacheBuffer property of a view to allow asynchronous creation and
665buffering of delegates outside of the visible area. Utilizing a \c cacheBuffer is
666recommended for view delegates that are non-trivial and unlikely to be created within a
667single frame.
668
669Bear in mind that a \c cacheBuffer keeps additional delegates in-memory. Therefore, the value derived from utilizing the \c cacheBuffer must be balanced against additional memory
670usage. Developers should use benchmarking to find the best value for their use-case, since
671the increased memory pressure caused by utilizing a \c cacheBuffer can, in some rare cases,
672cause reduced frame rate when scrolling.
673
674\section1 Visual Effects
675
676\l {Qt Quick}{Qt Quick 2} includes several features which allow developers and designers to create
677exceptionally appealing user interfaces. Fluidity and dynamic transitions as well
678as visual effects can be used to great effect in an application, but some care must
679be taken when using some of the features in QML as they can have performance implications.
680
681\section2 Animations
682
683In general, animating a property will cause any bindings which reference that property
684to be re-evaluated. Usually, this is what is desired but in other cases it may be better
685to disable the binding prior to performing the animation, and then reassign the binding
686once the animation has completed.
687
688Avoid running JavaScript during animation. For example, running a complex JavaScript
689expression for each frame of an x property animation should be avoided.
690
691Developers should be especially careful using script animations, as these are run in the main
692thread (and therefore can cause frames to be skipped if they take too long to complete).
693
694\section2 Particles
695
696The \l {QtQuick.Particles}{Qt Quick Particles} module allows beautiful particle effects to be integrated
697seamlessly into user interfaces. However, every platform has different graphics hardware
698capabilities, and the Particles module is unable to limit parameters to what your hardware
699can gracefully support. The more particles you attempt to render (and the larger they are),
700the faster your graphics hardware will need to be in order to render at 60 FPS. Affecting
701more particles requires a faster CPU. It is therefore important to test all
702particle effects on your target platform carefully, to calibrate the number and size of
703particles you can render at 60 FPS.
704
705It should be noted that a particle system can be disabled when not in use
706(for example, on a non-visible element) to avoid doing unnecessary simulation.
707
708See the \l{Particle System Performance Guide} for more in-depth information.
709
710\section1 Controlling Element Lifetime
711
712By partitioning an application into simple, modular components, each contained in a single
713QML file, you can achieve faster application startup time and better control over memory
714usage, and reduce the number of active-but-invisible elements in your application.
715
716\section2 Lazy Initialization
717
718The QML engine does some tricky things to try to ensure that loading and initialization of
719components doesn't cause frames to be skipped. However, there is no better way to reduce
720startup time than to avoid doing work you don't need to do, and delaying the work until
721it is necessary. This may be achieved by using either \l Loader or creating components
722\l {Dynamic QML Object Creation from JavaScript}{dynamically}.
723
724\section3 Using Loader
725
726The Loader is an element which allows dynamic loading and unloading of components.
727
728\list
729\li Using the "active" property of a Loader, initialization can be delayed until required.
730\li Using the overloaded version of the "setSource()" function, initial property values can
731 be supplied.
732\li Setting the Loader \l {Loader::asynchronous}{asynchronous} property to true may also
733 improve fluidity while a component is instantiated.
734\endlist
735
736\section3 Using Dynamic Creation
737
738Developers can use the Qt.createComponent() function to create a component dynamically at
739runtime from within JavaScript, and then call createObject() to instantiate it. Depending
740on the ownership semantics specified in the call, the developer may have to delete the
741created object manually. See \l{Dynamic QML Object Creation from JavaScript} for more
742information.
743
744\section2 Destroy Unused Elements
745
746Elements which are invisible because they are a child of a non-visible element (for example, the
747second tab in a tab-widget, while the first tab is shown) should be initialized lazily in
748most cases, and deleted when no longer in use, to avoid the ongoing cost of leaving them
749active (for example, rendering, animations, property binding evaluation, etc).
750
751An item loaded with a Loader element may be released by resetting the "source" or
752"sourceComponent" property of the Loader, while other items may be explicitly
753released by calling destroy() on them. In some cases, it may be necessary to
754leave the item active, in which case it should be made invisible at the very least.
755
756See the upcoming section on Rendering for more information on active but invisible elements.
757
758\section1 Rendering
759
760The scene graph used for rendering in QtQuick 2 allows highly dynamic, animated user
761interfaces to be rendered fluidly at 60 FPS. There are some things which can
762dramatically decrease rendering performance, however, and developers should be careful
763to avoid these pitfalls wherever possible.
764
765\target clipping-performance
766\section2 Clipping
767
768Clipping is disabled by default, and should only be enabled when required.
769
770Clipping is a visual effect, NOT an optimization. It increases (rather than reduces)
771complexity for the renderer. If clipping is enabled, an item will clip its own painting,
772as well as the painting of its children, to its bounding rectangle. This stops the renderer
773from being able to reorder the drawing order of elements freely, resulting in a sub-optimal
774best-case scene graph traversal.
775
776Clipping inside a delegate is especially bad and should be avoided at all costs.
777
778\section2 Over-drawing and Invisible Elements
779
780If you have elements which are totally covered by other (opaque) elements, it is best to
781set their "visible" property to \c false or they will be drawn needlessly.
782
783Similarly, elements which are invisible (for example, the second tab in a tab widget, while the
784first tab is shown) but need to be initialized at startup time (for example, if the cost of
785instantiating the second tab takes too long to be able to do it only when the tab is
786activated), should have their "visible" property set to \c false, in order to avoid the
787cost of drawing them (although as previously explained, they will still incur the cost of
788any animations or bindings evaluation since they are still active).
789
790\section2 Translucent vs Opaque
791
792Opaque content is generally a lot faster to draw than translucent. The reason being
793that translucent content needs blending and that the renderer can potentially optimize
794opaque content better.
795
796An image with one translucent pixel is treated as fully translucent, even though it
797is mostly opaque. The same is true for an \l BorderImage with transparent edges.
798
799\section2 Shaders
800
801The \l ShaderEffect type makes it possible to place GLSL code inline in a Qt Quick application with
802very little overhead. However, it is important to realize that the fragment program needs to run
803for every pixel in the rendered shape. When deploying to low-end hardware and the shader
804is covering a large amount of pixels, one should keep the fragment shader to a few instructions
805to avoid poor performance.
806
807Shaders written in GLSL allow for complex transformations and visual effects to be written,
808however they should be used with care. Using a \l ShaderEffectSource causes a scene to be
809prerendered into an FBO before it can be drawn. This extra overhead can be quite expensive.
810
811\section1 Memory Allocation And Collection
812
813The amount of memory which will be allocated by an application and the way in which that
814memory will be allocated are very important considerations. Aside from the obvious
815concerns about out-of-memory conditions on memory-constrained devices, allocating memory
816on the heap is a fairly computationally expensive operation, and certain allocation
817strategies can result in increased fragmentation of data across pages. JavaScript uses
818a managed memory heap which is automatically garbage collected, and this has some
819advantages, but also some important implications.
820
821An application written in QML uses memory from both the C++ heap and an automatically
822managed JavaScript heap. The application developer needs to be aware of the subtleties
823of each in order to maximise performance.
824
825\section2 Tips For QML Application Developers
826
827The tips and suggestions contained in this section are guidelines only, and may not be
828applicable in all circumstances. Be sure to benchmark and analyze your application
829carefully using empirical metrics, in order to make the best decisions possible.
830
831\section3 Instantiate and initialize components lazily
832
833If your application consists of multiple views (for example, multiple tabs) but only
834one is required at any one time, you can use lazy instantiation to minimize the
835amount of memory you need to have allocated at any given time. See the prior section
836on \l{Lazy Initialization} for more information.
837
838\section3 Destroy unused objects
839
840If you lazy load components, or create objects dynamically during a JavaScript
841expression, it is often better to \c{destroy()} them manually rather than wait for
842automatic garbage collection to do so. See the prior section on
843\l{Controlling Element Lifetime} for more information.
844
845\section3 Don't manually invoke the garbage collector
846
847In most cases, it is not wise to manually invoke the garbage collector, as it will block
848the GUI thread for a substantial period of time. This can result in skipped frames and
849jerky animations, which should be avoided at all costs.
850
851There are some cases where manually invoking the garbage collector is acceptable (and
852this is explained in greater detail in an upcoming section), but in most cases, invoking
853the garbage collector is unnecessary and counter-productive.