拜爾說,他演講的主題是表演。 他告誡說,與大多數與性能相關的事情一樣,請避免性能預先優化。 他有一個黃色的大警告屏幕,上面寫著“寫清楚的代碼,然后再顯示個人資料!”。 他說,他的演講基于JavaFX 2.2,其中一些技巧可能不適用于JavaFX 8。

Bair為Windows,Linux和Mac OS X這三種不同的操作系統(未指定版本)上的幾種瀏覽器提供了“ GUIMark 2 Vector”基準測試。Bair將JavaFX與這些瀏覽器的本機支持進行了比較。 他還指出,有時SceneGraph更快,有時Canvas更快。 Bair提出的許多觀點在較小的設備上比在臺式機上更為重要。
JavaFX比GUIMark 2位圖中的瀏覽器快得多,而JavaFX Canvas是所有瀏覽器中最快的。 由于速度有限,GUIMark 2 Text測試無法為Windows提供有用的數據,但是JavaFX在Linux和Mac OS X上表現出色。Bair打算發布基準測試方法以供公眾使用,他展示了一個圖表,該圖表表明從JavaFX 2.2到2007年的顯著性能改進。 JavaFX 8。
拜爾的績效準則#1是“少做點工作”。 Bair說:“更小的系統需要更激烈的性能調整。” 他補充說,“每行計數”和“額外的方法調用加起來”。 盡管在傳統的桌面Java中,我們已經學會了不要擔心方法調用的數量,但這在較小的設備上可能是個問題(“過多的內聯非常昂貴”,而“過多的方法調用很昂貴”)。 Bair展示了如何使用局部final
變量來減少方法調用的次數。 他承認這是臺式機上的“絕對微性能預優化”,但對于較小的設備來說是一種有用的策略。
Bair說,“填充率”是“幾乎100%確定性”的限制。 除非您有“成千上萬的頂點”,否則幾何率不太可能成為JavaFX中的重要限制。 CSS開銷和布局計算一樣都是可能的限制。 JavaFX進行了大量的緩存,而后者可能并不總是一個問題。 系統I / O很有可能會限制您,特別是在較小的設備上。
拜爾(Bair)展示了一個“濫用填充率”的示例,該方法首先繪制最遠的背景,然后用另一填充繪制大部分。 他有一些避免這種不必要填充的觀點,例如“只畫變化了”。 Bair指出開發人員會在Swing中識別“臟區”,但是JavaFX SceneGraph會“自動執行此操作!” 他確實警告JavaFX Canvas要求開發人員識別“臟區”。
提高填充率的另一種方法是“限制使用(某些)效果”。 “效果在您的臺式機系統上幾乎是免費的,”但可能需要在較小的設備上更仔細地觀察。 拜爾討論了一項子彈,指出“限制使用非矩形,無軸對齊的夾子”是提高填充率的另一種策略。 直接剪切對齊的圖像很快,但是抗鋸齒,渲染為背景圖像以及旋轉未對齊的像素邊界的過程會“花費更多”(但在大多數桌面應用程序中您不會注意到)。
Bair表示,減少透支是提高填充率的有效方法。 與減少透支有關,他討論了使用“圖像蒙皮”的問題。 Bair在這里還提到JavaFX 8包括自動區域紋理緩存。 減少透支的其他想法包括簡化樣式(Metro,Android),合并背景填充以及減少重疊節點的數量。
Bair表示,Microsoft故意在Metro中提出了易于繪制的樣式。 同樣,Android樣式更快,更容易繪制。
“ 遮擋剔除”可以避免繪制(剔除)不可見的東西。” 這樣做可以使我們“減少過度繪制并提高渲染性能”。 JavaFX引擎可以響應JavaFX CSS不透明的插圖,以了解何時不重繪這些區域。
有一些CSS成本需要注意,例如解析樣式表。 貝爾(Bair)展示了一個帶有.parent:hover .child {...}
的“ CSS Horror Show”幻燈片,并解釋了為什么如此恐怖:每次將父項懸停時,都必須重新審視所有子項。 同樣,如果有大量.parent .child {...}
, .parent .child {...}
可能會很糟糕,因為“當我們遇到一個帶有.child樣式類的節點時,我們必須沿著整個場景圖走動直到找到它。” 最好將搜索限制為直接父級。
Bair指出,setStyle CSS屬性非常方便,但代價可能很高。 解析和其他支持會增加性能問題。 CSS提供了功能,靈活性和便利性,但這確實是以性能為代價的。
Bair的技巧之一是“避免對SceneGraph進行結構更改”。 從變更點開始的所有CSS必須重新計算。 除了重新應用CSS外,更改SceneGraph時還需要“結構完整性檢查”。 JavaFX已經優化了toFront / toBack,因此請使用它們而不是刪除并添加回來。
另一個Bair技巧是“使用FXCollections”。 他對此的第一句話說:“爭取最小的通知開銷。” 建議使用setAll而不是clear和addAll的子項目符號。 添加了另一個子項目,“避免多次添加呼叫”。
最好使用FXColections.sort(),因為它“發送”排列”更改事件。 這意味著JavaFX引擎知道更改了什么,因此僅重新計算該特定類型更改所需的內容。 這些“排列”由“單獨的快速路徑處理”。
Bair表示“ ListView快速起泡”,因為它“重用節點”并保持最小的更改。 Bair總結說,該幻燈片帶有“重用ListView來滿足您所有的虛擬化需求!”
Bair的“手動布局”技巧包括了Region
的自定義擴展的想法。 他警告說,擴展Region
時,幾乎總是需要實現computePrefWidth
和computePrefHeight
。
Bair有一張幻燈片列出了處理布局時“ JavaFX會問”的問題。 這些問題是“您想要多大/多高?” 和“您可以調整大小嗎?” 當嘗試渲染布局時,JavaFX至少會問這些問題一次,有時甚至是問更多次。 定制的布局可以減少嘗試的次數和提出的問題的數量。 “ JavaFX提出了很多問題”,并且“在布局期間每個節點都被問到了”。
拜爾有一個“重要提示!” 與“內容偏差”相關。 如果高度取決于寬度,則表示水平偏差。 如果寬度取決于高度,則表示您有偏見。 Bair表示“((contentBias = null)到目前為止是最快的”(所有計算出的高度和寬度首選項都將被緩存)。 內容偏差通常為null或水平。 內在錯誤是“內置布局實際上未很好地支持contentBias!= null”。
到目前為止,所有內容均已符合Bair的第一條規則(減少工作量)。 規則2現在為“了解您的設備”。 Bair展示了一張幻燈片,其中將功能強大的NVidia GForce GTX 690與功能較弱的NVidia GForce 310甚至更??低的PowerVR SGX543MP3進行了比較。 Bair的觀點當然是,“ JavaFX為您提供了一個開發平臺和一套API,但是您可以使用和不能使用哪些API將取決于設備的固有性能特征。”
Bair對設備上的JavaFX有一些經驗法則。 使用桌面應用程序處理2萬到10萬個節點。 500到1000個節點是嵌入式的最佳范圍。 對于非常小的嵌入式設備,對于JavaFX應用程序,堅持使用100到200個節點。
Bair提供了另一個與緩存有關的技巧。 他談到要緩存圖表,因為然后將其僅繪制到圖像一次,然后可以快速繪制到屏幕“數十億次”。 但是,Bair警告說,“如果節點發生很大變化,則會適得其反”。 拜爾說,他經常將緩存設置為true,制作動畫,然后再次將緩存設置為false。
旋轉和縮放時可以將CacheHint設置為SPEED,以獲得更好的性能。 如果您希望它在旋轉時能重繪以提高準確性,則可以使用除SPEED之外的其他緩存提示。
JavaFX 8具有Pulse Logger( -Djavafx.pulseLogger=true
系統屬性),可以“打印出很多有關JavaFX引擎執行的廢話”(很好的方式)。 在每個脈沖的基礎上有很多提供的信息,包括脈沖數(自動遞增的整數),脈沖持續時間以及自最后一個脈沖以來的時間。 該信息還包括線程詳細信息和事件詳細信息。 此數據使開發人員可以查看大部分時間。
Bair用相同的鮮黃色警告幻燈片結束了會議:編寫干凈代碼,然后分析! 幻燈片還指出,“不要過度操作,否則您將陷入無法維護的困境。
參考: JavaOne 2012:來自JCG合作伙伴 Dustin Marx的JavaFX圖形技巧和竅門,內容來自Inspired by Actual Events博客。
翻譯自: https://www.javacodegeeks.com/2012/10/javaone-2012-javafx-graphics-tips-and.html