Performance Tips in Qml Development (Translation)

Performance Tips in Qml Development (Translation)

1. About image performance Tips

1.1 Bitmap format comparison vector format

  Qt supports any standard image format, including bitmap formats such as PNG and JPEG, and vector graphics formats such as SVG. Compared with bitmap images, rendering SVG images is slow.

1.2 Loading large images asynchronously

  If the images are loaded synchronously, the UI interface will be blocked. In many cases, images do not need to be immediately visible, so they can be lazily loaded.

  • If you don't need to display the image immediately, you should load the image asynchronously in a separate thread. This can be done by setting the QML Image asynchronous (asynchronous) to true. In this way, the user interface can remain responsive.
  • Please note that this attribute is only valid for images read from the local file system. Images loaded via network resources (such as HTTP) are always loaded asynchronously.

1.3 Avoid adjustment and scaling

  • Resizing/scaling is a very heavy operation in QML. Use the original size image instead of resizing/zooming the image.

1.4 Large images use sourceSize attribute

  Images are usually the largest memory used in QML user interfaces.

  • sourceSize should be used with large images because the image loaded with the property set to store the actual number of pixels.
  • If you have a very large image 3264 2448, but you set the sourceSize to 204 153, then it will be reduced and stored as 204*153 memory.
  • If the actual size of the image is greater than sourceSize , the image is reduced. In this way, large images will not occupy more memory than necessary;
  • This is especially important for content loaded from external sources or provided by users.
  • Please note that dynamically changing this property will cause the image source to be reloaded, possibly even from the network, if it is not in the memory cache.
  • Images are cached and shared internally, so if multiple image elements use the same source, only one memory of the image is loaded.

1.5 Enable the smooth property of Image only when necessary

  Enabling the smooth attribute is bad for performance. Use natural-sized images or disable smoothing in animations.

  • The smooth attribute of Image can smoothly process the image when zooming or converting.
  • Smoothing provides better visual quality but is slower .
  • If the image is displayed in its natural size, the smooth of Image has no visual effect or performance impact.
  • If you really need to enable the smooth property of Image, please disable smoothing at the beginning of the animation and re-enable it at the end of the animation (scaling artifacts are only visible when the image is still on the screen).

1.6 Avoid images composed of multiple elements

  An image composed of a single image is more efficient than an image composed of multiple elements.

  • For example, a rectangle placed on an image that provides a shadow can be used to create an image with a shadow.
  • It is more efficient to provide images that include frames and shadows.

2. About list performance Tips

2.1 Make sure your data model is as fast as possible

  In many cases, the slow model is actually the bottleneck of list scrolling performance . Make sure that the data model is as fast as possible.

  • When the view is flicked (drag), an agent must be created quickly;
  • For example, any other functions that are only needed when you click delegate should be created by Loader when needed ;
  • Keep the quantity of QML to a minimum in the commission. The fewer elements in the delegate, the faster the scrolling speed of the view ;
  • In the list commission, only QML is used for the user interface, and C++ is used to implement the rest (for example: data generation, data processing). Don't use JavaScript.

2.2 Use CacheBuffer in ListView/GridView

  In some cases, cacheBuffer is useful in improving the performance of ListView/GridView. The default cacheBuffer is zero.

  • The cacheBuffer property determines whether the delegate is instantiated outside the visible area of ​​the view .
  • Please note that cacheBuffer is defined in pixels. For example, if the delegate is 20 pixels high, the cacheBuffer is set to 40 (maximum 2 delegate instances), and the 2 delegate instances below the visible area can be kept in memory.
  • Setting this value can improve the smoothness of scrolling behavior , but at the expense of additional memory usage. The data itself is not cached, but the cached delegate is instantiated.
  • For shorter lists, each item can be cached.
  • For longer lists, cacheBuffer does not bring benefits, because the speed of creating entries is the same as without caching during fast scrolling. The cacheBuffer only delays the occurrence of the problem, that is, it just pushes the position created by the delegate to above/below the visible part of the list/grid.
  • For more information about cacheBuffer , please see:

