最后!
項目3:使用簡單的形狀代替圖像
第4項:使用小圖像代替復雜形狀
這兩個項目似乎相互矛盾。 不幸的是,這里沒有簡單的答案:有時使用形狀更好,有時使用圖像更好。 為了幫助您做出正確的決定,以下是應考慮的幾點:
- 復雜性單個基本形狀(例如矩形或圓形)幾乎總是比圖像更快。 但是,為了獲得所需的工件而組裝的形狀數量越多,或者用戶定義的路徑越復雜,對這些形狀進行的操作就越昂貴。 并且優勢縮小。 重要說明:javafx.text.Text對象是一個非常復雜的形狀。
- 大小大多數圖像操作的性能都是二次方的,這意味著如果寬度和高度加倍,則操作的速度變為4倍,如果將寬度和高度加倍,則操作的速度變為9倍,等等。因此,元素越大,使用形狀越好。
- 變換旋轉或縮放不僅在使用形狀時看起來更好,而且通常也比變換圖像更快。 特別是如果旋轉和縮放設置為動畫,則形狀會更好。
- 啟動時間加載圖像和設置ImageView通常比設置形狀要慢。
- 足跡靜態和動態的足跡幾乎總是使用較高的圖像時。
重要說明:運行時當前未使用javafx.scene.Node的變量緩存。 設置它沒有區別!
現在我們將專注于圖像加載
項目5:使用預縮放功能
如果圖像需要縮放并且縮放比例以后沒有更改,建議使用預縮放功能。 這可以通過設置Image對象的寬度和高度來完成,該對象將在加載圖像時縮放圖像。
使用預縮放有兩個好處。 首先,它可以帶來更好的性能。 如果使用預縮放,則縮放肯定只計算一次。 相反,每當ImageView對象的變換被其他東西(然后是平移)更改時,都會重新計算其縮放比例。 例如,更改旋轉度將導致重新計算縮放比例。 其次,如果圖像按比例縮小,則使用預縮放后,內存使用量將大大減少。
如果標志Image.smooth為false,則可以更快地計算縮放比例。 但是必須檢查縮放圖像的質量。
例
本示例為許多圖像生成縮略圖。 代碼示例1使用ImageView的縮放功能創建了一系列縮略圖。
def thumbnails = for (i in [0..11])ImageView {image: Image {url: "{__DIR__}images/img{i}.png"}preserveRatio: truefitWidth: 30fitHeight: 20}
代碼示例1:在ImageView中縮放
如代碼示例2所示,使用Image類的預縮放功能可以實現相同的效果。使用此方法顯示縮略圖通常更快,并且內存使用量要小得多。
def thumbnails = for (i in [0..11])ImageView {image: Image {url: "{__DIR__}images/img{i}.png"preserveRatio: truewidth: 30height: 20}}
代碼示例2:使用圖像進行預縮放
項目6:使用后臺加載
Image類提供了一個很好的但容易被忽略的功能,可以在后臺異步加載圖像。 這不會提高運行時性能或減少應用程序的占用空間,但可以大大縮短啟動時間。 要啟用它,必須設置標志Image.backgroundLoading。 后臺加載有兩個后果,在實現過程中需要考慮這些后果。 如果應該在創建后不久顯示加載在后臺的圖像,則必須檢查下載進度。 否則,將首先顯示空白圖像。 另一個選擇是將變量占位符設置為顯示替代圖像,直到完成實際圖像的加載為止。 在下面的示例中使用了這種方法。
第二個結果是,在完全加載圖像之前,不會設置圖像的寬度和高度。 這可能會破壞任何布局,這取決于所用圖像的大小。 同樣,如果占位符圖像和最終圖像的大小相同,則可以使用占位符圖像來克服這一問題。 或者可以手動設置寬度和高度,這會將圖像預縮放為給定的大小。 最后一個選項是在圖像加載完成后重新計算布局。
例
代碼示例3從上方擴展了示例,以在后臺加載縮略圖并顯示它們。 加載圖像后,將顯示一個占位符(logo.png),其大小與縮略圖相同。 請注意,徽標未加載到背景中,以確保我們可以立即顯示它。
def logo = Image {url: "{__DIR__}images/logo.png"}def thumbnails = for (i in [0..11])ImageView {image: Image {url: "{__DIR__}images/img{i}.png"preserveRatio: truewidth: 30height: 20backgroundLoading: trueplaceholder: logo}x: i mod 4 * 50 + 20y: ((i/4) as Integer) * 40 + 20}Stage {scene: Scene {content: thumbnails}}
代碼示例3:在后臺加載縮略圖
在仿真器上,必須看起來非常接近才能注意到后臺加載。 在真實設備上,加載圖像通常需要更長的時間。 啟用背景加載后,屏幕將快速顯示,首先僅顯示占位符,這些占位符被實際圖像一個接一個地替換。 如果禁用了后臺加載,則該應用程序將顯示空白屏幕,直到完全加載并顯示所有圖像為止。
第7項:使用def而不是var定義變量。 使它們成為腳本專用。
在定義實例變量時,優良作法是盡可能限制可訪問性。 同樣,如果變量立即被初始化且之后沒有重新分配,則應使用關鍵字def對其進行定義。 幾乎所有綁定變量都是如此,因為綁定變量無法重新分配(不存在非綁定操作),并且通常在定義它們時就已經知道它們綁定的對象。
除了產生更清晰,更不易出錯的代碼外,遵循這些建議還可以提高性能。 我們可以提供給編譯器的提示越多,它就越可以優化我們的代碼。 讓我們看一下代碼示例1中的示例。
class Main {def i1: Integer = 0;var i2: Integer;public def i3: Integer = 0;public var i4: Integer;}
代碼示例1:具有公共,私有def和var的示例腳本
代碼示例1定義了一個具有四個成員i1,i2,i3和i4的小類。 變量i1和i2是專用腳本,i3和i4是公共變量; 變量i1和i3用def定義,i2和i4用var定義。 代碼示例2顯示了部分生成的Java代碼。
class Main extends java.lang.Object implements Main$Intf,com.sun.javafx.runtime.FXObject{public int $Main$i1;public int $Main$i2;public int $i3;public final com.sun.javafx.runtime.location.IntVariable $i4;...}
代碼示例2:從代碼示例1生成的Java代碼的一部分
生成的Java代碼的顯著之處在于,除i4之外的所有變量都變成了簡單的整數。 只有變量i4被轉換為IntVariable,因為它需要提供更多功能。 一個Int變量比IntVariable實例需要更少的內存并執行得更快。
條款8:使用整數代替數字
整數運算總是比浮點值運算快。 在通常沒有臺式計算機之類的數學協處理器的有限設備上,兩者之間的差異是巨大的。 因此,最好在可能的情況下使用Integer。 JavaFX編譯器的類型推斷機制通常在確定變量的正確類型方面做得很好,但是如果有疑問,它將選擇Number。 因此,應始終明確設置Integer變量的類型。
條款9:使用Sequence類的功能
軟件包javafx.util中的Sequences類提供了大量用于處理序列的有用函數。 應該熟悉提供的功能并使用它們,而不要自己實現。 序列中的功能已經過全面測試,其性能至少要好于自己實現的性能。
參考:來自JCG合作伙伴的 JavaFX移動應用程序最佳實踐 3和JavaFX移動應用程序 最佳實踐 4和JavaFX移動應用程序 最佳實踐5 ? 邁克博客(Mike's Blog)上的邁克爾·海因里希(Michael Heinrichs)。
翻譯自: https://www.javacodegeeks.com/2012/03/best-practices-for-javafx-mobile_07.html