如果您在處理圖片時不夠謹慎,可能很快就會發生效能問題。處理大型點陣圖時,很容易就會遇到 OutOfMemoryError
。請按照下列最佳做法,確保應用程式能發揮最佳效能。
僅載入需要的點陣圖大小
多數智慧型手機都配備會產生大型圖片檔的高解析度相機。如果您要在螢幕上顯示圖片,必須降低圖片的解析度,或者只載入圖片容器大小範圍內的圖片。持續載入大於所需的圖片,可能會耗盡 GPU 快取,導致 UI 算繪的效能降低。
如何管理圖片大小:
- 在不影響輸出圖片的前提下,盡可能縮小圖片檔案。
- 考慮將圖片轉換為 WEBP 格式,而非 JPEG 或 PNG。
- 針對不同的螢幕解析度提供較小的圖片 (請參閱提示 #3)。
- 使用圖片載入程式庫,根據螢幕上的檢視畫面大小縮小圖片。這有助於改善畫面載入效能。
盡可能使用向量圖片取代點陣圖
在畫面上以視覺化方式呈現事物時,您必須決定是否可用向量形式加以呈現。盡可能使用向量圖片而非點陣圖,因為當圖片縮放至不同大小時,向量圖片不會以像素呈現。不過,並非所有圖片都能以向量形式呈現,使用相機拍攝的圖片就無法轉換成向量圖片。
為不同螢幕大小提供額外資源
如果應用程式提供內建圖片,建議您為不同裝置解析度提供不同尺寸的素材資源。這有助於縮減應用程式在裝置上的下載大小及提升效能,因為系統會在較低解析度的裝置上載入解析度較低的圖片。如要進一步瞭解如何為不同裝置大小提供替代點陣圖,請參閱替代點陣圖說明文件。
使用 ImageBitmap
時,請先呼叫 prepareToDraw
,再進行繪圖
使用 ImageBitmap
時,如要啟動將紋理上傳至 GPU 的程序,請先呼叫 ImageBitmap#prepareToDraw()
,然後再實際進行繪圖。這有助於 GPU 準備紋理,並提高在螢幕上顯示影像內容的效能。多數圖片載入程式庫都已執行這項最佳化作業,但如果您是自行使用 ImageBitmap
類別,就需要留意這一點。
最好將 Int
DrawableRes
或網址做為參數傳遞至可組合項,而非 Painter
由於處理圖片的程序非常複雜 (例如為 Bitmaps
編寫 equals 函式會耗用昂貴的計算資源),Painter
API 並未明確標示為穩定版類別。不穩定的類別可能會產生不必要的重組作業,原因在於編譯器無法輕易推斷資料是否已變更。
因此,最好將網址或可繪製資源 ID 做為參數傳遞至可組合項,而非做為參數傳遞至 Painter
。
// Prefer this:
@Composable
fun MyImage(url: String) {
}
// Over this:
@Composable
fun MyImage(painter: Painter) {
}
不要在記憶體中保存不再需要的點陣圖
載入記憶體的點陣圖越多,裝置的記憶體就越可能用盡。舉例來說,如果要在畫面上載入大型 Image 可組合項清單,請使用 LazyColumn
或 LazyRow
,確保系統可在捲動大型清單時釋放記憶體。
不要使用 AAB/APK 檔案封裝大型圖片
造成應用程式下載大小偏大的主要原因之一,就是封裝在 AAB 或 APK 檔案中的圖像。您可以使用 APK 分析工具,確保您封裝的圖片檔案並未超過所需尺寸。請縮減尺寸,或考慮將圖片放在伺服器上,並且僅在必要時下載圖片。
為您推薦
- 注意:系統會在 JavaScript 關閉時顯示連結文字
- ImageBitmap 與 ImageVector {:#bitmap-vs-vector}
- 在 Compose 中儲存 UI 狀態
- Jetpack Compose 階段