zoukankan      html  css  js  c++  java
  • Qml开发中的性能Tips(翻译文)

    Qml开发中的性能Tips(翻译文)

    来源 https://cloud.tencent.com/developer/article/1468124

    1.关于图像性能Tips

    1.1 位图格式对比矢量图格式

    Qt支持任何标准图像格式,包括PNG和JPEG等位图格式,以及SVG等矢量图形格式。与位图图像相比,渲染SVG图像很慢。

    1.2 异步加载大图像

    如果同步加载图像,则会阻塞UI界面。在许多情况下,图像不需要立即可见,因此它们可以是延迟加载的。

    • 如果不需要立即显示图像,则应在单独的线程中异步加载图像。这可以通过将QML的Image异步(asynchronous)设置为true来完成。这样,用户界面就可以保持响应。
    • 请注意,此属性仅对从本地文件系统读取的图像有效。通过网络资源(例如HTTP)加载的图像始终是异步加载的。

    1.3 避免调整和缩放

    • 调整大小/缩放是QML中非常繁重的操作。使用原始大小的图像,而不是调整大小图像的大小/缩放大小。

    1.4 大图像使用sourceSize属性

    图像通常是QML用户界面中使用占用最大的内存。

    • sourceSize应与大图像一起使用,因为属性设置为加载的图像则存储着实际像素数。
    • 如果你有一个很大的图像32642448,但你设置了sourceSize为204153,那么它会缩小并将被存储为204*153的内存。
    • 如果图像的实际大小大于sourceSize,则缩小图像。 这样,大图像不会占用超过必要的内存;
    • 这对于从外部源加载或由用户提供的内容尤为重要。
    • 注意,动态更改此属性会导致重新加载图像源,甚至可能来自网络,如果它不在内存缓存中。
    • 图像在内部进行缓存和共享,因此如果多个图像元素使用相同的源,则只加载图像的一个内存。

    1.5 仅在必要时启用Image的smooth属性

    启用smooth属性对性能不利。使用自然大小的图像或禁用动画中的平滑(smooth)处理。

    • Image的smooth属性可在缩放或转换时平滑处理图像。
    • 平滑处理提供更好的视觉质量,但速度较慢
    • 如果图像以其自然大小显示,则Image的smooth没有视觉效果或性能影响。
    • 如果您确实需要启用Image的smooth属性,请在动画开始时禁用平滑处理,并在动画结束时重新启用它(仅当图像在屏幕上静止时,缩放瑕疵才可见)。

    1.6 避免由多个元素组成图像

    由单个图像组成的图像比由多个元素组成图像效率更高。

    • 例如,可以使用放置在提供阴影的图像上的矩形来创建具有阴影的图像。
    • 提供包括框架和阴影的图像效率更高。

    2.关于列表性能Tips


    2.1 确保您的数据模型尽可能快

    在许多情况下,慢速模型(slow model)实际上是列表滚动性能瓶颈。请确保数据模型尽可能快。

    • 视图被轻弹(拖动)时,必须快速创建代理;
    • 例如,在单击委托时仅需要的任何其他功能应由Loader需要时创建
    • 在委托中将QML的数量保持在最低水平。委托中的元素越少,视图的滚动速度就越快
    • 在列表委托中,仅将QML用于用户界面,并使用C++实现其余部分(例如:数据生成,数据处理)。不要使用JavaScript。

    2.2 在ListView/GridView中使用CacheBuffer

    在某些情况下,cacheBuffer在改善ListView/GridView性能方面很有用。默认的cacheBuffer为零。

    • cacheBuffer属性确定是否在视图的可见区域之外实例化委托(delegate)。
    • 请注意,cacheBuffer以像素为单位定义,例如: 如果委托高20像素,则cacheBuffer设置为40(最多2个委托实例),可见区域下方的2个委托实例可以保留在内存中。
    • 设置此值可以提高滚动行为的流畅性,但要牺牲额外的内存使用量。数据本身不缓存,但缓存的是实例化委托。
    • 对于较短的列表,那么其中每个项都可以缓存。
    • 对于较长的列表,cacheBuffer没有带来好处,因为创建条目的速度与快速滚动时没有缓存的速度相同。cacheBuffer只是推迟了问题的发生,也就是说,它只是将委托创建的位置推到列表/网格可见部分的上方/下方。 更多关于cacheBuffer信息请查看:
    http://doc.qt.io/qt-5/qml-qtquick-listview.html#cacheBuffer-prop

    2.3 避免无用的绘画

    你应该防止在同一个区域重复绘画。例如,如果您提供了应用程序的背景,则可以防止QDeclarativeView绘制其窗口背景:

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

    此外,考虑使用Item作为根元素而不是Rectangle,以避免多次绘制背景:

    • 如果你的根元素是一个Rectangle,就会绘制每个像素,甚至可能是几次。
    • 系统QDeclarativeView首先绘制背景,然后绘制所有QML元素。
    • 您可能有一个Rectangle作为根元素,并且内部有很多元素,没有不透明度覆盖大部分Rectangle。在这种情况下,系统正在进行无用的绘画。
    • 您可以改为使用Item作为根元素,因为它没有视觉外观。
    • 如果您需要绘制背景,但是具有覆盖屏幕一部分的静态UI元素,您仍然可以使用Item作为根元素并在这些静态项之间锚定一个Rectangle。这样你就不会做无用的绘画。 更多信息请查看:
    http://doc.qt.io/qt-5/qtquick-performance.html#rendering

    3.使用动态加载优化性能


    如果需要解析大量QML,则QML应用程序会缓慢启动。如果整个应用程序在一个代码量巨大的QML文件中实现,就会发生这种情况。明智地将应用程序划分逻辑实体,在开始时加载最小QML,然后再使用加载器Loader根据需要加载更多QML。

    • Loader控件可用于动态加载和卸载在QML文件中定义的可视QML组件或在QML文件中定义的项/组件。这种动态行为允许开发人员控制应用程序的内存使用和启动速度
    • 将应用程序划分为几个QML文件,以便每个文件包含一个逻辑UI实体。这种装卸方式更容易控制。每个应用程序不应该写一个巨大代码量的QML文件。
    • 在应用程序启动加载绝对最少量的QML,以使您的应用程序尽快启动。在应用程序UI可见后,您可以连接到网络并显示微调器等。
    • 如果您的第一个视图非常复杂并且需要加载大量QML,请显示一个启动画面,让用户感觉某些事情正在发生(过渡效果)。
    • 您应该只根据需要加载UI片段,例如当用户导航到另一个视图时,但是另一方面,在视图之间导航(切换)可能需要更多的时间。 更多Loader控件信息请查看:
    http://doc.qt.io/qt-5/qml-qtquick-loader.html

    4.其他QML的一些性能Tips


    如果您有一个固定长度的简单列表,您可以尝试使用Flickable+Column+Repeater来优化性能,而不是使用QML的ListView。虽然创建列表会慢一些,但是列表滚动会更流畅。

    4.1 在过渡动画中尽可能为屏幕的小区域设置动画

    如果您需要在一秒钟内移动3个元素,请尝试每次移动300毫秒。该系统可以计算需要重新绘制的项的边界,并在这些边界内绘制所有内容。

    4.2 避免复杂的裁剪

    您应该只在真正需要的时候启用裁剪clip功能。默认clip值为false。

    • 如果启用了裁剪,则Item将把自己的绘制以及其子项的绘制裁剪到其边界矩形。

    4.3 如果从QML文件中去掉注释或空白,是否有助于提高性能?

    不是真的。这些文件在启动时被重新处理为二进制内存表示,因此到运行时应该不会有性能差异。您可能很幸运,获得了0.5%的改进,然后只在启动时(QML解析就是在这里完成的),其他地方都没有。

    4.4 避免不必要的转换

    如果属性的给定值与属性指定的类型不匹配,QML将执行类型转换。这种转换会消耗额外的内存。

    • 例如,Image和BorderImage需要一个图像源,类型为url。如果图像源的属性定义为string,则需要转换,实际上它应该是url属性。
    • 错误方法:
    property string messageAvatar: ""
    • 正确方法:
    property url messageAvatar: ""

    4.5 小心字符串操作

    • 操作符的多次使用通常意味着多次内存分配。
    • 使用StringBuilder获得更高效的字符串。QStringBuilder使用表达式模板并重新实现运算符,这样当您使用的多个子字符串连接将被推迟,直到最终结果将被分配给QString。此时,已知最终结果所需的存储量。然后调用内存分配器一次以获得所需的空间,并将子串逐个复制到其中。
    • 定义QT_USE_FAST_CONCATENATIONQT_USE_FAST_OPERATOR_PLUS宏来优化字符串内存操作。

    ============= End

  • 相关阅读:
    现有某电商网站用户对商品的收藏数据,记录了用户收藏的商品id以及收藏日期,名为buyer_favorite1。 buyer_favorite1包含:买家id,商品id,收藏日期这三个字段,数据以“ ”分割
    面向对象程序设计中类与类的关系都有哪几种?分别用类图实例说明。
    Java为什么没有指针
    touchz,mkdir,vi的区别
    session使用方法
    迪杰斯特拉算法-文档读取数据
    数据结构---公交线路提示系统(Java后台+excel表格+web前端)
    caffe中train过程的train数据集、val数据集、test时候的test数据集区别
    caffe程序中出现的db.cpp:#line(行号) unknown database backend问题
    caffe的cancat层
  • 原文地址:https://www.cnblogs.com/lsgxeva/p/12418485.html
Copyright © 2011-2022 走看看