開篇
性能優(yōu)化在行業(yè)里永遠(yuǎn)是一個常談的話題,該話題里的內(nèi)容無法用準(zhǔn)則來描述啦,而更多的是建議和規(guī)則。本文多數(shù)內(nèi)容、觀點(diǎn)和建議參考于Qt官方資料并結(jié)合自己的實(shí)際QML使用習(xí)慣總結(jié)而成。優(yōu)化規(guī)則并不是“黃金規(guī)則”,更不是“金標(biāo)準(zhǔn)”。對于QML應(yīng)用開發(fā)來說,將這些規(guī)則根據(jù)具體應(yīng)用場景能合理運(yùn)用即可啦。
本文內(nèi)容主要涉及到:Text元素、Image元素、模型視圖和視覺效果四個方面的一些優(yōu)化規(guī)則和推薦實(shí)踐。
性能優(yōu)化 | Text元素
計(jì)算文本的布局會是一個緩慢的操作。所以,在實(shí)際開發(fā)中盡可能優(yōu)先考慮使用明文格式,而不是StyledText
,這可以減少布局引擎的工作量。如果不能使用明文(例如:需要嵌入圖像,或使用標(biāo)記來指定具有特定格式(粗體、斜體等)的字符范圍),那么才考慮使用StyledText
。
應(yīng)該只在文本可能是StyledText的情況下使用AutoText,因?yàn)檫@種模式會導(dǎo)致很高的解析成本。除此之外,還不應(yīng)該使用RichText模式,因?yàn)镾tyledText幾乎提供了其所有的特性。
性能優(yōu)化 | Image元素
在任何軟件的用戶界面中,圖片都是重要組成部分。但是一般加載圖片所需的時間、消耗的內(nèi)存數(shù)量和使用方式,都會影響應(yīng)用程序的性能,在本小結(jié)中,描述在實(shí)際qml應(yīng)用開發(fā)中,在使用圖片時關(guān)于性能的幾條優(yōu)化點(diǎn)。
異步加載圖片
圖片通常非常大,所以最佳的做法是確保加載圖片不會阻塞UI線程。將Image元素的asynchronous
屬性設(shè)置為true,用于允許從本地文件系統(tǒng)異步加載圖片(注:遠(yuǎn)程圖片總是異步加載的)。
注:當(dāng)
asynchronous
屬性設(shè)置為true時,圖片元素將在低優(yōu)先級的工作線程中加載。
顯式設(shè)置圖片源的屬性
如果在應(yīng)用程序中加載了一個大尺寸的圖片,但是卻在一個小尺寸的元素中顯示它,因此我們應(yīng)該設(shè)置圖片的sourceSize
屬性為被呈現(xiàn)的元素的大小,以確保在內(nèi)存中保存的是小尺寸的圖片,而不是大尺寸的圖片。
注:更改sourceSize會導(dǎo)致圖像重新加載。
避免運(yùn)行時拼接
通過在應(yīng)用程序中提供預(yù)合成的圖片資源(例如,提供帶有陰影效果的元素),可以避免在運(yùn)行時進(jìn)行圖片合成。
避免平滑圖片
對于Image類型,image.smotth
用于設(shè)置圖片的平滑參數(shù),我們在需要時才進(jìn)行平滑操作。因?yàn)樵谝恍┯布线M(jìn)行圖片平滑速度較慢,而且如果圖像以原圖大小顯示,則沒有視覺效果,因此也沒有意義且影響性能。
避免多次繪制
避免在一個區(qū)域多次繪制。在設(shè)計(jì)qml文件時,使用Item
作為根元素,而不要使用Rectangle
,以避免多次繪制背景。
性能優(yōu)化 | 使用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
}
使用綁定定位(通過將綁定表達(dá)式賦值給可視對象的x、y、widht和height屬性)相對較慢,但是這種方式具有靈活性的優(yōu)點(diǎn)。
如果布局不是動態(tài)的,指定布局最有效的方法是靜態(tài)初始化x, y, width和height屬性。Item坐標(biāo)總是相對于它們的父節(jié)點(diǎn),所以如果想要與父節(jié)點(diǎn)的(0,0)坐標(biāo)保持固定的偏移,就不能使用anchor。如下面的例子,子矩形對象位于相同的位置,但錨代碼顯示的效率不如通過靜態(tài)初始化使用固定定位的代碼:
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
}
}
性能優(yōu)化 | 模型和視圖
絕大多數(shù)的應(yīng)用程序至少包含一個向視圖提供數(shù)據(jù)的模型。但是如果數(shù)據(jù)量較大,將會影響性能,所以我們需要知道在實(shí)際開發(fā)中如何優(yōu)化性能,本小節(jié)提供幾條方法:
自定義C++模型
用C++編寫我們的自定義模型,以便在QML中與視圖一起使用。此類模型的最佳實(shí)現(xiàn)將在很大程度上取決于實(shí)際的應(yīng)用場景,以下是幾點(diǎn)準(zhǔn)則:
(1)盡可能保持異步。
(2)保證所有的處理都在一個(低優(yōu)先級)的工作線程中進(jìn)行。
(3)盡可能在后臺批處理操作,以減少I/O和IPC。
注意:建議使用低優(yōu)先級的工作線程,以將GUI線程被饑餓的風(fēng)險降到最低(因?yàn)檫@可能會極大程度上影響GUI體驗(yàn)效果)。除此之外,同步和鎖機(jī)制可能是導(dǎo)致性能變慢的一個重要原因,因此應(yīng)避免不必要的鎖定。
ListModel QML類型
在QML中,優(yōu)先使用ListModel
類型,用于向ListView
視圖提供數(shù)據(jù)。該類型足以滿足大多數(shù)的使用場景了,只要使用正確,ListMode
性能也相對較好。在使用中,應(yīng)注意以下兩點(diǎn):
(1)在工作線程中填充
在JavaScript中,ListModel
元素可以被填充到一個(低優(yōu)先級)的工作線程中。我們必須在WorkerScript中顯式調(diào)用ListModel上的sync()
,以便將更改同步到主線程。
注,使用WorkerScript元素將導(dǎo)致創(chuàng)建一個單獨(dú)的JavaScript引擎(因?yàn)镴avaScript引擎是屬于單個線程),這一點(diǎn)將增加內(nèi)存使用量。然而,多個WorkerScript元素將使用同一個工作線程,因此一旦應(yīng)用程序已經(jīng)使用了一個WorkerScript元素,那么使用第二個或第三個WorkerScript元素對內(nèi)存的影響就可以忽略不計(jì)了。
(2)不要使用動態(tài)元素
Qt Quick 2 ListModel中的性能優(yōu)化主要來自:假定了對給定模型中單個元素中的類型不會更改,因此緩存性能將顯著提高。如果類型可以從一個元素到另一個元素的動態(tài)變化,則不滿足Qt Quick 2對ListModel的優(yōu)化,而且模型的性能將會差一個數(shù)量級。
因此,在默認(rèn)情況下動態(tài)類型是禁用的。必須專門設(shè)置模型的dynamicRoles
屬性,才能啟用動態(tài)類型(并承受隨之而來的性能下降)。因此,如果可以重新設(shè)計(jì)應(yīng)用程序來避免使用動態(tài)類型,則推薦不要使用動態(tài)類型而是去重新設(shè)計(jì)程序。
視圖(View)
視圖代理應(yīng)盡可能簡單。在代理中只放置需要QML來顯示的必要信息,不是立即需要的附加信息和操作(例如:如果在單擊時顯示更多信息)應(yīng)該在需要的時候才創(chuàng)建(即:延遲創(chuàng)建
)
在設(shè)計(jì)視圖代理時需要注意以下幾點(diǎn):
(1)代理中的元素越少,在視圖中創(chuàng)建的速度就越快,因此視圖滾動的速度就越快,效果越好。
(2)減少代理中綁定的數(shù)量。推薦在代理中使用Anchor而不是綁定來進(jìn)行相對定位。
(3)避免在代理中使用ShaderEffect
元素。
(4)不要在代理中啟動Clipping。
可以設(shè)置一個視圖的cacheBuffer
屬性來允許異步創(chuàng)建和在可見區(qū)域外緩存代理。對于不簡單且不太可能在單幀內(nèi)創(chuàng)建的視圖代理,推薦使用cacheBuffer
。
注:
cacheBuffer
是在內(nèi)存中保留額外的代理。因此,利用cacheBuffer
獲得的值必須與內(nèi)存使用相平衡。應(yīng)使用基準(zhǔn)測試來找到用例的最佳值,因?yàn)槭褂胏acheBuffer會增加內(nèi)存壓力,在極端情況下,會導(dǎo)致視圖滾動幀率降低,出現(xiàn)卡頓現(xiàn)象!
性能優(yōu)化 | 視覺效果
Qt Quick 2允許開發(fā)人員和設(shè)計(jì)人員創(chuàng)建高端的用戶界面。因此流動性、動態(tài)轉(zhuǎn)換和視覺效果等特性可以在應(yīng)用程序中發(fā)揮巨大作用,但在QML中使用這些特性時必須謹(jǐn)慎,因?yàn)榭赡軙绊懶阅堋?/p>
動畫
通常,動畫化一個Item的屬性會導(dǎo)致引用該屬性的所有綁定都被重新計(jì)算。在屬性動畫過程中的屬性綁定被重新計(jì)算在實(shí)際開發(fā)中是必須的;但在一些情況下,可以考慮最好在執(zhí)行動畫之前禁用綁定,然后在動畫完成后重新分配綁定。
避免在動畫期間運(yùn)行JavaScript。例如:避免為x屬性的動畫運(yùn)行復(fù)雜的JavaScript表達(dá)式。
在使用腳本動畫時應(yīng)注意,因?yàn)檫@些動畫是在主線程中運(yùn)行的(因此如果它們需要很長時間才能完成,就可能會導(dǎo)致一些動畫幀缺失)。
粒子效果
在Qt Quick Particles模塊中允許粒子效果無縫集成到用戶界面中。每個平臺都有不同的圖形硬件功能,Particles模塊無法將參數(shù)限制為硬件能夠很好支持的情況。
如果渲染的粒子越多(它們越大),圖形硬件就需要越快,才能以60幀/秒的速度渲染,更快的CPU速度才能渲染更多的粒子效果。
因此,在目標(biāo)平臺上測試所有的粒子效果就變得很重要了,用于評估在60fps下渲染的粒子數(shù)量和大小。
審核編輯 :李倩
-
圖像
+關(guān)注
關(guān)注
2文章
1088瀏覽量
40515 -
模型
+關(guān)注
關(guān)注
1文章
3279瀏覽量
48976 -
線程
+關(guān)注
關(guān)注
0文章
505瀏覽量
19715
原文標(biāo)題:QML性能優(yōu)化 | 常見界面元素優(yōu)化
文章出處:【微信號:嵌入式小生,微信公眾號:嵌入式小生】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論