開篇
性能優化在行業里永遠是一個常談的話題,該話題里的內容無法用準則來描述啦,而更多的是建議和規則。本文多數內容、觀點和建議參考于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下渲染的粒子數量和大小。
審核編輯 :李倩
-
圖像
+關注
關注
2文章
1084瀏覽量
40451 -
模型
+關注
關注
1文章
3229瀏覽量
48812 -
線程
+關注
關注
0文章
504瀏覽量
19675
原文標題:QML性能優化 | 常見界面元素優化
文章出處:【微信號:嵌入式小生,微信公眾號:嵌入式小生】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論