Text元素、Image元素、模型视图和视觉效果优化规则和推荐实践

电子说

1.3w人已加入

描述

 


 

开篇

性能优化在行业里永远是一个常谈的话题,该话题里的内容无法用准则来描述啦,而更多的是建议和规则。本文多数内容、观点和建议参考于Qt官方资料并结合自己的实际QML使用习惯总结而成。优化规则并不是“黄金规则”,更不是“金标准”。对于QML应用开发来说,将这些规则根据具体应用场景能合理运用即可啦。

本文内容主要涉及到:Text元素、Image元素、模型视图和视觉效果四个方面的一些优化规则和推荐实践。

性能优化 | Text元素

计算文本的布局会是一个缓慢的操作。所以,在实际开发中尽可能优先考虑使用明文格式,而不是StyledText,这可以减少布局引擎的工作量。如果不能使用明文(例如:需要嵌入图像,或使用标记来指定具有特定格式(粗体、斜体等)的字符范围),那么才考虑使用StyledText

应该只在文本可能是StyledText的情况下使用AutoText,因为这种模式会导致很高的解析成本。除此之外,还不应该使用RichText模式,因为StyledText几乎提供了其所有的特性。

性能优化 | Image元素

在任何软件的用户界面中,图片都是重要组成部分。但是一般加载图片所需的时间、消耗的内存数量和使用方式,都会影响应用程序的性能,在本小结中,描述在实际qml应用开发中,在使用图片时关于性能的几条优化点。

异步加载图片

图片通常非常大,所以最佳的做法是确保加载图片不会阻塞UI线程。将Image元素的asynchronous属性设置为true,用于允许从本地文件系统异步加载图片(注:远程图片总是异步加载的)。

注:当asynchronous属性设置为true时,图片元素将在低优先级的工作线程中加载。

显式设置图片源的属性

如果在应用程序中加载了一个大尺寸的图片,但是却在一个小尺寸的元素中显示它,因此我们应该设置图片的sourceSize属性为被呈现的元素的大小,以确保在内存中保存的是小尺寸的图片,而不是大尺寸的图片。

注:更改sourceSize会导致图像重新加载。

避免运行时拼接

通过在应用程序中提供预合成的图片资源(例如,提供带有阴影效果的元素),可以避免在运行时进行图片合成。

避免平滑图片

对于Image类型,image.smotth用于设置图片的平滑参数,我们在需要时才进行平滑操作。因为在一些硬件上进行图片平滑速度较慢,而且如果图像以原图大小显示,则没有视觉效果,因此也没有意义且影响性能。

避免多次绘制

避免在一个区域多次绘制。在设计qml文件时,使用Item作为根元素,而不要使用Rectangle,以避免多次绘制背景。

性能优化 | 使用Anchor定位元素

使用锚定位比使用绑定更有效率。例如下列代码,

Rectangle {
    id: rect1
    x: 20
    width: 200; height: 200
}
Rectangle {
    id: rect2
    x: rect1.x
    y: rect1.y + rect1.height
    width: rect1.width - 20
    height: 200
}

在上述代码中,是使用使用绑定来定位rect2相对于rect1的位置。从性能角度来看,更高效的做法是:

Rectangle {
    id: rect1
    x: 20
    width: 200; height: 200
}
Rectangle {
    id: rect2
    height: 200
    anchors.left: rect1.left
    anchors.top: rect1.bottom
    anchors.right: rect1.right
    anchors.rightMargin: 20
}

使用绑定定位(通过将绑定表达式赋值给可视对象的x、y、widht和height属性)相对较慢,但是这种方式具有灵活性的优点。

如果布局不是动态的,指定布局最有效的方法是静态初始化x, y, width和height属性。Item坐标总是相对于它们的父节点,所以如果想要与父节点的(0,0)坐标保持固定的偏移,就不能使用anchor。如下面的例子,子矩形对象位于相同的位置,但锚代码显示的效率不如通过静态初始化使用固定定位的代码:

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
    }
}

性能优化 | 模型和视图

绝大多数的应用程序至少包含一个向视图提供数据的模型。但是如果数据量较大,将会影响性能,所以我们需要知道在实际开发中如何优化性能,本小节提供几条方法:

自定义C++模型

用C++编写我们的自定义模型,以便在QML中与视图一起使用。此类模型的最佳实现将在很大程度上取决于实际的应用场景,以下是几点准则:

(1)尽可能保持异步。

(2)保证所有的处理都在一个(低优先级)的工作线程中进行。

(3)尽可能在后台批处理操作,以减少I/O和IPC。

注意:建议使用低优先级的工作线程,以将GUI线程被饥饿的风险降到最低(因为这可能会极大程度上影响GUI体验效果)。除此之外,同步和锁机制可能是导致性能变慢的一个重要原因,因此应避免不必要的锁定。

ListModel QML类型

在QML中,优先使用ListModel类型,用于向ListView视图提供数据。该类型足以满足大多数的使用场景了,只要使用正确,ListMode性能也相对较好。在使用中,应注意以下两点:

(1)在工作线程中填充

在JavaScript中,ListModel元素可以被填充到一个(低优先级)的工作线程中。我们必须在WorkerScript中显式调用ListModel上的sync(),以便将更改同步到主线程。

注,使用WorkerScript元素将导致创建一个单独的JavaScript引擎(因为JavaScript引擎是属于单个线程),这一点将增加内存使用量。然而,多个WorkerScript元素将使用同一个工作线程,因此一旦应用程序已经使用了一个WorkerScript元素,那么使用第二个或第三个WorkerScript元素对内存的影响就可以忽略不计了。

(2)不要使用动态元素

Qt Quick 2 ListModel中的性能优化主要来自:假定了对给定模型中单个元素中的类型不会更改,因此缓存性能将显著提高。如果类型可以从一个元素到另一个元素的动态变化,则不满足Qt Quick 2对ListModel的优化,而且模型的性能将会差一个数量级。

因此,在默认情况下动态类型是禁用的。必须专门设置模型的dynamicRoles属性,才能启用动态类型(并承受随之而来的性能下降)。因此,如果可以重新设计应用程序来避免使用动态类型,则推荐不要使用动态类型而是去重新设计程序。

视图(View)

视图代理应尽可能简单。在代理中只放置需要QML来显示的必要信息,不是立即需要的附加信息和操作(例如:如果在单击时显示更多信息)应该在需要的时候才创建(即:延迟创建

在设计视图代理时需要注意以下几点:

(1)代理中的元素越少,在视图中创建的速度就越快,因此视图滚动的速度就越快,效果越好。

(2)减少代理中绑定的数量。推荐在代理中使用Anchor而不是绑定来进行相对定位。

(3)避免在代理中使用ShaderEffect元素。

(4)不要在代理中启动Clipping。

可以设置一个视图的cacheBuffer属性来允许异步创建和在可见区域外缓存代理。对于不简单且不太可能在单帧内创建的视图代理,推荐使用cacheBuffer

注:cacheBuffer是在内存中保留额外的代理。因此,利用cacheBuffer获得的值必须与内存使用相平衡。应使用基准测试来找到用例的最佳值,因为使用cacheBuffer会增加内存压力,在极端情况下,会导致视图滚动帧率降低,出现卡顿现象!

性能优化 | 视觉效果

Qt Quick 2允许开发人员和设计人员创建高端的用户界面。因此流动性、动态转换和视觉效果等特性可以在应用程序中发挥巨大作用,但在QML中使用这些特性时必须谨慎,因为可能会影响性能。

动画

通常,动画化一个Item的属性会导致引用该属性的所有绑定都被重新计算。在属性动画过程中的属性绑定被重新计算在实际开发中是必须的;但在一些情况下,可以考虑最好在执行动画之前禁用绑定,然后在动画完成后重新分配绑定。

避免在动画期间运行JavaScript。例如:避免为x属性的动画运行复杂的JavaScript表达式。

在使用脚本动画时应注意,因为这些动画是在主线程中运行的(因此如果它们需要很长时间才能完成,就可能会导致一些动画帧缺失)。

粒子效果

在Qt Quick Particles模块中允许粒子效果无缝集成到用户界面中。每个平台都有不同的图形硬件功能,Particles模块无法将参数限制为硬件能够很好支持的情况。

如果渲染的粒子越多(它们越大),图形硬件就需要越快,才能以60帧/秒的速度渲染,更快的CPU速度才能渲染更多的粒子效果。

因此,在目标平台上测试所有的粒子效果就变得很重要了,用于评估在60fps下渲染的粒子数量和大小。

 

审核编辑 :李倩


打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分