2.3 Avoid useless painting

  You should prevent repeated painting in the same area . For example, if you provide the background of the application, you can prevent QDeclarativeView from drawing its window background:

Window a QDeclarativeView ; window .setAttribute( the Qt :: WA_OpaquePaintEvent ); window .setAttribute( the Qt :: WA_NoSystemBackground ); window .viewport()->setAttribute( the Qt :: WA_OpaquePaintEvent ); window .viewport()->setAttribute( the Qt :: WA_NoSystemBackground );

  In addition, consider using Item as the root element instead of Rectangle to avoid drawing the background multiple times:

  • If your root element is a Rectangle , each pixel will be drawn, maybe even several times.
  • The system QDeclarativeView first draws the background and then all QML elements.
  • You may have a Rectangle as the root element, and there are many elements inside, and no opacity covers most of the Rectangle. In this case, the system is doing useless painting.
  • You can use Item as the root element instead , because it has no visual appearance.
  • If you need to draw a background, but have static UI elements that cover part of the screen, you can still use Item as the root element and anchor a Rectangle between these static items . This way you won't do useless paintings.
    For more information, please see:

3. Use dynamic loading to optimize performance

  If a large amount of QML needs to be parsed, the QML application will start slowly. This can happen if the whole application is implemented in a QML file with a huge amount of code. Judicious application is divided into logical entities , QML minimum loading at the beginning, and then use a loader Loader Load more QML needed.

  • The Loader control can be used to dynamically load and unload visual QML components defined in QML files or items/components defined in QML files. This dynamic behavior allows developers to control the memory usage and startup speed of the application .
  • Divide the application into several QML files so that each file contains a logical UI entity. This way of loading and unloading is easier to control. Each application should not write a QML file with a huge amount of code.
  • Load the absolute minimum amount of QML when the application starts , so that your application starts as soon as possible. After the app UI is visible, you can connect to the network and display the spinner etc.
  • If your first view is very complex and needs to load a lot of QML, display a splash screen to make the user feel that something is happening ( transition effect ).
  • You should only load UI fragments as needed, for example when the user navigates to another view, but on the other hand, navigating (switching) between views may take more time.
  • For more Loader control information, please see:

4. Some performance Tips of other QML

  If you have a simple list with a fixed length, you can try to use Flickable+Column+Repeater to optimize performance instead of using QML's ListView. Although creating the list will be slower, the list scrolling will be smoother.

4.1 Animate small areas of the screen as much as possible in the transition animation

  If you need to move 3 elements in one second, try moving 300 milliseconds each time. The system can calculate the boundaries of items that need to be redrawn and draw everything within these boundaries.

4.2 Avoid complex cutting

  You should only enable the clip function when you really need it . The default clip value is false.

  • If clipping is enabled, the Item will clip its own drawing and the drawing of its children to its bounding rectangle.

4.3 If you remove comments or blanks from the QML file, will it help improve performance?

  not real. These files are reprocessed into binary memory representation at startup, so there should be no performance difference at runtime. You may be lucky to get 0.5% improvement, and then only at startup (QML parsing is done here), nothing else.

4.4 Avoid unnecessary conversion

  If the given value of the attribute does not match the type specified by the attribute, QML will perform type conversion. This conversion consumes additional memory.

  • For example, Image and BorderImage require an image source of type url. If the attribute of the image source is defined as a string, it needs to be converted. In fact, it should be a url attribute.
  • Wrong method:
property string messageAvatar: ""
  • The correct way:
property url messageAvatar: ""

4.5 Be careful with string manipulation

  • Multiple use of operators usually means multiple memory allocations.
  • Use StringBuilder to get more efficient strings. QStringBuilder uses expression templates and reimplements operators so that when you use multiple substring concatenations, it will be postponed until the final result will be assigned to QString. At this point, the amount of storage required for the final result is known. Then call the memory allocator once to obtain the required space, and copy the substrings into it one by one.
  • Define QT_USE_FAST_CONCATENATION , QT_USE_FAST_OPERATOR_PLUS macros to optimize string memory operations.

At last

  • For more information about QML performance optimization, please view:
  • This article is translated from Qt official website and published on WeChat public account: Qt Jun

Reference :